(svn r13548) [NewGRF_ports] -Sync: with trunk r13412:13544. NewGRF_ports
authorrichk
Tue, 17 Jun 2008 13:22:13 +0000
branchNewGRF_ports
changeset 10994 cd9968b6f96b
parent 10991 d8811e327d12
child 10995 311b38c7f9a7
(svn r13548) [NewGRF_ports] -Sync: with trunk r13412:13544.
bin/data/openttdd.grf
bin/data/openttdw.grf
projects/openttd_vs80.vcproj
projects/openttd_vs90.vcproj
source.list
src/blitter/32bpp_optimized.cpp
src/blitter/32bpp_optimized.hpp
src/bridge_gui.cpp
src/bridge_map.h
src/core/alloc_func.hpp
src/core/mem_func.hpp
src/core/sort_func.hpp
src/dock_gui.cpp
src/driver.cpp
src/driver.h
src/gamelog.cpp
src/genworld.cpp
src/genworld_gui.cpp
src/gfx.cpp
src/gfx_func.h
src/graph_gui.cpp
src/group_gui.cpp
src/industry_cmd.cpp
src/landscape.cpp
src/lang/english.txt
src/main_gui.cpp
src/misc/blob.hpp
src/network/network.cpp
src/network/network.h
src/network/network_gui.cpp
src/network/network_udp.cpp
src/newgrf.cpp
src/newgrf_house.cpp
src/newgrf_industries.cpp
src/newgrf_spritegroup.cpp
src/news_gui.cpp
src/openttd.cpp
src/order_gui.cpp
src/pathfind.cpp
src/players.cpp
src/rail.h
src/rail_cmd.cpp
src/roadveh_cmd.cpp
src/saveload.cpp
src/settings.cpp
src/settings_gui.cpp
src/ship_cmd.cpp
src/signs_func.h
src/signs_gui.cpp
src/slope_func.h
src/sortlist_type.h
src/station_cmd.cpp
src/strings.cpp
src/table/bridge_land.h
src/table/files.h
src/table/railtypes.h
src/table/sprites.h
src/terraform_gui.cpp
src/thread_pthread.cpp
src/toolbar_gui.cpp
src/town_cmd.cpp
src/town_gui.cpp
src/town_map.h
src/town_type.h
src/train_cmd.cpp
src/tunnelbridge_cmd.cpp
src/vehicle.cpp
src/vehicle_gui.cpp
src/video/cocoa/cocoa_v.mm
src/video/dedicated_v.cpp
src/video/null_v.cpp
src/video/sdl_v.cpp
src/video/video_driver.hpp
src/video/win32_v.cpp
src/viewport.cpp
src/water_cmd.cpp
src/win32.cpp
src/window.cpp
src/yapf/follow_track.hpp
src/yapf/yapf_ship.cpp
Binary file bin/data/openttdd.grf has changed
Binary file bin/data/openttdw.grf has changed
--- a/projects/openttd_vs80.vcproj	Tue Jun 17 10:32:49 2008 +0000
+++ b/projects/openttd_vs80.vcproj	Tue Jun 17 13:22:13 2008 +0000
@@ -1136,6 +1136,10 @@
 				>
 			</File>
 			<File
+				RelativePath=".\..\src\core\mem_func.hpp"
+				>
+			</File>
+			<File
 				RelativePath=".\..\src\minilzo.h"
 				>
 			</File>
@@ -1460,6 +1464,10 @@
 				>
 			</File>
 			<File
+				RelativePath=".\..\src\core\sort_func.hpp"
+				>
+			</File>
+			<File
 				RelativePath=".\..\src\sortlist_type.h"
 				>
 			</File>
--- a/projects/openttd_vs90.vcproj	Tue Jun 17 10:32:49 2008 +0000
+++ b/projects/openttd_vs90.vcproj	Tue Jun 17 13:22:13 2008 +0000
@@ -1121,6 +1121,10 @@
 				>
 			</File>
 			<File
+				RelativePath=".\..\src\core\mem_func.hpp"
+				>
+			</File>
+			<File
 				RelativePath=".\..\src\minilzo.h"
 				>
 			</File>
@@ -1441,6 +1445,10 @@
 				>
 			</File>
 			<File
+				RelativePath=".\..\src\core\sort_func.hpp"
+				>
+			</File>
+			<File
 				RelativePath=".\..\src\sortlist_type.h"
 				>
 			</File>
--- a/source.list	Tue Jun 17 10:32:49 2008 +0000
+++ b/source.list	Tue Jun 17 13:22:13 2008 +0000
@@ -209,6 +209,7 @@
 map_type.h
 core/math_func.hpp
 md5.h
+core/mem_func.hpp
 minilzo.h
 mixer.h
 music.h
@@ -290,6 +291,7 @@
 signs_type.h
 slope_func.h
 slope_type.h
+core/sort_func.hpp
 sortlist_type.h
 sound_func.h
 sound_type.h
--- a/src/blitter/32bpp_optimized.cpp	Tue Jun 17 10:32:49 2008 +0000
+++ b/src/blitter/32bpp_optimized.cpp	Tue Jun 17 13:22:13 2008 +0000
@@ -10,7 +10,7 @@
 
 static FBlitter_32bppOptimized iFBlitter_32bppOptimized;
 
-void Blitter_32bppOptimized::Draw(Blitter::BlitterParams *bp, BlitterMode mode, ZoomLevel zoom)
+template <BlitterMode mode, ZoomLevel zoom> inline void Blitter_32bppOptimized::Draw(Blitter::BlitterParams *bp)
 {
 	const SpriteLoader::CommonPixel *src, *src_line;
 	uint32 *dst, *dst_line;
@@ -66,6 +66,27 @@
 	}
 }
 
+template <BlitterMode mode> inline void Blitter_32bppOptimized::Draw(Blitter::BlitterParams *bp, ZoomLevel zoom)
+{
+	switch (zoom) {
+		default: NOT_REACHED();
+		case ZOOM_LVL_NORMAL: Draw<mode, ZOOM_LVL_NORMAL>(bp); return;
+		case ZOOM_LVL_OUT_2X: Draw<mode, ZOOM_LVL_OUT_2X>(bp); return;
+		case ZOOM_LVL_OUT_4X: Draw<mode, ZOOM_LVL_OUT_4X>(bp); return;
+		case ZOOM_LVL_OUT_8X: Draw<mode, ZOOM_LVL_OUT_8X>(bp); return;
+	}
+}
+
+void Blitter_32bppOptimized::Draw(Blitter::BlitterParams *bp, BlitterMode mode, ZoomLevel zoom)
+{
+	switch (mode) {
+		default: NOT_REACHED();
+		case BM_NORMAL:       Draw<BM_NORMAL>      (bp, zoom); return;
+		case BM_COLOUR_REMAP: Draw<BM_COLOUR_REMAP>(bp, zoom); return;
+		case BM_TRANSPARENT:  Draw<BM_TRANSPARENT> (bp, zoom); return;
+	}
+}
+
 Sprite *Blitter_32bppOptimized::Encode(SpriteLoader::Sprite *sprite, Blitter::AllocatorProc *allocator)
 {
 	Sprite *dest_sprite;
--- a/src/blitter/32bpp_optimized.hpp	Tue Jun 17 10:32:49 2008 +0000
+++ b/src/blitter/32bpp_optimized.hpp	Tue Jun 17 13:22:13 2008 +0000
@@ -14,6 +14,9 @@
 	/* virtual */ Sprite *Encode(SpriteLoader::Sprite *sprite, Blitter::AllocatorProc *allocator);
 
 	/* virtual */ const char *GetName() { return "32bpp-optimized"; }
+
+	template <BlitterMode mode, ZoomLevel zoom> void Draw(Blitter::BlitterParams *bp);
+	template <BlitterMode mode> void Draw(Blitter::BlitterParams *bp, ZoomLevel zoom);
 };
 
 class FBlitter_32bppOptimized: public BlitterFactory<FBlitter_32bppOptimized> {
--- a/src/bridge_gui.cpp	Tue Jun 17 10:32:49 2008 +0000
+++ b/src/bridge_gui.cpp	Tue Jun 17 13:22:13 2008 +0000
@@ -119,6 +119,7 @@
 	{
 		this->bridges->SetListing(this->last_sorting);
 		this->bridges->SetSortFuncs(this->sorter_funcs);
+		this->bridges->NeedResort();
 		this->SortBridgeList();
 
 		/* Change the data, or the caption of the gui. Set it to road or rail, accordingly */
@@ -150,7 +151,7 @@
 	{
 		this->DrawWidgets();
 
-		this->DrawSortButtonState(BBSW_DROPDOWN_ORDER, (this->bridges->flags & VL_DESC) ? SBS_DOWN : SBS_UP);
+		this->DrawSortButtonState(BBSW_DROPDOWN_ORDER, this->bridges->IsDescSortOrder() ? SBS_DOWN : SBS_UP);
 
 		uint y = this->widget[BBSW_BRIDGE_LIST].top + 2;
 
--- a/src/bridge_map.h	Tue Jun 17 10:32:49 2008 +0000
+++ b/src/bridge_map.h	Tue Jun 17 13:22:13 2008 +0000
@@ -200,5 +200,15 @@
 	MakeBridgeRamp(t, o, bridgetype, d, TRANSPORT_RAIL, r);
 }
 
+/**
+ * Make a bridge ramp for aqueducts.
+ * @param t          the tile to make a bridge ramp
+ * @param o          the new owner of the bridge ramp
+ * @param d          the direction this ramp must be facing
+ */
+static inline void MakeAqueductBridgeRamp(TileIndex t, Owner o, DiagDirection d)
+{
+	MakeBridgeRamp(t, o, 0, d, TRANSPORT_WATER, 0);
+}
 
 #endif /* BRIDGE_MAP_H */
--- a/src/core/alloc_func.hpp	Tue Jun 17 10:32:49 2008 +0000
+++ b/src/core/alloc_func.hpp	Tue Jun 17 13:22:13 2008 +0000
@@ -90,4 +90,7 @@
 	return t_ptr;
 }
 
+/** alloca() has to be called in the parent function, so define AllocaM() as a macro */
+#define AllocaM(T, num_elements) ((T*)alloca((num_elements) * sizeof(T)))
+
 #endif /* ALLOC_FUNC_HPP */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/core/mem_func.hpp	Tue Jun 17 13:22:13 2008 +0000
@@ -0,0 +1,97 @@
+/* $Id$ */
+
+/** @file mem_func.hpp Functions related to memory operations. */
+
+#ifndef MEM_FUNC_HPP
+#define MEM_FUNC_HPP
+
+#include <string.h>
+#include "math_func.hpp"
+
+/**
+ * Type-safe version of memcpy().
+ *
+ * @param destination Pointer to the destination buffer
+ * @param source Pointer to the source buffer
+ * @param num number of items to be copied. (!not number of bytes!)
+ */
+template <typename T>
+FORCEINLINE void MemCpyT(T *destination, const T *source, uint num = 1)
+{
+	memcpy(destination, source, num * sizeof(T));
+}
+
+/**
+ * Type-safe version of memmove().
+ *
+ * @param destination Pointer to the destination buffer
+ * @param source Pointer to the source buffer
+ * @param num number of items to be copied. (!not number of bytes!)
+ */
+template <typename T>
+FORCEINLINE void MemMoveT(T *destination, const T *source, uint num = 1)
+{
+	memmove(destination, source, num * sizeof(T));
+}
+
+/**
+ * Type-safe version of memset().
+ *
+ * @param ptr Pointer to the destination buffer
+ * @param value Value to be set
+ * @param num number of items to be set (!not number of bytes!)
+ */
+template <typename T>
+FORCEINLINE void MemSetT(T *ptr, int value, uint num = 1)
+{
+	memset(ptr, value, num * sizeof(T));
+}
+
+/**
+ * Type-safe version of memcmp().
+ *
+ * @param ptr1 Pointer to the first buffer
+ * @param ptr2 Pointer to the second buffer
+ * @param num Number of items to compare. (!not number of bytes!)
+ * @return an int value indicating the relationship between the content of the two buffers
+ */
+template <typename T>
+FORCEINLINE int MemCmpT(const T *ptr1, const T *ptr2, uint num = 1)
+{
+	return memcmp(ptr1, ptr2, num * sizeof(T));
+}
+
+/**
+ * Type safe memory reverse operation.
+ *  Reverse a block of memory in steps given by the
+ *  type of the pointers.
+ *
+ * @param ptr1 Start-pointer to the block of memory.
+ * @param ptr2 End-pointer to the block of memory.
+ */
+template<typename T>
+FORCEINLINE void MemReverseT(T *ptr1, T *ptr2)
+{
+	assert(ptr1 != NULL && ptr2 != NULL);
+	assert(ptr1 < ptr2);
+
+	do {
+		Swap(*ptr1, *ptr2);
+	} while (++ptr1 < --ptr2);
+}
+
+/**
+ * Type safe memory reverse operation (overloaded)
+ *
+ * @param ptr Pointer to the block of memory.
+ * @param num The number of items we want to reverse.
+ */
+template<typename T>
+FORCEINLINE void MemReverseT(T *ptr, uint num)
+{
+	assert(ptr != NULL);
+
+	MemReverseT(ptr, ptr + (num - 1));
+}
+
+#endif /* MEM_FUNC_HPP */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/core/sort_func.hpp	Tue Jun 17 13:22:13 2008 +0000
@@ -0,0 +1,85 @@
+/* $Id$ */
+
+/** @file sort_func.hpp Functions related to sorting operations. */
+
+#ifndef SORT_FUNC_HPP
+#define SORT_FUNC_HPP
+
+#include <stdlib.h>
+#include "math_func.hpp"
+#include "mem_func.hpp"
+
+/**
+ * Type safe qsort()
+ *
+ * @todo replace the normal qsort with this one
+ * @note Use this sort for irregular sorted data.
+ *
+ * @param base Pointer to the first element of the array to be sorted.
+ * @param num Number of elements in the array pointed by base.
+ * @param comparator Function that compares two elements.
+ * @param desc Sort descending.
+ */
+template<typename T>
+FORCEINLINE void QSortT(T *base, uint num, int (CDECL *comparator)(const T*, const T*), bool desc = false)
+{
+	if (num < 2) return;
+
+	qsort(base, num, sizeof(T), (int (CDECL *)(const void *, const void *))comparator);
+
+	if (desc) MemReverseT(base, num);
+}
+
+/**
+ * Type safe Gnome Sort.
+ *
+ * This is a slightly modifyied Gnome search. The basic
+ * Gnome search trys to sort already sorted list parts.
+ * The modification skips these.
+ *
+ * @note Use this sort for presorted / regular sorted data.
+ *
+ * @param base Pointer to the first element of the array to be sorted.
+ * @param num Number of elements in the array pointed by base.
+ * @param comparator Function that compares two elements.
+ * @param desc Sort descending.
+ */
+template<typename T>
+FORCEINLINE void GSortT(T *base, uint num, int (CDECL *comparator)(const T*, const T*), bool desc = false)
+{
+	if (num < 2) return;
+
+	assert(base != NULL);
+	assert(comparator != NULL);
+
+	T *a = base;
+	T *b = base + 1;
+	uint offset = 0;
+
+	while (num > 1) {
+		const int diff = comparator(a, b);
+		if ((!desc && diff <= 0) || (desc && diff >= 0)) {
+			if (offset != 0) {
+				/* Jump back to the last direction switch point */
+				a += offset;
+				b += offset;
+				offset = 0;
+				continue;
+			}
+
+			a++;
+			b++;
+			num--;
+		} else {
+			Swap(*a, *b);
+
+			if (a == base) continue;
+
+			a--;
+			b--;
+			offset++;
+		}
+	}
+}
+
+#endif /* SORT_FUNC_HPP */
--- a/src/dock_gui.cpp	Tue Jun 17 10:32:49 2008 +0000
+++ b/src/dock_gui.cpp	Tue Jun 17 13:22:13 2008 +0000
@@ -69,6 +69,12 @@
 	DoCommandP(tile, 0, 0, CcBuildDocks, CMD_BUILD_LOCK | CMD_MSG(STR_CANT_BUILD_LOCKS));
 }
 
+static void PlaceDocks_Aqueduct(TileIndex tile)
+{
+	VpStartPlaceSizing(tile, VPM_X_OR_Y, DDSP_BUILD_BRIDGE);
+}
+
+
 /** Enum referring to the widgets of the build dock toolbar */
 enum DockToolbarWidgets {
 	DTW_BEGIN = 0,                 ///< Start of toolbar widgets
@@ -83,6 +89,7 @@
 	DTW_DEPOT,                     ///< Build depot button
 	DTW_STATION,                   ///< Build station button
 	DTW_BUOY,                      ///< Build buoy button
+	DTW_BUILD_AQUEDUCT,            ///< Build aqueduct button
 	DTW_END,                       ///< End of toolbar widgets
 };
 
@@ -120,6 +127,11 @@
 	HandlePlacePushButton(w, DTW_BUOY, SPR_CURSOR_BOUY, VHM_RECT, PlaceDocks_Buoy);
 }
 
+static void BuildDocksClick_Aqueduct(Window *w)
+{
+	HandlePlacePushButton(w, DTW_BUILD_AQUEDUCT, SPR_CURSOR_AQUEDUCT, VHM_RECT, PlaceDocks_Aqueduct);
+}
+
 
 typedef void OnButtonClick(Window *w);
 static OnButtonClick * const _build_docks_button_proc[] = {
@@ -129,7 +141,8 @@
 	BuildDocksClick_Demolish,
 	BuildDocksClick_Depot,
 	BuildDocksClick_Dock,
-	BuildDocksClick_Buoy
+	BuildDocksClick_Buoy,
+	BuildDocksClick_Aqueduct
 };
 
 struct BuildDocksToolbarWindow : Window {
@@ -164,6 +177,8 @@
 			case '4': BuildDocksClick_Depot(this); break;
 			case '5': BuildDocksClick_Dock(this); break;
 			case '6': BuildDocksClick_Buoy(this); break;
+			case 'B':
+			case '7': BuildDocksClick_Aqueduct(this); break;
 			default:  return ES_NOT_HANDLED;
 		}
 		return ES_HANDLED;
@@ -183,6 +198,11 @@
 	{
 		if (pt.x != -1) {
 			switch (select_proc) {
+				case DDSP_BUILD_BRIDGE:
+					ResetObjectToPlace();
+					extern void CcBuildBridge(bool success, TileIndex tile, uint32 p1, uint32 p2);
+					DoCommandP(end_tile, start_tile, TRANSPORT_WATER << 15, CcBuildBridge, CMD_BUILD_BRIDGE | CMD_MSG(STR_CAN_T_BUILD_AQUEDUCT_HERE));
+
 				case DDSP_DEMOLISH_AREA:
 					GUIPlaceProcDragXY(select_proc, start_tile, end_tile);
 					break;
@@ -214,8 +234,8 @@
 
 static const Widget _build_docks_toolb_widgets[] = {
 {   WWT_CLOSEBOX,   RESIZE_NONE,     7,     0,    10,     0,    13, STR_00C5,                   STR_018B_CLOSE_WINDOW},                   // DTW_CLOSEBOX
-{    WWT_CAPTION,   RESIZE_NONE,     7,    11,   123,     0,    13, STR_9801_DOCK_CONSTRUCTION, STR_018C_WINDOW_TITLE_DRAG_THIS},         // DTW_CAPTION
-{  WWT_STICKYBOX,   RESIZE_NONE,     7,   124,   135,     0,    13, 0x0,                        STR_STICKY_BUTTON},                       // DTW_STICKY
+{    WWT_CAPTION,   RESIZE_NONE,     7,    11,   145,     0,    13, STR_9801_DOCK_CONSTRUCTION, STR_018C_WINDOW_TITLE_DRAG_THIS},         // DTW_CAPTION
+{  WWT_STICKYBOX,   RESIZE_NONE,     7,   146,   157,     0,    13, 0x0,                        STR_STICKY_BUTTON},                       // DTW_STICKY
 {     WWT_IMGBTN,   RESIZE_NONE,     7,     0,    21,    14,    35, SPR_IMG_BUILD_CANAL,        STR_BUILD_CANALS_TIP},                    // DTW_CANAL
 {     WWT_IMGBTN,   RESIZE_NONE,     7,    22,    43,    14,    35, SPR_IMG_BUILD_LOCK,         STR_BUILD_LOCKS_TIP},                     // DTW_LOCK
 
@@ -225,11 +245,12 @@
 {     WWT_IMGBTN,   RESIZE_NONE,     7,    70,    91,    14,    35, SPR_IMG_SHIP_DEPOT,         STR_981E_BUILD_SHIP_DEPOT_FOR_BUILDING},  // DTW_DEPOT
 {     WWT_IMGBTN,   RESIZE_NONE,     7,    92,   113,    14,    35, SPR_IMG_SHIP_DOCK,          STR_981D_BUILD_SHIP_DOCK},                // DTW_STATION
 {     WWT_IMGBTN,   RESIZE_NONE,     7,   114,   135,    14,    35, SPR_IMG_BOUY,               STR_9834_POSITION_BUOY_WHICH_CAN},        // DTW_BUOY
+{     WWT_IMGBTN,   RESIZE_NONE,     7,   136,   157,    14,    35, SPR_IMG_AQUEDUCT,           STR_BUILD_AQUEDUCT},                      // DTW_BUILD_AQUEDUCT
 {   WIDGETS_END},
 };
 
 static const WindowDesc _build_docks_toolbar_desc = {
-	WDP_ALIGN_TBR, 22, 136, 36, 136, 36,
+	WDP_ALIGN_TBR, 22, 158, 36, 158, 36,
 	WC_BUILD_TOOLBAR, WC_NONE,
 	WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_STICKY_BUTTON,
 	_build_docks_toolb_widgets,
--- a/src/driver.cpp	Tue Jun 17 10:32:49 2008 +0000
+++ b/src/driver.cpp	Tue Jun 17 13:22:13 2008 +0000
@@ -14,8 +14,8 @@
 VideoDriver *_video_driver;
 char _ini_videodriver[32];
 int _num_resolutions;
-uint16 _resolutions[32][2];
-uint16 _cur_resolution[2];
+Dimension _resolutions[32];
+Dimension _cur_resolution;
 
 SoundDriver *_sound_driver;
 char _ini_sounddriver[32];
@@ -183,3 +183,18 @@
 
 	return p;
 }
+
+/** Frees memory used for this->name
+ */
+DriverFactoryBase::~DriverFactoryBase() {
+	if (this->name == NULL) return;
+
+	/* Prefix the name with driver type to make it unique */
+	char buf[32];
+	strecpy(buf, GetDriverTypeName(type), lastof(buf));
+	strecpy(buf + 5, this->name, lastof(buf));
+
+	GetDrivers().erase(buf);
+	if (GetDrivers().empty()) delete &GetDrivers();
+	free(this->name);
+}
--- a/src/driver.h	Tue Jun 17 10:32:49 2008 +0000
+++ b/src/driver.h	Tue Jun 17 13:22:13 2008 +0000
@@ -67,20 +67,7 @@
 		name(NULL)
 	{}
 
-	/** Frees memory used for this->name
-	 */
-	virtual ~DriverFactoryBase() {
-		if (this->name == NULL) return;
-
-		/* Prefix the name with driver type to make it unique */
-		char buf[32];
-		strecpy(buf, GetDriverTypeName(type), lastof(buf));
-		strecpy(buf + 5, this->name, lastof(buf));
-
-		GetDrivers().erase(buf);
-		if (GetDrivers().empty()) delete &GetDrivers();
-		free(this->name);
-	}
+	virtual ~DriverFactoryBase();
 
 	/** Shuts down all active drivers
 	 */
--- a/src/gamelog.cpp	Tue Jun 17 10:32:49 2008 +0000
+++ b/src/gamelog.cpp	Tue Jun 17 13:22:13 2008 +0000
@@ -754,6 +754,8 @@
 			la->change = ReallocT(la->change, la->changes + 1);
 
 			LoggedChange *lc = &la->change[la->changes++];
+			/* for SLE_STR, pointer has to be valid! so make it NULL */
+			memset(lc, 0, sizeof(*lc));
 			lc->ct = ct;
 
 			assert((uint)ct < GLCT_END);
--- a/src/genworld.cpp	Tue Jun 17 10:32:49 2008 +0000
+++ b/src/genworld.cpp	Tue Jun 17 13:22:13 2008 +0000
@@ -156,7 +156,6 @@
 		/* Show all vital windows again, because we have hidden them */
 		if (_gw.threaded && _game_mode != GM_MENU) ShowVitalWindows();
 		_gw.active   = false;
-		_gw.thread   = NULL;
 		_gw.proc     = NULL;
 		_gw.threaded = false;
 
@@ -199,6 +198,7 @@
 	if (_gw.thread == NULL) return;
 	_gw.quit_thread = true;
 	_gw.thread->Join();
+	delete _gw.thread;
 	_gw.thread   = NULL;
 	_gw.threaded = false;
 }
@@ -233,9 +233,7 @@
 	/* Show all vital windows again, because we have hidden them */
 	if (_gw.threaded && _game_mode != GM_MENU) ShowVitalWindows();
 
-	ThreadObject *thread = _gw.thread;
 	_gw.active   = false;
-	_gw.thread   = NULL;
 	_gw.proc     = NULL;
 	_gw.abortp   = NULL;
 	_gw.threaded = false;
@@ -243,7 +241,7 @@
 	DeleteWindowById(WC_GENERATE_PROGRESS_WINDOW, 0);
 	MarkWholeScreenDirty();
 
-	thread->Exit();
+	_gw.thread->Exit();
 }
 
 /**
@@ -287,6 +285,12 @@
 	/* Create toolbars */
 	SetupColorsAndInitialWindow();
 
+	if (_gw.thread != NULL) {
+		_gw.thread->Join();
+		delete _gw.thread;
+		_gw.thread = NULL;
+	}
+
 	if (_network_dedicated ||
 	    (_gw.thread = ThreadObject::New(&_GenerateWorld, NULL)) == NULL) {
 		DEBUG(misc, 1, "Cannot create genworld thread, reverting to single-threaded mode");
--- a/src/genworld_gui.cpp	Tue Jun 17 10:32:49 2008 +0000
+++ b/src/genworld_gui.cpp	Tue Jun 17 13:22:13 2008 +0000
@@ -477,7 +477,7 @@
 			* (use random seed) it should not be possible to be
 			* entered into the input field; the generate seed
 			* button can be used instead. */
-		_settings_newgame.game_creation.generation_seed = minu(strtoul(this->edit_str_buf, NULL, sizeof(this->edit_str_buf) - 1), MAX_UVALUE(uint32) - 1);
+		_settings_newgame.game_creation.generation_seed = minu(strtoul(this->edit_str_buf, NULL, 10), MAX_UVALUE(uint32) - 1);
 		return state;
 	}
 
--- a/src/gfx.cpp	Tue Jun 17 10:32:49 2008 +0000
+++ b/src/gfx.cpp	Tue Jun 17 13:22:13 2008 +0000
@@ -18,6 +18,7 @@
 #include "core/math_func.hpp"
 #include "settings_type.h"
 #include "core/alloc_func.hpp"
+#include "core/sort_func.hpp"
 #include "landscape_type.h"
 
 #include "table/palettes.h"
@@ -689,7 +690,7 @@
 	}
 }
 
-static inline void GfxMainBlitter(const Sprite *sprite, int x, int y, BlitterMode mode, const SubSprite *sub)
+static void GfxMainBlitter(const Sprite *sprite, int x, int y, BlitterMode mode, const SubSprite *sub)
 {
 	const DrawPixelInfo *dpi = _cur_dpi;
 	Blitter::BlitterParams bp;
@@ -715,8 +716,8 @@
 	bp.height = UnScaleByZoom(sprite->height - clip_top - clip_bottom, dpi->zoom);
 	bp.top = 0;
 	bp.left = 0;
-	bp.skip_left = UnScaleByZoom(clip_left, dpi->zoom);
-	bp.skip_top = UnScaleByZoom(clip_top, dpi->zoom);
+	bp.skip_left = UnScaleByZoomLower(clip_left, dpi->zoom);
+	bp.skip_top = UnScaleByZoomLower(clip_top, dpi->zoom);
 
 	x += ScaleByZoom(bp.skip_left, dpi->zoom);
 	y += ScaleByZoom(bp.skip_top, dpi->zoom);
@@ -767,6 +768,9 @@
 		if (bp.width <= 0) return;
 	}
 
+	assert(bp.skip_left + bp.width <= UnScaleByZoom(sprite->width, dpi->zoom));
+	assert(bp.skip_top + bp.height <= UnScaleByZoom(sprite->height, dpi->zoom));
+
 	BlitterFactoryBase::GetCurrentBlitter()->Draw(&bp, mode, dpi->zoom);
 }
 
@@ -1309,14 +1313,14 @@
 	return result;
 }
 
-static int CDECL compare_res(const void *pa, const void *pb)
+static int CDECL compare_res(const Dimension *pa, const Dimension *pb)
 {
-	int x = ((const uint16*)pa)[0] - ((const uint16*)pb)[0];
+	int x = pa->width - pb->width;
 	if (x != 0) return x;
-	return ((const uint16*)pa)[1] - ((const uint16*)pb)[1];
+	return pa->height - pb->height;
 }
 
 void SortResolutions(int count)
 {
-	qsort(_resolutions, count, sizeof(_resolutions[0]), compare_res);
+	QSortT(_resolutions, count, &compare_res);
 }
--- a/src/gfx_func.h	Tue Jun 17 10:32:49 2008 +0000
+++ b/src/gfx_func.h	Tue Jun 17 13:22:13 2008 +0000
@@ -60,8 +60,8 @@
 extern int _pal_first_dirty;
 extern int _pal_count_dirty;
 extern int _num_resolutions;
-extern uint16 _resolutions[32][2];
-extern uint16 _cur_resolution[2];
+extern Dimension _resolutions[32];
+extern Dimension _cur_resolution;
 extern Colour _cur_palette[256];
 
 void HandleKeypress(uint32 key);
--- a/src/graph_gui.cpp	Tue Jun 17 10:32:49 2008 +0000
+++ b/src/graph_gui.cpp	Tue Jun 17 13:22:13 2008 +0000
@@ -16,6 +16,7 @@
 #include "window_func.h"
 #include "date_func.h"
 #include "gfx_func.h"
+#include "sortlist_type.h"
 
 #include "table/strings.h"
 #include "table/sprites.h"
@@ -758,34 +759,54 @@
 	return _performance_titles[minu(value, 1000) >> 6];
 }
 
-static int CDECL PerfHistComp(const void* elem1, const void* elem2)
-{
-	const Player* p1 = *(const Player* const*)elem1;
-	const Player* p2 = *(const Player* const*)elem2;
+class CompanyLeagueWindow : public Window {
+private:
+	GUIList<const Player*> players;
 
-	return p2->old_economy[1].performance_history - p1->old_economy[1].performance_history;
-}
+	/**
+	 * (Re)Build the company league list
+	 */
+	void BuildPlayerList()
+	{
+		if (!this->players.NeedRebuild()) return;
 
-struct CompanyLeagueWindow : Window {
+		this->players.Clear();
+
+		const Player *p;
+		FOR_ALL_PLAYERS(p) {
+			if (p->is_active) {
+				*this->players.Append() = p;
+			}
+		}
+
+		this->players.Compact();
+		this->players.RebuildDone();
+	}
+
+	/** Sort the company league by performance history */
+	static int CDECL PerformanceSorter(const Player* const *p1, const Player* const *p2)
+	{
+		return (*p2)->old_economy[1].performance_history - (*p1)->old_economy[1].performance_history;
+	}
+
+public:
 	CompanyLeagueWindow(const WindowDesc *desc, WindowNumber window_number) : Window(desc, window_number)
 	{
+		this->players.ForceRebuild();
+		this->players.NeedResort();
+
 		this->FindWindowPlacementAndResize(desc);
 	}
 
 	virtual void OnPaint()
 	{
-		const Player *plist[MAX_PLAYERS];
-		const Player *p;
+		this->BuildPlayerList();
+		this->players.Sort(&PerformanceSorter);
 
 		this->DrawWidgets();
 
-		uint pl_num = 0;
-		FOR_ALL_PLAYERS(p) if (p->is_active) plist[pl_num++] = p;
-
-		qsort((void*)plist, pl_num, sizeof(*plist), PerfHistComp);
-
-		for (uint i = 0; i != pl_num; i++) {
-			p = plist[i];
+		for (uint i = 0; i != this->players.Length(); i++) {
+			const Player *p = this->players[i];
 			SetDParam(0, i + STR_01AC_1ST);
 			SetDParam(1, p->index);
 			SetDParam(2, p->index);
@@ -795,6 +816,22 @@
 			DrawPlayerIcon(p->index, 27, 16 + i * 10);
 		}
 	}
+
+	virtual void OnTick()
+	{
+		if (this->players.NeedResort()) {
+			this->SetDirty();
+		}
+	}
+
+	virtual void OnInvalidateData(int data)
+	{
+		if (data == 0) {
+			this->players.ForceRebuild();
+		} else {
+			this->players.ForceResort();
+		}
+	}
 };
 
 
--- a/src/group_gui.cpp	Tue Jun 17 10:32:49 2008 +0000
+++ b/src/group_gui.cpp	Tue Jun 17 13:22:13 2008 +0000
@@ -205,9 +205,9 @@
 			case VEH_AIRCRAFT: this->sorting = &_sorting.aircraft; break;
 		}
 
-		this->vehicles.sort_type = this->sorting->criteria;
-		this->vehicles.flags = VL_REBUILD | (this->sorting->order ? VL_DESC : VL_NONE);
-		this->vehicles.resort_timer = DAY_TICKS * PERIODIC_RESORT_DAYS; // Set up resort timer
+		this->vehicles.SetListing(*this->sorting);
+		this->vehicles.ForceRebuild();
+		this->vehicles.NeedResort();
 
 		this->groups.ForceRebuild();
 		this->groups.NeedResort();
@@ -260,15 +260,16 @@
 
 	~VehicleGroupWindow()
 	{
+		*this->sorting = this->vehicles.GetListing();
 	}
 
 	virtual void OnInvalidateData(int data)
 	{
-		this->vehicles.flags |= (data == 0 ? VL_REBUILD : VL_RESORT);
-
 		if (data == 0) {
+			this->vehicles.ForceRebuild();
 			this->groups.ForceRebuild();
 		} else {
+			this->vehicles.ForceResort();
 			this->groups.ForceResort();
 		}
 
@@ -384,7 +385,7 @@
 		}
 
 		/* Set text of sort by dropdown */
-		this->widget[GRP_WIDGET_SORT_BY_DROPDOWN].data = _vehicle_sort_listing[this->vehicles.sort_type];
+		this->widget[GRP_WIDGET_SORT_BY_DROPDOWN].data = _vehicle_sort_listing[this->vehicles.SortType()];
 
 		this->DrawWidgets();
 
@@ -434,7 +435,7 @@
 			DrawStringRightAligned(187, y1 + 1, STR_GROUP_TINY_NUM, (this->group_sel == g->index) ? TC_WHITE : TC_BLACK);
 		}
 
-		this->DrawSortButtonState(GRP_WIDGET_SORT_BY_ORDER, this->vehicles.flags & VL_DESC ? SBS_DOWN : SBS_UP);
+		this->DrawSortButtonState(GRP_WIDGET_SORT_BY_ORDER, this->vehicles.IsDescSortOrder() ? SBS_DOWN : SBS_UP);
 
 		int list_width = this->widget[GRP_WIDGET_LIST_VEHICLE].right - this->widget[GRP_WIDGET_LIST_VEHICLE].left - 20;
 
@@ -472,21 +473,18 @@
 
 		switch(widget) {
 			case GRP_WIDGET_SORT_BY_ORDER: // Flip sorting method ascending/descending
-				this->vehicles.flags ^= VL_DESC;
-				this->vehicles.flags |= VL_RESORT;
-
-				this->sorting->order = !!(this->vehicles.flags & VL_DESC);
+				this->vehicles.ToggleSortOrder();
 				this->SetDirty();
 				break;
 
 			case GRP_WIDGET_SORT_BY_DROPDOWN: // Select sorting criteria dropdown menu
-				ShowDropDownMenu(this, _vehicle_sort_listing, this->vehicles.sort_type,  GRP_WIDGET_SORT_BY_DROPDOWN, 0, (this->vehicle_type == VEH_TRAIN || this->vehicle_type == VEH_ROAD) ? 0 : (1 << 10));
+				ShowDropDownMenu(this, _vehicle_sort_listing, this->vehicles.SortType(),  GRP_WIDGET_SORT_BY_DROPDOWN, 0, (this->vehicle_type == VEH_TRAIN || this->vehicle_type == VEH_ROAD) ? 0 : (1 << 10));
 				return;
 
 			case GRP_WIDGET_ALL_VEHICLES: // All vehicles button
 				if (!IsAllGroupID(this->group_sel)) {
 					this->group_sel = ALL_GROUP;
-					this->vehicles.flags |= VL_REBUILD;
+					this->vehicles.ForceRebuild();
 					this->SetDirty();
 				}
 				break;
@@ -494,7 +492,7 @@
 			case GRP_WIDGET_DEFAULT_VEHICLES: // Ungrouped vehicles button
 				if (!IsDefaultGroupID(this->group_sel)) {
 					this->group_sel = DEFAULT_GROUP;
-					this->vehicles.flags |= VL_REBUILD;
+					this->vehicles.ForceRebuild();
 					this->SetDirty();
 				}
 				break;
@@ -510,7 +508,7 @@
 
 				this->group_sel = this->groups[id_g]->index;;
 
-				this->vehicles.flags |= VL_REBUILD;
+				this->vehicles.ForceRebuild();
 				this->SetDirty();
 				break;
 			}
@@ -669,11 +667,7 @@
 	{
 		switch (widget) {
 			case GRP_WIDGET_SORT_BY_DROPDOWN:
-				if (this->vehicles.sort_type != index) {
-					this->vehicles.flags |= VL_RESORT;
-					this->vehicles.sort_type = index;
-					this->sorting->criteria = this->vehicles.sort_type;
-				}
+				this->vehicles.SetSortType(index);
 				break;
 
 			case GRP_WIDGET_MANAGE_VEHICLES_DROPDOWN:
@@ -715,12 +709,7 @@
 	virtual void OnTick()
 	{
 		if (_pause_game != 0) return;
-		if (--this->vehicles.resort_timer == 0) {
-			this->vehicles.resort_timer = DAY_TICKS * PERIODIC_RESORT_DAYS;
-			this->vehicles.flags |= VL_RESORT;
-			this->SetDirty();
-		}
-		if (this->groups.NeedResort()) {
+		if (this->groups.NeedResort() || this->vehicles.NeedResort()) {
 			this->SetDirty();
 		}
 	}
--- a/src/industry_cmd.cpp	Tue Jun 17 10:32:49 2008 +0000
+++ b/src/industry_cmd.cpp	Tue Jun 17 13:22:13 2008 +0000
@@ -337,8 +337,7 @@
 	IndustryGfx gfx = GetIndustryGfx(tile);
 
 	/* For NewGRF industry tiles we might not be drawing a foundation. We need to
-	 * account for this, otherwise we might be applying a FOUNDATION_LEVELED
-	 * on a steep slope which is not allowed. Furthermore other structures should
+	 * account for this, as other structures should
 	 * draw the wall of the foundation in this case.
 	 */
 	if (gfx >= NEW_INDUSTRYTILEOFFSET) {
--- a/src/landscape.cpp	Tue Jun 17 10:32:49 2008 +0000
+++ b/src/landscape.cpp	Tue Jun 17 13:22:13 2008 +0000
@@ -79,8 +79,9 @@
 	if (!IsFoundation(f)) return 0;
 
 	if (IsLeveledFoundation(f)) {
+		uint dz = TILE_HEIGHT + (IsSteepSlope(*s) ? TILE_HEIGHT : 0);
 		*s = SLOPE_FLAT;
-		return TILE_HEIGHT;
+		return dz;
 	}
 
 	if (f != FOUNDATION_STEEP_BOTH && IsNonContinuousFoundation(f)) {
@@ -402,6 +403,9 @@
 
 			AddSortableSpriteToDraw(inclined_base + inclined, PAL_NONE, ti->x, ti->y, 16, 16, 1, ti->z);
 			OffsetGroundSprite(31, 9);
+		} else if (IsLeveledFoundation(f)) {
+			AddSortableSpriteToDraw(leveled_base + SlopeWithOneCornerRaised(highest_corner), PAL_NONE, ti->x, ti->y, 16, 16, 7, ti->z - TILE_HEIGHT);
+			OffsetGroundSprite(31, 1);
 		} else if (f == FOUNDATION_STEEP_LOWER) {
 			/* one corner raised */
 			OffsetGroundSprite(31, 1);
--- a/src/lang/english.txt	Tue Jun 17 10:32:49 2008 +0000
+++ b/src/lang/english.txt	Tue Jun 17 13:22:13 2008 +0000
@@ -1291,6 +1291,9 @@
 STR_BUILD_LOCKS_TIP                                             :{BLACK}Build locks
 STR_LANDINFO_LOCK                                               :Lock
 
+STR_CANT_PLACE_RIVERS                                           :{WHITE}Can't place rivers here...
+STR_LANDINFO_RIVER                                              :River
+
 STR_BUOY_IS_IN_USE                                              :{WHITE}...buoy is in use!
 
 STR_LANDINFO_COORDS                                             :{BLACK}Coordinates: {LTBLUE}{NUM}x{NUM}x{NUM} ({STRING})
@@ -1943,6 +1946,7 @@
 STR_3804_WATER                                                  :Water
 STR_3805_COAST_OR_RIVERBANK                                     :Coast or riverbank
 STR_3806_SHIP_DEPOT                                             :Ship depot
+STR_AQUEDUCT                                                    :Aqueduct
 STR_3807_CAN_T_BUILD_ON_WATER                                   :{WHITE}...Can't build on water
 STR_MUST_DEMOLISH_CANAL_FIRST                                   :{WHITE}Must demolish canal first
 
@@ -2662,14 +2666,17 @@
 STR_8803_TRAIN_IN_THE_WAY                                       :{WHITE}Train in the way
 STR_8804                                                        :{SETX 10}{COMMA}: {STRING4} {STRING2}
 STR_8805                                                        :{RIGHTARROW}{SETX 10}{COMMA}: {STRING4} {STRING2}
+STR_ORDER_NON_STOP                                              :{BLACK}Non-stop
 STR_ORDER_GO_TO                                                 :Go to
 STR_ORDER_GO_NON_STOP_TO                                        :Go non-stop to
 STR_ORDER_GO_VIA                                                :Go via
 STR_ORDER_GO_NON_STOP_VIA                                       :Go non-stop via
+STR_ORDER_TOGGLE_FULL_LOAD                                      :{BLACK}Full load any cargo
 STR_ORDER_DROP_LOAD_IF_POSSIBLE                                 :Load if available
 STR_ORDER_DROP_FULL_LOAD_ALL                                    :Full load all cargo
 STR_ORDER_DROP_FULL_LOAD_ANY                                    :Full load any cargo
 STR_ORDER_DROP_NO_LOADING                                       :No loading
+STR_ORDER_TOGGLE_UNLOAD                                         :{BLACK}Unload all
 STR_ORDER_DROP_UNLOAD_IF_ACCEPTED                               :Unload if accepted
 STR_ORDER_DROP_UNLOAD                                           :Unload all
 STR_ORDER_DROP_TRANSFER                                         :Transfer
@@ -3004,6 +3011,8 @@
 STR_9833_CITIZENS_CELEBRATE_FIRST                               :{BLACK}{BIGFONT}Citizens celebrate . . .{}First ship arrives at {STATION}!
 STR_9834_POSITION_BUOY_WHICH_CAN                                :{BLACK}Place a buoy which can be used as a waypoint
 STR_9835_CAN_T_POSITION_BUOY_HERE                               :{WHITE}Can't place buoy here...
+STR_BUILD_AQUEDUCT                                              :{BLACK}Build aqueduct
+STR_CAN_T_BUILD_AQUEDUCT_HERE                                   :{WHITE}Can't build aqueduct here...
 STR_9836_RENAME                                                 :{BLACK}Rename
 STR_9837_RENAME_SHIP_TYPE                                       :{BLACK}Rename ship type
 STR_9838_RENAME_SHIP_TYPE                                       :{WHITE}Rename ship type
--- a/src/main_gui.cpp	Tue Jun 17 10:32:49 2008 +0000
+++ b/src/main_gui.cpp	Tue Jun 17 13:22:13 2008 +0000
@@ -289,7 +289,7 @@
 
 			case '1' | WKC_ALT: // Gimme money
 				/* Server can not cheat in advertise mode either! */
-				if (!_networking || !_network_server || !_network_advertise)
+				if (!_networking || !_network_server || !_settings_client.network.server_advertise)
 					DoCommandP(0, 10000000, 0, NULL, CMD_MONEY_CHEAT);
 				break;
 
@@ -446,8 +446,8 @@
  */
 void GameSizeChanged()
 {
-	_cur_resolution[0] = _screen.width;
-	_cur_resolution[1] = _screen.height;
+	_cur_resolution.width  = _screen.width;
+	_cur_resolution.height = _screen.height;
 	ScreenSizeChanged();
 	RelocateAllWindows(_screen.width, _screen.height);
 	MarkWholeScreenDirty();
--- a/src/misc/blob.hpp	Tue Jun 17 10:32:49 2008 +0000
+++ b/src/misc/blob.hpp	Tue Jun 17 13:22:13 2008 +0000
@@ -6,16 +6,7 @@
 #define BLOB_HPP
 
 #include "../core/alloc_func.hpp"
-
-/** Type-safe version of memcpy().
- * @param d destination buffer
- * @param s source buffer
- * @param num_items number of items to be copied (!not number of bytes!) */
-template <class Titem_>
-FORCEINLINE void MemCpyT(Titem_* d, const Titem_* s, int num_items = 1)
-{
-	memcpy(d, s, num_items * sizeof(Titem_));
-}
+#include "../core/mem_func.hpp"
 
 /** Base class for simple binary blobs.
 *  Item is byte.
--- a/src/network/network.cpp	Tue Jun 17 10:32:49 2008 +0000
+++ b/src/network/network.cpp	Tue Jun 17 13:22:13 2008 +0000
@@ -45,7 +45,6 @@
 bool _network_server;     ///< network-server is active
 bool _network_available;  ///< is network mode available?
 bool _network_dedicated;  ///< are we a dedicated server?
-bool _network_advertise;  ///< is the server advertising to the master server?
 bool _is_network_server;  ///< Does this client wants to be a network-server?
 NetworkServerGameInfo _network_game_info;
 NetworkPlayerInfo _network_player_info[MAX_PLAYERS];
@@ -1110,7 +1109,7 @@
 		}
 	}
 
-	if (_network_advertise) NetworkUDPRemoveAdvertise();
+	if (_settings_client.network.server_advertise) NetworkUDPRemoveAdvertise();
 
 	DeleteWindowById(WC_NETWORK_STATUS_WINDOW, 0);
 
--- a/src/network/network.h	Tue Jun 17 10:32:49 2008 +0000
+++ b/src/network/network.h	Tue Jun 17 13:22:13 2008 +0000
@@ -16,7 +16,6 @@
 extern bool _network_server;     ///< network-server is active
 extern bool _network_available;  ///< is network mode available?
 extern bool _network_dedicated;  ///< are we a dedicated server?
-extern bool _network_advertise;  ///< is the server advertising to the master server?
 extern bool _is_network_server;  ///< Does this client wants to be a network-server?
 
 #else /* ENABLE_NETWORK */
@@ -29,7 +28,6 @@
 #define _network_server 0
 #define _network_available 0
 #define _network_dedicated 0
-#define _network_advertise 0
 #define _is_network_server 0
 
 #endif /* ENABLE_NETWORK */
--- a/src/network/network_gui.cpp	Tue Jun 17 10:32:49 2008 +0000
+++ b/src/network/network_gui.cpp	Tue Jun 17 13:22:13 2008 +0000
@@ -686,7 +686,7 @@
 		const FiosItem *item;
 
 		/* draw basic widgets */
-		SetDParam(1, _connection_types_dropdown[_network_advertise]);
+		SetDParam(1, _connection_types_dropdown[_settings_client.network.server_advertise]);
 		SetDParam(2, _settings_client.network.max_clients);
 		SetDParam(3, _settings_client.network.max_companies);
 		SetDParam(4, _settings_client.network.max_spectators);
@@ -748,7 +748,7 @@
 			} break;
 
 			case NSSW_CONNTYPE_BTN: // Connection type
-				ShowDropDownMenu(this, _connection_types_dropdown, _network_advertise, NSSW_CONNTYPE_BTN, 0, 0); // do it for widget NSSW_CONNTYPE_BTN
+				ShowDropDownMenu(this, _connection_types_dropdown, _settings_client.network.server_advertise, NSSW_CONNTYPE_BTN, 0, 0); // do it for widget NSSW_CONNTYPE_BTN
 				break;
 
 			case NSSW_CLIENTS_BTND:    case NSSW_CLIENTS_BTNU:    // Click on up/down button for number of clients
@@ -836,7 +836,7 @@
 	{
 		switch (widget) {
 			case NSSW_CONNTYPE_BTN:
-				_network_advertise = (index != 0);
+				_settings_client.network.server_advertise = (index != 0);
 				break;
 			case NSSW_LANGUAGE_BTN:
 				_settings_client.network.server_lang = _language_dropdown[index] - STR_NETWORK_LANG_ANY;
--- a/src/network/network_udp.cpp	Tue Jun 17 10:32:49 2008 +0000
+++ b/src/network/network_udp.cpp	Tue Jun 17 13:22:13 2008 +0000
@@ -52,7 +52,7 @@
 	DEBUG(net, 2, "[udp] advertising on master server successful");
 
 	/* We are advertised, but we don't want to! */
-	if (!_network_advertise) NetworkUDPRemoveAdvertise();
+	if (!_settings_client.network.server_advertise) NetworkUDPRemoveAdvertise();
 }
 
 ///*** Communication with clients (we are server) ***/
@@ -562,7 +562,7 @@
 	struct sockaddr_in out_addr;
 
 	/* Check if we should send an advertise */
-	if (!_networking || !_network_server || !_network_udp_server || !_network_advertise)
+	if (!_networking || !_network_server || !_network_udp_server || !_settings_client.network.server_advertise)
 		return;
 
 	/* check for socket */
--- a/src/newgrf.cpp	Tue Jun 17 10:32:49 2008 +0000
+++ b/src/newgrf.cpp	Tue Jun 17 13:22:13 2008 +0000
@@ -1548,6 +1548,14 @@
 				ret = true;
 			} break;
 
+			case 0x21: // long introduction year
+				housespec->min_year = grf_load_word(&buf);
+				break;
+
+			case 0x22: // long maximum year
+				housespec->max_year = grf_load_word(&buf);
+				break;
+
 			default:
 				ret = true;
 				break;
@@ -3292,9 +3300,9 @@
 		}
 	}
 
-	EngineID *engines = (EngineID*)alloca(idcount * sizeof(*engines));
+	EngineID *engines = AllocaM(EngineID, idcount);
 	for (uint i = 0; i < idcount; i++) {
-		engines[i] = GetNewEngine(_cur_grffile, (VehicleType)feature, grf_load_byte(&buf))->index;
+		engines[i] = GetNewEngine(_cur_grffile, (VehicleType)feature, grf_load_extended(&buf))->index;
 		if (!wagover) last_engines[i] = engines[i];
 	}
 
@@ -3342,7 +3350,7 @@
 
 static void CanalMapSpriteGroup(byte *buf, uint8 idcount)
 {
-	CanalFeature *cfs = (CanalFeature*)alloca(idcount * sizeof(*cfs));
+	CanalFeature *cfs = AllocaM(CanalFeature, idcount);
 	for (uint i = 0; i < idcount; i++) {
 		cfs[i] = (CanalFeature)grf_load_byte(&buf);
 	}
@@ -3368,7 +3376,7 @@
 
 static void StationMapSpriteGroup(byte *buf, uint8 idcount)
 {
-	uint8 *stations = (uint8*)alloca(idcount * sizeof(*stations));
+	uint8 *stations = AllocaM(uint8, idcount);
 	for (uint i = 0; i < idcount; i++) {
 		stations[i] = grf_load_byte(&buf);
 	}
@@ -3415,7 +3423,7 @@
 
 static void TownHouseMapSpriteGroup(byte *buf, uint8 idcount)
 {
-	uint8 *houses = (uint8*)alloca(idcount * sizeof(*houses));
+	uint8 *houses = AllocaM(uint8, idcount);
 	for (uint i = 0; i < idcount; i++) {
 		houses[i] = grf_load_byte(&buf);
 	}
@@ -3441,7 +3449,7 @@
 
 static void IndustryMapSpriteGroup(byte *buf, uint8 idcount)
 {
-	uint8 *industries = (uint8*)alloca(idcount * sizeof(*industries));
+	uint8 *industries = AllocaM(uint8, idcount);
 	for (uint i = 0; i < idcount; i++) {
 		industries[i] = grf_load_byte(&buf);
 	}
@@ -3467,7 +3475,7 @@
 
 static void IndustrytileMapSpriteGroup(byte *buf, uint8 idcount)
 {
-	uint8 *indtiles = (uint8*)alloca(idcount * sizeof(*indtiles));
+	uint8 *indtiles = AllocaM(uint8, idcount);
 	for (uint i = 0; i < idcount; i++) {
 		indtiles[i] = grf_load_byte(&buf);
 	}
@@ -3493,7 +3501,7 @@
 
 static void CargoMapSpriteGroup(byte *buf, uint8 idcount)
 {
-	CargoID *cargos = (CargoID*)alloca(idcount * sizeof(*cargos));
+	CargoID *cargos = AllocaM(CargoID, idcount);
 	for (uint i = 0; i < idcount; i++) {
 		cargos[i] = grf_load_byte(&buf);
 	}
@@ -3678,7 +3686,14 @@
 	uint8 lang     = grf_load_byte(&buf);
 	uint8 num      = grf_load_byte(&buf);
 	bool generic   = HasBit(lang, 7);
-	uint16 id      = generic ? grf_load_word(&buf) : grf_load_byte(&buf);
+	uint16 id;
+	if (generic) {
+		id = grf_load_word(&buf);
+	} else if (feature <= GSF_AIRCRAFT) {
+		id = grf_load_extended(&buf);
+	} else {
+		id = grf_load_byte(&buf);
+	}
 
 	ClrBit(lang, 7);
 
@@ -3856,28 +3871,28 @@
 
 	static const Action5Type action5_types[] = {
 		/* Note: min_sprites should not be changed. Therefore these constants are directly here and not in sprites.h */
-		/* 0x00 */ { A5BLOCK_INVALID,      0,                   0, 0,                                           "Type 0x00"             },
-		/* 0x01 */ { A5BLOCK_INVALID,      0,                   0, 0,                                           "Type 0x01"             },
-		/* 0x02 */ { A5BLOCK_INVALID,      0,                   0, 0,                                           "Type 0x02"             },
-		/* 0x03 */ { A5BLOCK_INVALID,      0,                   0, 0,                                           "Type 0x03"             },
-		/* 0x04 */ { A5BLOCK_FIXED,        SPR_SIGNALS_BASE,   48, PRESIGNAL_SEMAPHORE_AND_PBS_SPRITE_COUNT,    "Signal graphics"       },
-		/* 0x05 */ { A5BLOCK_FIXED,        SPR_ELRAIL_BASE,    48, ELRAIL_SPRITE_COUNT,                         "Catenary graphics"     },
-		/* 0x06 */ { A5BLOCK_FIXED,        SPR_SLOPES_BASE,    74, NORMAL_AND_HALFTILE_FOUNDATION_SPRITE_COUNT, "Foundation graphics"   },
-		/* 0x07 */ { A5BLOCK_INVALID,      0,                  75, 0,                                           "TTDP GUI graphics"     }, // Not used by OTTD.
-		/* 0x08 */ { A5BLOCK_FIXED,        SPR_CANALS_BASE,    65, CANALS_SPRITE_COUNT,                         "Canal graphics"        },
-		/* 0x09 */ { A5BLOCK_FIXED,        SPR_ONEWAY_BASE,     6, ONEWAY_SPRITE_COUNT,                         "One way road graphics" },
-		/* 0x0A */ { A5BLOCK_FIXED,        SPR_2CCMAP_BASE,   256, TWOCCMAP_SPRITE_COUNT,                       "2CC colour maps"       },
-		/* 0x0B */ { A5BLOCK_FIXED,        SPR_TRAMWAY_BASE,  113, TRAMWAY_SPRITE_COUNT,                        "Tramway graphics"      },
-		/* 0x0C */ { A5BLOCK_INVALID,      0,                 133, 0,                                           "Snowy temperate tree"  }, // Not yet used by OTTD.
-		/* 0x0D */ { A5BLOCK_FIXED,        SPR_SHORE_BASE,     16, SPR_SHORE_SPRITE_COUNT,                      "Shore graphics"        },
-		/* 0x0E */ { A5BLOCK_INVALID,      0,                   0, 0,                                           "New Signals graphics"  }, // Not yet used by OTTD.
-		/* 0x0F */ { A5BLOCK_INVALID,      0,                  12, 0,                                           "Sloped rail track"     }, // Not yet used by OTTD.
-		/* 0x10 */ { A5BLOCK_FIXED,        SPR_AIRPORTX_BASE,  15, AIRPORTX_SPRITE_COUNT,                       "Airport graphics"      },
-		/* 0x11 */ { A5BLOCK_FIXED,        SPR_ROADSTOP_BASE,   8, ROADSTOP_SPRITE_COUNT,                       "Road stop graphics"    },
-		/* 0x12 */ { A5BLOCK_INVALID,      0,                   8, 0,                                           "Aqueduct graphics"     }, // Not yet used by OTTD.
-		/* 0x13 */ { A5BLOCK_FIXED,        SPR_AUTORAIL_BASE,  55, AUTORAIL_SPRITE_COUNT,                       "Autorail graphics"     },
-		/* 0x14 */ { A5BLOCK_ALLOW_OFFSET, SPR_FLAGS_BASE,      1, FLAGS_SPRITE_COUNT,                          "Flag graphics"         },
-		/* 0x15 */ { A5BLOCK_ALLOW_OFFSET, SPR_OPENTTD_BASE,    1, OPENTTD_SPRITE_COUNT,                        "OpenTTD GUI graphics"  },
+		/* 0x00 */ { A5BLOCK_INVALID,      0,                            0, 0,                                           "Type 0x00"             },
+		/* 0x01 */ { A5BLOCK_INVALID,      0,                            0, 0,                                           "Type 0x01"             },
+		/* 0x02 */ { A5BLOCK_INVALID,      0,                            0, 0,                                           "Type 0x02"             },
+		/* 0x03 */ { A5BLOCK_INVALID,      0,                            0, 0,                                           "Type 0x03"             },
+		/* 0x04 */ { A5BLOCK_FIXED,        SPR_SIGNALS_BASE,            48, PRESIGNAL_SEMAPHORE_AND_PBS_SPRITE_COUNT,    "Signal graphics"       },
+		/* 0x05 */ { A5BLOCK_FIXED,        SPR_ELRAIL_BASE,             48, ELRAIL_SPRITE_COUNT,                         "Catenary graphics"     },
+		/* 0x06 */ { A5BLOCK_FIXED,        SPR_SLOPES_BASE,             74, NORMAL_AND_HALFTILE_FOUNDATION_SPRITE_COUNT, "Foundation graphics"   },
+		/* 0x07 */ { A5BLOCK_INVALID,      0,                           75, 0,                                           "TTDP GUI graphics"     }, // Not used by OTTD.
+		/* 0x08 */ { A5BLOCK_FIXED,        SPR_CANALS_BASE,             65, CANALS_SPRITE_COUNT,                         "Canal graphics"        },
+		/* 0x09 */ { A5BLOCK_FIXED,        SPR_ONEWAY_BASE,              6, ONEWAY_SPRITE_COUNT,                         "One way road graphics" },
+		/* 0x0A */ { A5BLOCK_FIXED,        SPR_2CCMAP_BASE,            256, TWOCCMAP_SPRITE_COUNT,                       "2CC colour maps"       },
+		/* 0x0B */ { A5BLOCK_FIXED,        SPR_TRAMWAY_BASE,           113, TRAMWAY_SPRITE_COUNT,                        "Tramway graphics"      },
+		/* 0x0C */ { A5BLOCK_INVALID,      0,                          133, 0,                                           "Snowy temperate tree"  }, // Not yet used by OTTD.
+		/* 0x0D */ { A5BLOCK_FIXED,        SPR_SHORE_BASE,              16, SPR_SHORE_SPRITE_COUNT,                      "Shore graphics"        },
+		/* 0x0E */ { A5BLOCK_INVALID,      0,                            0, 0,                                           "New Signals graphics"  }, // Not yet used by OTTD.
+		/* 0x0F */ { A5BLOCK_FIXED,        SPR_TRACKS_FOR_SLOPES_BASE,  12, TRACKS_FOR_SLOPES_SPRITE_COUNT,              "Sloped rail track"     },
+		/* 0x10 */ { A5BLOCK_FIXED,        SPR_AIRPORTX_BASE,           15, AIRPORTX_SPRITE_COUNT,                       "Airport graphics"      },
+		/* 0x11 */ { A5BLOCK_FIXED,        SPR_ROADSTOP_BASE,            8, ROADSTOP_SPRITE_COUNT,                       "Road stop graphics"    },
+		/* 0x12 */ { A5BLOCK_FIXED,        SPR_AQUEDUCT_BASE,            8, AQUEDUCT_SPRITE_COUNT,                       "Aqueduct graphics"     },
+		/* 0x13 */ { A5BLOCK_FIXED,        SPR_AUTORAIL_BASE,           55, AUTORAIL_SPRITE_COUNT,                       "Autorail graphics"     },
+		/* 0x14 */ { A5BLOCK_ALLOW_OFFSET, SPR_FLAGS_BASE,               1, FLAGS_SPRITE_COUNT,                          "Flag graphics"         },
+		/* 0x15 */ { A5BLOCK_ALLOW_OFFSET, SPR_OPENTTD_BASE,             1, OPENTTD_SPRITE_COUNT,                        "OpenTTD GUI graphics"  },
 	};
 
 	if (!check_length(len, 2, "GraphicsNew")) return;
--- a/src/newgrf_house.cpp	Tue Jun 17 10:32:49 2008 +0000
+++ b/src/newgrf_house.cpp	Tue Jun 17 13:22:13 2008 +0000
@@ -254,6 +254,12 @@
 		/* Land info for nearby tiles. */
 		case 0x62: return GetNearbyTileInformation(parameter, tile);
 
+		/* Current animation frame of nearby house tiles */
+		case 0x63: {
+			TileIndex testtile = GetNearbyTile(parameter, tile);
+			return IsTileType(testtile, MP_HOUSE) ? GetHouseAnimationFrame(testtile) : 0;
+		}
+
 		/* Read GRF parameter */
 		case 0x7F: return GetGRFParameter(object->u.house.house_id, parameter);
 	}
--- a/src/newgrf_industries.cpp	Tue Jun 17 10:32:49 2008 +0000
+++ b/src/newgrf_industries.cpp	Tue Jun 17 13:22:13 2008 +0000
@@ -265,6 +265,8 @@
 			return industry->founder | (is_ai ? 0x10000 : 0) | (colours << 24);
 		}
 
+		case 0x46: return industry->construction_date; // Date when built - long format - (in days)
+
 		/* Get industry ID at offset param */
 		case 0x60: return GetIndustryIDAtOffset(GetNearbyTile(parameter, industry->xy), industry);
 
--- a/src/newgrf_spritegroup.cpp	Tue Jun 17 10:32:49 2008 +0000
+++ b/src/newgrf_spritegroup.cpp	Tue Jun 17 13:22:13 2008 +0000
@@ -93,6 +93,8 @@
 		case 0x18: return object->callback_param2;
 		case 0x1C: return object->last_value;
 
+		case 0x5F: return (object->GetRandomBits(object) << 8) | object->GetTriggers(object);
+
 		case 0x7D: return _temp_store.Get(parameter);
 
 		/* Not a common variable, so evalute the feature specific variables */
--- a/src/news_gui.cpp	Tue Jun 17 10:32:49 2008 +0000
+++ b/src/news_gui.cpp	Tue Jun 17 13:22:13 2008 +0000
@@ -528,7 +528,7 @@
 		MoveToNextItem();
 	}
 
-	if ((_current_news == ni) && (FindWindowById(WC_MESSAGE_HISTORY, 0) != NULL)) {
+	if ((_current_news == ni) && (FindWindowById(WC_NEWS_WINDOW, 0) != NULL)) {
 		/* about to remove the currently displayed item; also skip */
 		MoveToNextItem();
 	}
--- a/src/openttd.cpp	Tue Jun 17 10:32:49 2008 +0000
+++ b/src/openttd.cpp	Tue Jun 17 13:22:13 2008 +0000
@@ -286,7 +286,7 @@
  * @param res variable to store the resolution in.
  * @param s   the string to decompose.
  */
-static void ParseResolution(int res[2], const char *s)
+static void ParseResolution(Dimension *res, const char *s)
 {
 	const char *t = strchr(s, 'x');
 	if (t == NULL) {
@@ -294,8 +294,8 @@
 		return;
 	}
 
-	res[0] = max(strtoul(s, NULL, 0), 64UL);
-	res[1] = max(strtoul(t + 1, NULL, 0), 64UL);
+	res->width  = max(strtoul(s, NULL, 0), 64UL);
+	res->height = max(strtoul(t + 1, NULL, 0), 64UL);
 }
 
 static void InitializeDynamicVariables()
@@ -377,7 +377,7 @@
 	int i;
 	const char *optformat;
 	char musicdriver[32], sounddriver[32], videodriver[32], blitter[32];
-	int resolution[2] = {0, 0};
+	Dimension resolution = {0, 0};
 	Year startyear = INVALID_YEAR;
 	uint generation_seed = GENERATE_NEW_SEED;
 	bool save_config = true;
@@ -442,7 +442,7 @@
 			debuglog_conn = mgo.opt;
 			break;
 #endif /* ENABLE_NETWORK */
-		case 'r': ParseResolution(resolution, mgo.opt); break;
+		case 'r': ParseResolution(&resolution, mgo.opt); break;
 		case 't': startyear = atoi(mgo.opt); break;
 		case 'd': {
 #if defined(WIN32)
@@ -495,14 +495,14 @@
 	if (!StrEmpty(sounddriver)) ttd_strlcpy(_ini_sounddriver, sounddriver, sizeof(_ini_sounddriver));
 	if (!StrEmpty(videodriver)) ttd_strlcpy(_ini_videodriver, videodriver, sizeof(_ini_videodriver));
 	if (!StrEmpty(blitter))     ttd_strlcpy(_ini_blitter, blitter, sizeof(_ini_blitter));
-	if (resolution[0] != 0) { _cur_resolution[0] = resolution[0]; _cur_resolution[1] = resolution[1]; }
+	if (resolution.width != 0) { _cur_resolution = resolution; }
 	if (startyear != INVALID_YEAR) _settings_newgame.game_creation.starting_year = startyear;
 	if (generation_seed != GENERATE_NEW_SEED) _settings_newgame.game_creation.generation_seed = generation_seed;
 
 	/* The width and height must be at least 1 pixel, this
 	 * way all internal drawing routines work correctly. */
-	if (_cur_resolution[0] == 0) _cur_resolution[0] = 1;
-	if (_cur_resolution[1] == 0) _cur_resolution[1] = 1;
+	if (_cur_resolution.width  <= 0) _cur_resolution.width  = 1;
+	if (_cur_resolution.height <= 0) _cur_resolution.height = 1;
 
 #if defined(ENABLE_NETWORK)
 	if (dedicated_host) snprintf(_settings_client.network.server_bind_ip, sizeof(_settings_client.network.server_bind_ip), "%s", dedicated_host);
--- a/src/order_gui.cpp	Tue Jun 17 10:32:49 2008 +0000
+++ b/src/order_gui.cpp	Tue Jun 17 13:22:13 2008 +0000
@@ -43,10 +43,13 @@
 	ORDER_WIDGET_SCROLLBAR,
 	ORDER_WIDGET_SKIP,
 	ORDER_WIDGET_DELETE,
+	ORDER_WIDGET_NON_STOP_DROPDOWN,
 	ORDER_WIDGET_NON_STOP,
+	ORDER_WIDGET_GOTO_DROPDOWN,
 	ORDER_WIDGET_GOTO,
-	ORDER_WIDGET_GOTO_DROPDOWN,
+	ORDER_WIDGET_FULL_LOAD_DROPDOWN,
 	ORDER_WIDGET_FULL_LOAD,
+	ORDER_WIDGET_UNLOAD_DROPDOWN,
 	ORDER_WIDGET_UNLOAD,
 	ORDER_WIDGET_REFIT,
 	ORDER_WIDGET_SERVICE,
@@ -444,13 +447,7 @@
 		if (order == NULL || order->GetLoadType() == load_type) return;
 
 		if (load_type < 0) {
-			switch (order->GetLoadType()) {
-				case OLF_LOAD_IF_POSSIBLE: load_type = OLFB_FULL_LOAD;       break;
-				case OLFB_FULL_LOAD:       load_type = OLF_FULL_LOAD_ANY;    break;
-				case OLF_FULL_LOAD_ANY:    load_type = OLFB_NO_LOAD;         break;
-				case OLFB_NO_LOAD:         load_type = OLF_LOAD_IF_POSSIBLE; break;
-				default: NOT_REACHED();
-			}
+			load_type = order->GetLoadType() == OLF_LOAD_IF_POSSIBLE ? OLF_FULL_LOAD_ANY : OLF_LOAD_IF_POSSIBLE;
 		}
 		DoCommandP(w->vehicle->tile, w->vehicle->index + (sel_ord << 16), MOF_LOAD | (load_type << 4), NULL, CMD_MODIFY_ORDER | CMD_MSG(STR_8835_CAN_T_MODIFY_THIS_ORDER));
 	}
@@ -507,13 +504,7 @@
 		if (order == NULL || order->GetUnloadType() == unload_type) return;
 
 		if (unload_type < 0) {
-			switch (order->GetUnloadType()) {
-				case OUF_UNLOAD_IF_POSSIBLE: unload_type = OUFB_UNLOAD;            break;
-				case OUFB_UNLOAD:            unload_type = OUFB_TRANSFER;          break;
-				case OUFB_TRANSFER:          unload_type = OUFB_NO_UNLOAD;         break;
-				case OUFB_NO_UNLOAD:         unload_type = OUF_UNLOAD_IF_POSSIBLE; break;
-				default: NOT_REACHED();
-			}
+			unload_type = order->GetUnloadType() == OUF_UNLOAD_IF_POSSIBLE ? OUFB_UNLOAD : OUF_UNLOAD_IF_POSSIBLE;
 		}
 
 		DoCommandP(w->vehicle->tile, w->vehicle->index + (sel_ord << 16), MOF_UNLOAD | (unload_type << 4), NULL, CMD_MODIFY_ORDER | CMD_MSG(STR_8835_CAN_T_MODIFY_THIS_ORDER));
@@ -534,9 +525,10 @@
 
 		/* Keypress if negative, so 'toggle' to the next */
 		if (non_stop < 0) {
-			non_stop = (order->GetNonStopType() + 1) % ONSF_END;
+			non_stop = order->GetNonStopType() ^ ONSF_NO_STOP_AT_INTERMEDIATE_STATIONS;
 		}
 
+		w->InvalidateWidget(ORDER_WIDGET_NON_STOP);
 		DoCommandP(w->vehicle->tile, w->vehicle->index + (sel_ord << 16), MOF_NON_STOP | non_stop << 4,  NULL, CMD_MODIFY_ORDER | CMD_MSG(STR_8835_CAN_T_MODIFY_THIS_ORDER));
 	}
 
@@ -631,9 +623,6 @@
 
 		if (this->vehicle->owner == _local_player) {
 			/* Set the strings for the dropdown boxes. */
-			this->widget[ORDER_WIDGET_NON_STOP].data        = _order_non_stop_drowdown[order == NULL ? 0 : order->GetNonStopType()];
-			this->widget[ORDER_WIDGET_FULL_LOAD].data       = _order_full_load_drowdown[order == NULL ? 0 : order->GetLoadType()];
-			this->widget[ORDER_WIDGET_UNLOAD].data          = _order_unload_drowdown[order == NULL ? 0 : order->GetUnloadType()];
 			this->widget[ORDER_WIDGET_COND_VARIABLE].data   = _order_conditional_variable[order == NULL ? 0 : order->GetConditionVariable()];
 			this->widget[ORDER_WIDGET_COND_COMPARATOR].data = _order_conditional_condition[order == NULL ? 0 : order->GetConditionComparator()];
 
@@ -646,8 +635,11 @@
 
 			/* non-stop only for trains */
 			this->SetWidgetDisabledState(ORDER_WIDGET_NON_STOP,  (this->vehicle->type != VEH_TRAIN && this->vehicle->type != VEH_ROAD) || order == NULL);
+			this->SetWidgetDisabledState(ORDER_WIDGET_NON_STOP_DROPDOWN, this->IsWidgetDisabled(ORDER_WIDGET_NON_STOP));
 			this->SetWidgetDisabledState(ORDER_WIDGET_FULL_LOAD, order == NULL || (order->GetNonStopType() & ONSF_NO_STOP_AT_DESTINATION_STATION) != 0); // full load
+			this->SetWidgetDisabledState(ORDER_WIDGET_FULL_LOAD_DROPDOWN, this->IsWidgetDisabled(ORDER_WIDGET_FULL_LOAD));
 			this->SetWidgetDisabledState(ORDER_WIDGET_UNLOAD,    order == NULL || (order->GetNonStopType() & ONSF_NO_STOP_AT_DESTINATION_STATION) != 0); // unload
+			this->SetWidgetDisabledState(ORDER_WIDGET_UNLOAD_DROPDOWN, this->IsWidgetDisabled(ORDER_WIDGET_UNLOAD));
 			/* Disable list of vehicles with the same shared orders if there is no list */
 			this->SetWidgetDisabledState(ORDER_WIDGET_SHARED_ORDER_LIST, !shared_orders || this->vehicle->orders == NULL);
 			this->SetWidgetDisabledState(ORDER_WIDGET_REFIT,     order == NULL); // Refit
@@ -660,35 +652,53 @@
 			this->HideWidget(ORDER_WIDGET_COND_VALUE);
 		}
 
+		this->ShowWidget(ORDER_WIDGET_NON_STOP_DROPDOWN);
 		this->ShowWidget(ORDER_WIDGET_NON_STOP);
+		this->ShowWidget(ORDER_WIDGET_UNLOAD_DROPDOWN);
 		this->ShowWidget(ORDER_WIDGET_UNLOAD);
+		this->ShowWidget(ORDER_WIDGET_FULL_LOAD_DROPDOWN);
 		this->ShowWidget(ORDER_WIDGET_FULL_LOAD);
 
+		this->RaiseWidget(ORDER_WIDGET_NON_STOP);
+		this->RaiseWidget(ORDER_WIDGET_FULL_LOAD);
+		this->RaiseWidget(ORDER_WIDGET_UNLOAD);
+
 		if (order != NULL) {
+			this->SetWidgetLoweredState(ORDER_WIDGET_NON_STOP, order->GetNonStopType() & ONSF_NO_STOP_AT_INTERMEDIATE_STATIONS);
 			switch (order->GetType()) {
 				case OT_GOTO_STATION:
-					if (!GetStation(order->GetDestination())->IsBuoy()) break;
+					if (!GetStation(order->GetDestination())->IsBuoy()) {
+						this->SetWidgetLoweredState(ORDER_WIDGET_FULL_LOAD, order->GetLoadType() == OLF_FULL_LOAD_ANY);
+						this->SetWidgetLoweredState(ORDER_WIDGET_UNLOAD, order->GetUnloadType() == OUFB_UNLOAD);
+						break;
+					}
 					/* Fall-through */
 
 				case OT_GOTO_WAYPOINT:
+					this->DisableWidget(ORDER_WIDGET_FULL_LOAD_DROPDOWN);
 					this->DisableWidget(ORDER_WIDGET_FULL_LOAD);
+					this->DisableWidget(ORDER_WIDGET_UNLOAD_DROPDOWN);
 					this->DisableWidget(ORDER_WIDGET_UNLOAD);
 					break;
 
 				case OT_GOTO_DEPOT:
-					this->DisableWidget(ORDER_WIDGET_FULL_LOAD);
-
 					/* Remove unload and replace it with refit */
+					this->HideWidget(ORDER_WIDGET_UNLOAD_DROPDOWN);
 					this->HideWidget(ORDER_WIDGET_UNLOAD);
+					this->HideWidget(ORDER_WIDGET_FULL_LOAD_DROPDOWN);
+					this->HideWidget(ORDER_WIDGET_FULL_LOAD);
 					this->ShowWidget(ORDER_WIDGET_REFIT);
-					this->HideWidget(ORDER_WIDGET_FULL_LOAD);
 					this->ShowWidget(ORDER_WIDGET_SERVICE);
+					this->SetWidgetLoweredState(ORDER_WIDGET_SERVICE, order->GetDepotOrderType() & ODTFB_SERVICE);
 					break;
 
 				case OT_CONDITIONAL: {
+					this->HideWidget(ORDER_WIDGET_NON_STOP_DROPDOWN);
 					this->HideWidget(ORDER_WIDGET_NON_STOP);
 					this->HideWidget(ORDER_WIDGET_UNLOAD);
+					this->HideWidget(ORDER_WIDGET_UNLOAD_DROPDOWN);
 					this->HideWidget(ORDER_WIDGET_FULL_LOAD);
+					this->HideWidget(ORDER_WIDGET_FULL_LOAD_DROPDOWN);
 					this->ShowWidget(ORDER_WIDGET_COND_VARIABLE);
 					this->ShowWidget(ORDER_WIDGET_COND_COMPARATOR);
 					this->ShowWidget(ORDER_WIDGET_COND_VALUE);
@@ -703,8 +713,11 @@
 				} break;
 
 				default: // every other orders
+					this->DisableWidget(ORDER_WIDGET_NON_STOP_DROPDOWN);
 					this->DisableWidget(ORDER_WIDGET_NON_STOP);
+					this->DisableWidget(ORDER_WIDGET_FULL_LOAD_DROPDOWN);
 					this->DisableWidget(ORDER_WIDGET_FULL_LOAD);
+					this->DisableWidget(ORDER_WIDGET_UNLOAD_DROPDOWN);
 					this->DisableWidget(ORDER_WIDGET_UNLOAD);
 			}
 		}
@@ -790,9 +803,13 @@
 				OrderClick_Delete(this, 0);
 				break;
 
-			case ORDER_WIDGET_NON_STOP: {
+			case ORDER_WIDGET_NON_STOP:
+				OrderClick_Nonstop(this, -1);
+				break;
+
+			case ORDER_WIDGET_NON_STOP_DROPDOWN: {
 				const Order *o = GetVehicleOrder(this->vehicle, this->OrderGetSel());
-				ShowDropDownMenu(this, _order_non_stop_drowdown, o->GetNonStopType(), ORDER_WIDGET_NON_STOP, 0, o->IsType(OT_GOTO_STATION) ? 0 : (o->IsType(OT_GOTO_WAYPOINT) ? 3 : 12));
+				ShowDropDownMenu(this, _order_non_stop_drowdown, o->GetNonStopType(), ORDER_WIDGET_NON_STOP_DROPDOWN, 0, o->IsType(OT_GOTO_STATION) ? 0 : (o->IsType(OT_GOTO_WAYPOINT) ? 3 : 12));
 			} break;
 
 			case ORDER_WIDGET_GOTO:
@@ -800,15 +817,23 @@
 				break;
 
 			case ORDER_WIDGET_GOTO_DROPDOWN:
-				ShowDropDownMenu(this, this->vehicle->type == VEH_AIRCRAFT ? _order_goto_dropdown_aircraft : _order_goto_dropdown, 0, ORDER_WIDGET_GOTO, 0, 0, this->widget[ORDER_WIDGET_GOTO_DROPDOWN].right - this->widget[ORDER_WIDGET_GOTO].left);
+				ShowDropDownMenu(this, this->vehicle->type == VEH_AIRCRAFT ? _order_goto_dropdown_aircraft : _order_goto_dropdown, 0, ORDER_WIDGET_GOTO_DROPDOWN, 0, 0);
 				break;
 
 			case ORDER_WIDGET_FULL_LOAD:
-				ShowDropDownMenu(this, _order_full_load_drowdown, GetVehicleOrder(this->vehicle, this->OrderGetSel())->GetLoadType(), ORDER_WIDGET_FULL_LOAD, 0, 2);
+				OrderClick_FullLoad(this, -1);
+				break;
+
+			case ORDER_WIDGET_FULL_LOAD_DROPDOWN:
+				ShowDropDownMenu(this, _order_full_load_drowdown, GetVehicleOrder(this->vehicle, this->OrderGetSel())->GetLoadType(), ORDER_WIDGET_FULL_LOAD_DROPDOWN, 0, 2);
 				break;
 
 			case ORDER_WIDGET_UNLOAD:
-				ShowDropDownMenu(this, _order_unload_drowdown, GetVehicleOrder(this->vehicle, this->OrderGetSel())->GetUnloadType(), ORDER_WIDGET_UNLOAD, 0, 8);
+				OrderClick_Unload(this, -1);
+				break;
+
+			case ORDER_WIDGET_UNLOAD_DROPDOWN:
+				ShowDropDownMenu(this, _order_unload_drowdown, GetVehicleOrder(this->vehicle, this->OrderGetSel())->GetUnloadType(), ORDER_WIDGET_UNLOAD_DROPDOWN, 0, 8);
 				break;
 
 			case ORDER_WIDGET_REFIT:
@@ -871,25 +896,21 @@
 	virtual void OnDropdownSelect(int widget, int index)
 	{
 		switch (widget) {
-			case ORDER_WIDGET_NON_STOP:
+			case ORDER_WIDGET_NON_STOP_DROPDOWN:
 				OrderClick_Nonstop(this, index);
 				break;
 
-			case ORDER_WIDGET_FULL_LOAD:
+			case ORDER_WIDGET_FULL_LOAD_DROPDOWN:
 				OrderClick_FullLoad(this, index);
 				break;
 
-			case ORDER_WIDGET_UNLOAD:
+			case ORDER_WIDGET_UNLOAD_DROPDOWN:
 				OrderClick_Unload(this, index);
 				break;
 
-			case ORDER_WIDGET_GOTO:
+			case ORDER_WIDGET_GOTO_DROPDOWN:
 				switch (index) {
-					case 0:
-						this->ToggleWidgetLoweredState(ORDER_WIDGET_GOTO);
-						OrderClick_Goto(this, 0);
-						break;
-
+					case 0: OrderClick_Goto(this, 0); break;
 					case 1: OrderClick_NearestDepot(this, 0); break;
 					case 2: OrderClick_Conditional(this, 0); break;
 					default: NOT_REACHED();
@@ -1040,11 +1061,14 @@
 
 	{ WWT_PUSHTXTBTN,   RESIZE_TB,      14,     0,   123,    88,    99, STR_8823_SKIP,           STR_8853_SKIP_THE_CURRENT_ORDER},     // ORDER_WIDGET_SKIP
 	{ WWT_PUSHTXTBTN,   RESIZE_TB,      14,   124,   247,    88,    99, STR_8824_DELETE,         STR_8854_DELETE_THE_HIGHLIGHTED},     // ORDER_WIDGET_DELETE
-	{   WWT_DROPDOWN,   RESIZE_TB,      14,     0,   123,    76,    87, STR_NULL,                STR_ORDER_TOOLTIP_NON_STOP},          // ORDER_WIDGET_NON_STOP
+	{   WWT_DROPDOWN,   RESIZE_TB,      14,     0,   123,    76,    87, STR_NULL,                STR_ORDER_TOOLTIP_NON_STOP},          // ORDER_WIDGET_NON_STOP_DROPDOWN
+	{    WWT_TEXTBTN,   RESIZE_TB,      14,     0,   111,    76,    87, STR_ORDER_NON_STOP,      STR_ORDER_TOOLTIP_NON_STOP},          // ORDER_WIDGET_NON_STOP
+	{   WWT_DROPDOWN,   RESIZE_TB,      14,   248,   371,    88,    99, STR_EMPTY,               STR_ORDER_GO_TO_DROPDOWN_TOOLTIP},    // ORDER_WIDGET_GOTO_DROPDOWN
 	{    WWT_TEXTBTN,   RESIZE_TB,      14,   248,   359,    88,    99, STR_8826_GO_TO,          STR_8856_INSERT_A_NEW_ORDER_BEFORE},  // ORDER_WIDGET_GOTO
-	{   WWT_DROPDOWN,   RESIZE_TB,      14,   360,   371,    88,    99, STR_EMPTY,               STR_ORDER_GO_TO_DROPDOWN_TOOLTIP},    // ORDER_WIDGET_GOTO_DROPDOWN
-	{   WWT_DROPDOWN,   RESIZE_TB,      14,   124,   247,    76,    87, STR_NULL,                STR_ORDER_TOOLTIP_FULL_LOAD},         // ORDER_WIDGET_FULL_LOAD
-	{   WWT_DROPDOWN,   RESIZE_TB,      14,   248,   371,    76,    87, STR_NULL,                STR_ORDER_TOOLTIP_UNLOAD},            // ORDER_WIDGET_UNLOAD
+	{   WWT_DROPDOWN,   RESIZE_TB,      14,   124,   247,    76,    87, STR_NULL,                STR_ORDER_TOOLTIP_FULL_LOAD},         // ORDER_WIDGET_FULL_LOAD_DROPDOWN
+	{    WWT_TEXTBTN,   RESIZE_TB,      14,   124,   235,    76,    87, STR_ORDER_TOGGLE_FULL_LOAD, STR_ORDER_TOOLTIP_FULL_LOAD},      // ORDER_WIDGET_FULL_LOAD
+	{   WWT_DROPDOWN,   RESIZE_TB,      14,   248,   371,    76,    87, STR_NULL,                STR_ORDER_TOOLTIP_UNLOAD},            // ORDER_WIDGET_UNLOAD_DROPDOWN
+	{    WWT_TEXTBTN,   RESIZE_TB,      14,   248,   359,    76,    87, STR_ORDER_TOGGLE_UNLOAD, STR_ORDER_TOOLTIP_UNLOAD},            // ORDER_WIDGET_UNLOAD
 	{ WWT_PUSHTXTBTN,   RESIZE_TB,      14,   124,   247,    76,    87, STR_REFIT,               STR_REFIT_TIP},                       // ORDER_WIDGET_REFIT
 	{ WWT_PUSHTXTBTN,   RESIZE_TB,      14,   248,   371,    76,    87, STR_SERVICE,             STR_SERVICE_HINT},                    // ORDER_WIDGET_SERVICE
 
@@ -1080,11 +1104,14 @@
 
 	{ WWT_PUSHTXTBTN,   RESIZE_TB,      14,     0,   123,    88,    99, STR_8823_SKIP,           STR_8853_SKIP_THE_CURRENT_ORDER},     // ORDER_WIDGET_SKIP
 	{ WWT_PUSHTXTBTN,   RESIZE_TB,      14,   124,   247,    88,    99, STR_8824_DELETE,         STR_8854_DELETE_THE_HIGHLIGHTED},     // ORDER_WIDGET_DELETE
+	{      WWT_EMPTY,   RESIZE_TB,      14,     0,     0,    76,    87, 0x0,                     0x0},                                 // ORDER_WIDGET_NON_STOP_DROPDOWN
 	{      WWT_EMPTY,   RESIZE_TB,      14,     0,     0,    76,    87, 0x0,                     0x0},                                 // ORDER_WIDGET_NON_STOP
+	{   WWT_DROPDOWN,   RESIZE_TB,      14,   248,   371,    88,    99, STR_EMPTY,               STR_ORDER_GO_TO_DROPDOWN_TOOLTIP},    // ORDER_WIDGET_GOTO_DROPDOWN
 	{    WWT_TEXTBTN,   RESIZE_TB,      14,   248,   359,    88,    99, STR_8826_GO_TO,          STR_8856_INSERT_A_NEW_ORDER_BEFORE},  // ORDER_WIDGET_GOTO
-	{   WWT_DROPDOWN,   RESIZE_TB,      14,   360,   371,    88,    99, STR_EMPTY,               STR_ORDER_GO_TO_DROPDOWN_TOOLTIP},    // ORDER_WIDGET_GOTO_DROPDOWN
-	{   WWT_DROPDOWN,   RESIZE_TB,      14,     0,   185,    76,    87, STR_NULL,                STR_ORDER_TOOLTIP_FULL_LOAD},         // ORDER_WIDGET_FULL_LOAD
-	{   WWT_DROPDOWN,   RESIZE_TB,      14,   186,   371,    76,    87, STR_NULL,                STR_ORDER_TOOLTIP_UNLOAD},            // ORDER_WIDGET_UNLOAD
+	{   WWT_DROPDOWN,   RESIZE_TB,      14,     0,   185,    76,    87, STR_NULL,                STR_ORDER_TOOLTIP_FULL_LOAD},         // ORDER_WIDGET_FULL_LOAD_DROPDOWN
+	{    WWT_TEXTBTN,   RESIZE_TB,      14,     0,   173,    76,    87, STR_ORDER_TOGGLE_FULL_LOAD, STR_ORDER_TOOLTIP_FULL_LOAD},      // ORDER_WIDGET_FULL_LOAD
+	{   WWT_DROPDOWN,   RESIZE_TB,      14,   186,   371,    76,    87, STR_NULL,                STR_ORDER_TOOLTIP_UNLOAD},            // ORDER_WIDGET_UNLOAD_DROPDOWN
+	{    WWT_TEXTBTN,   RESIZE_TB,      14,   186,   359,    76,    87, STR_ORDER_TOGGLE_UNLOAD, STR_ORDER_TOOLTIP_UNLOAD},            // ORDER_WIDGET_UNLOAD
 	{ WWT_PUSHTXTBTN,   RESIZE_TB,      14,     0,   185,    76,    87, STR_REFIT,               STR_REFIT_TIP},                       // ORDER_WIDGET_REFIT
 	{ WWT_PUSHTXTBTN,   RESIZE_TB,      14,   186,   371,    76,    87, STR_SERVICE,             STR_SERVICE_HINT},                    // ORDER_WIDGET_SERVICE
 
@@ -1120,10 +1147,13 @@
 
 	{      WWT_EMPTY,   RESIZE_NONE,    14,     0,     0,    76,    87, 0x0,                STR_NULL},                            // ORDER_WIDGET_SKIP
 	{      WWT_EMPTY,   RESIZE_NONE,    14,     0,     0,    76,    87, 0x0,                STR_NULL},                            // ORDER_WIDGET_DELETE
+	{      WWT_EMPTY,   RESIZE_NONE,    14,     0,     0,    76,    87, 0x0,                STR_NULL},                            // ORDER_WIDGET_NON_STOP_DROPDOWN
 	{      WWT_EMPTY,   RESIZE_NONE,    14,     0,     0,    76,    87, 0x0,                STR_NULL},                            // ORDER_WIDGET_NON_STOP
+	{      WWT_EMPTY,   RESIZE_NONE,    14,     0,     0,    76,    87, 0x0,                STR_NULL},                            // ORDER_WIDGET_GOTO_DROPDOWN
 	{      WWT_EMPTY,   RESIZE_NONE,    14,     0,     0,    76,    87, 0x0,                STR_NULL},                            // ORDER_WIDGET_GOTO
-	{      WWT_EMPTY,   RESIZE_NONE,    14,     0,     0,    76,    87, 0x0,                STR_NULL},                            // ORDER_WIDGET_GOTO_DROPDOWN
+	{      WWT_EMPTY,   RESIZE_NONE,    14,     0,     0,    76,    87, 0x0,                STR_NULL},                            // ORDER_WIDGET_FULL_LOAD_DROPDOWN
 	{      WWT_EMPTY,   RESIZE_NONE,    14,     0,     0,    76,    87, 0x0,                STR_NULL},                            // ORDER_WIDGET_FULL_LOAD
+	{      WWT_EMPTY,   RESIZE_NONE,    14,     0,     0,    76,    87, 0x0,                STR_NULL},                            // ORDER_WIDGET_UNLOAD_DROPDOWN
 	{      WWT_EMPTY,   RESIZE_NONE,    14,     0,     0,    76,    87, 0x0,                STR_NULL},                            // ORDER_WIDGET_UNLOAD
 	{      WWT_EMPTY,   RESIZE_NONE,    14,     0,     0,    76,    87, 0x0,                STR_NULL},                            // ORDER_WIDGET_REFIT
 	{      WWT_EMPTY,   RESIZE_NONE,    14,     0,     0,    76,    87, 0x0,                STR_NULL},                            // ORDER_WIDGET_SERVICE
--- a/src/pathfind.cpp	Tue Jun 17 10:32:49 2008 +0000
+++ b/src/pathfind.cpp	Tue Jun 17 13:22:13 2008 +0000
@@ -112,9 +112,28 @@
 
 static void TPFModeShip(TrackPathFinder* tpf, TileIndex tile, DiagDirection direction)
 {
-	RememberData rd;
+	assert(tpf->tracktype == TRANSPORT_WATER);
 
-	assert(tpf->tracktype == TRANSPORT_WATER);
+	if (IsTileType(tile, MP_TUNNELBRIDGE)) {
+		/* wrong track type */
+		if (GetTunnelBridgeTransportType(tile) != tpf->tracktype) return;
+
+		DiagDirection dir = GetTunnelBridgeDirection(tile);
+		/* entering tunnel / bridge? */
+		if (dir == direction) {
+			TileIndex endtile = GetOtherTunnelBridgeEnd(tile);
+
+			tpf->rd.cur_length += GetTunnelBridgeLength(tile, endtile) + 1;
+
+			TPFSetTileBit(tpf, tile, 14);
+			TPFSetTileBit(tpf, endtile, 14);
+
+			tile = endtile;
+		} else {
+			/* leaving tunnel / bridge? */
+			if (ReverseDiagDir(dir) != direction) return;
+		}
+	}
 
 	/* This addition will sometimes overflow by a single tile.
 	 * The use of TILE_MASK here makes sure that we still point at a valid
@@ -133,7 +152,7 @@
 	do {
 		Track track = RemoveFirstTrack(&bits);
 		if (bits != TRACK_BIT_NONE) only_one_track = false;
-		rd = tpf->rd;
+		RememberData rd = tpf->rd;
 
 		/* Change direction 4 times only */
 		if (!only_one_track && track != tpf->rd.last_choosen_track) {
--- a/src/players.cpp	Tue Jun 17 10:32:49 2008 +0000
+++ b/src/players.cpp	Tue Jun 17 13:22:13 2008 +0000
@@ -28,6 +28,7 @@
 #include "vehicle_func.h"
 #include "sound_func.h"
 #include "core/alloc_func.hpp"
+#include "core/sort_func.hpp"
 #include "autoreplace_func.h"
 #include "autoreplace_gui.h"
 #include "string_func.h"
@@ -818,6 +819,8 @@
 {
 	if (flags & DC_EXEC) _current_player = OWNER_NONE;
 
+	InvalidateWindowData(WC_COMPANY_LEAGUE, 0, 0);
+
 	switch (p1) {
 	case 0: { /* Create a new player */
 		/* Joining Client:
@@ -1019,12 +1022,9 @@
 }
 
 /** Sort all players given their performance */
-static int CDECL HighScoreSorter(const void *a, const void *b)
+static int CDECL HighScoreSorter(const Player* const *a, const Player* const *b)
 {
-	const Player *pa = *(const Player* const*)a;
-	const Player *pb = *(const Player* const*)b;
-
-	return pb->old_economy[0].performance_history - pa->old_economy[0].performance_history;
+	return (*b)->old_economy[0].performance_history - (*a)->old_economy[0].performance_history;
 }
 
 /* Save the highscores in a network game when it has ended */
@@ -1038,7 +1038,8 @@
 
 	/* Sort all active players with the highest score first */
 	FOR_ALL_PLAYERS(p) if (p->is_active) pl[count++] = p;
-	qsort((Player*)pl, count, sizeof(pl[0]), HighScoreSorter);
+
+	GSortT(pl, count, &HighScoreSorter);
 
 	{
 		uint i;
@@ -1270,8 +1271,11 @@
 		_player_colors[index] = p->player_color;
 
 		/* This is needed so an AI is attached to a loaded AI */
-		if (p->is_ai && (!_networking || _network_server) && _ai.enabled)
+		if (p->is_ai && (!_networking || _network_server) && _ai.enabled) {
+			/* Clear the memory of the new AI, otherwise we might be doing wrong things. */
+			memset(&_players_ainew[index], 0, sizeof(PlayerAiNew));
 			AI_StartNewAI(p->index);
+		}
 	}
 }
 
--- a/src/rail.h	Tue Jun 17 10:32:49 2008 +0000
+++ b/src/rail.h	Tue Jun 17 13:22:13 2008 +0000
@@ -38,6 +38,7 @@
 		SpriteID single_s;     ///< single piece of rail in the southern corner
 		SpriteID single_e;     ///< single piece of rail in the eastern corner
 		SpriteID single_w;     ///< single piece of rail in the western corner
+		SpriteID single_sloped;///< single piecs of rail for slopes
 		SpriteID crossing;     ///< level crossing, rail in X direction
 		SpriteID tunnel;       ///< tunnel sprites base
 	} base_sprites;
--- a/src/rail_cmd.cpp	Tue Jun 17 10:32:49 2008 +0000
+++ b/src/rail_cmd.cpp	Tue Jun 17 13:22:13 2008 +0000
@@ -1382,7 +1382,10 @@
 				cost.AddCost(ret);
 			}
 
-			if (water_ground) {
+			/* when bankrupting, don't make water dirty, there could be a ship on lower halftile */
+			if (water_ground && !(flags & DC_BANKRUPT)) {
+				if (!EnsureNoVehicleOnGround(tile)) return CMD_ERROR;
+
 				/* The track was removed, and left a coast tile. Now also clear the water. */
 				if (flags & DC_EXEC) DoClearSquare(tile);
 				cost.AddCost(_price.clear_water);
@@ -2112,6 +2115,19 @@
 
 static TrackStatus GetTileTrackStatus_Track(TileIndex tile, TransportType mode, uint sub_mode, DiagDirection side)
 {
+	/* Case of half tile slope with water. */
+	if (mode == TRANSPORT_WATER && IsPlainRailTile(tile) && GetRailGroundType(tile) == RAIL_GROUND_WATER) {
+		TrackBits tb = GetTrackBits(tile);
+		switch (tb) {
+			default: NOT_REACHED();
+			case TRACK_BIT_UPPER: tb = TRACK_BIT_LOWER; break;
+			case TRACK_BIT_LOWER: tb = TRACK_BIT_UPPER; break;
+			case TRACK_BIT_LEFT:  tb = TRACK_BIT_RIGHT; break;
+			case TRACK_BIT_RIGHT: tb = TRACK_BIT_LEFT;  break;
+		}
+		return CombineTrackStatus(TrackBitsToTrackdirBits(tb), TRACKDIR_BIT_NONE);
+	}
+
 	if (mode != TRANSPORT_RAIL) return 0;
 
 	TrackBits trackbits = TRACK_BIT_NONE;
--- a/src/roadveh_cmd.cpp	Tue Jun 17 10:32:49 2008 +0000
+++ b/src/roadveh_cmd.cpp	Tue Jun 17 13:22:13 2008 +0000
@@ -194,7 +194,7 @@
 	uint num_vehicles = 1 + CountArticulatedParts(p1, false);
 
 	/* Allow for the front and the articulated parts, plus one to "terminate" the list. */
-	Vehicle **vl = (Vehicle**)alloca(sizeof(*vl) * (num_vehicles + 1));
+	Vehicle **vl = AllocaM(Vehicle*, num_vehicles + 1);
 	memset(vl, 0, sizeof(*vl) * (num_vehicles + 1));
 
 	if (!Vehicle::AllocateList(vl, num_vehicles)) {
@@ -1714,6 +1714,7 @@
 			_road_veh_data_1[v->u.road.state - RVSB_IN_ROAD_STOP + (_settings_game.vehicle.road_side << RVS_DRIVE_SIDE)] == v->u.road.frame) ||
 			(IsInsideMM(v->u.road.state, RVSB_IN_DT_ROAD_STOP, RVSB_IN_DT_ROAD_STOP_END) &&
 			v->current_order.ShouldStopAtStation(v, GetStationIndex(v->tile)) &&
+			v->owner == GetRoadOwner(v->tile, v->u.road.roadtype) &&
 			GetRoadStopType(v->tile) == (IsCargoInClass(v->cargo_type, CC_PASSENGERS) ? ROADSTOP_BUS : ROADSTOP_TRUCK) &&
 			v->u.road.frame == RVC_DRIVE_THROUGH_STOP_FRAME))) {
 
--- a/src/saveload.cpp	Tue Jun 17 10:32:49 2008 +0000
+++ b/src/saveload.cpp	Tue Jun 17 13:22:13 2008 +0000
@@ -95,6 +95,7 @@
 
 typedef void (*AsyncSaveFinishProc)();
 static AsyncSaveFinishProc _async_save_finish = NULL;
+static ThreadObject *_save_thread;
 
 /**
  * Called by save thread to tell we finished saving.
@@ -117,6 +118,12 @@
 	_async_save_finish();
 
 	_async_save_finish = NULL;
+
+	if (_save_thread != NULL) {
+		_save_thread->Join();
+		delete _save_thread;
+		_save_thread = NULL;
+	}
 }
 
 /**
@@ -1545,8 +1552,6 @@
 	SaveFileDone();
 }
 
-static ThreadObject *_save_thread;
-
 /** We have written the whole game into memory, _Savegame_pool, now find
  * and appropiate compressor and start writing to file.
  */
@@ -1617,6 +1622,7 @@
 	if (_save_thread == NULL) return;
 
 	_save_thread->Join();
+	delete _save_thread;
 	_save_thread = NULL;
 }
 
--- a/src/settings.cpp	Tue Jun 17 10:32:49 2008 +0000
+++ b/src/settings.cpp	Tue Jun 17 13:22:13 2008 +0000
@@ -1510,7 +1510,7 @@
 	  SDTG_STR("sounddriver",      SLE_STRB,C|S,0, _ini_sounddriver,       NULL,    STR_NULL, NULL),
 	  SDTG_STR("blitter",          SLE_STRB,C|S,0, _ini_blitter,           NULL,    STR_NULL, NULL),
 	  SDTG_STR("language",         SLE_STRB, S, 0, _dynlang.curr_file,     NULL,    STR_NULL, NULL),
-	 SDTG_LIST("resolution",     SLE_UINT16, S, 0, _cur_resolution,   "640,480",    STR_NULL, NULL),
+	SDTG_CONDLIST("resolution",  SLE_INT, 2, S, 0, _cur_resolution,   "640,480",    STR_NULL, NULL, 0, SL_MAX_VERSION), // workaround for implicit lengthof() in SDTG_LIST
 	  SDTG_STR("screenshot_format",SLE_STRB, S, 0, _screenshot_format_name,NULL,    STR_NULL, NULL),
 	  SDTG_STR("savegame_format",  SLE_STRB, S, 0, _savegame_format,       NULL,    STR_NULL, NULL),
 	 SDTG_BOOL("rightclick_emulate",         S, 0, _rightclick_emulate,   false,    STR_NULL, NULL),
--- a/src/settings_gui.cpp	Tue Jun 17 10:32:49 2008 +0000
+++ b/src/settings_gui.cpp	Tue Jun 17 13:22:13 2008 +0000
@@ -93,8 +93,8 @@
 	int i;
 
 	for (i = 0; i != _num_resolutions; i++) {
-		if (_resolutions[i][0] == _screen.width &&
-				_resolutions[i][1] == _screen.height) {
+		if (_resolutions[i].width == _screen.width &&
+				_resolutions[i].height == _screen.height) {
 			break;
 		}
 	}
@@ -302,7 +302,7 @@
 				break;
 
 			case GAMEOPT_RESOLUTION_BTN: // Change resolution
-				if (index < _num_resolutions && ChangeResInGame(_resolutions[index][0], _resolutions[index][1])) {
+				if (index < _num_resolutions && ChangeResInGame(_resolutions[index].width, _resolutions[index].height)) {
 					this->SetDirty();
 				}
 				break;
--- a/src/ship_cmd.cpp	Tue Jun 17 10:32:49 2008 +0000
+++ b/src/ship_cmd.cpp	Tue Jun 17 13:22:13 2008 +0000
@@ -599,90 +599,102 @@
 	BeginVehicleMove(v);
 
 	GetNewVehiclePosResult gp = GetNewVehiclePos(v);
-	if (gp.old_tile == gp.new_tile) {
-		/* Staying in tile */
-		if (v->IsInDepot()) {
-			gp.x = v->x_pos;
-			gp.y = v->y_pos;
-		} else {
-			/* Not inside depot */
-			r = VehicleEnterTile(v, gp.new_tile, gp.x, gp.y);
-			if (HasBit(r, VETS_CANNOT_ENTER)) goto reverse_direction;
+	if (v->u.ship.state != TRACK_BIT_WORMHOLE) {
+		/* Not on a bridge */
+		if (gp.old_tile == gp.new_tile) {
+			/* Staying in tile */
+			if (v->IsInDepot()) {
+				gp.x = v->x_pos;
+				gp.y = v->y_pos;
+			} else {
+				/* Not inside depot */
+				r = VehicleEnterTile(v, gp.new_tile, gp.x, gp.y);
+				if (HasBit(r, VETS_CANNOT_ENTER)) goto reverse_direction;
 
-			/* A leave station order only needs one tick to get processed, so we can
-			 * always skip ahead. */
-			if (v->current_order.IsType(OT_LEAVESTATION)) {
-				v->current_order.Free();
-				InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
-			} else if (v->dest_tile != 0) {
-				/* We have a target, let's see if we reached it... */
-				if (v->current_order.IsType(OT_GOTO_STATION) &&
-						IsBuoyTile(v->dest_tile) &&
-						DistanceManhattan(v->dest_tile, gp.new_tile) <= 3) {
-					/* We got within 3 tiles of our target buoy, so let's skip to our
-					 * next order */
-					UpdateVehicleTimetable(v, true);
-					v->cur_order_index++;
-					v->current_order.MakeDummy();
-					InvalidateVehicleOrder(v);
-				} else {
-					/* Non-buoy orders really need to reach the tile */
-					if (v->dest_tile == gp.new_tile) {
-						if (v->current_order.IsType(OT_GOTO_DEPOT)) {
-							if ((gp.x & 0xF) == 8 && (gp.y & 0xF) == 8) {
-								VehicleEnterDepot(v);
-								return;
-							}
-						} else if (v->current_order.IsType(OT_GOTO_STATION)) {
-							v->last_station_visited = v->current_order.GetDestination();
+				/* A leave station order only needs one tick to get processed, so we can
+				* always skip ahead. */
+				if (v->current_order.IsType(OT_LEAVESTATION)) {
+					v->current_order.Free();
+					InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
+				} else if (v->dest_tile != 0) {
+					/* We have a target, let's see if we reached it... */
+					if (v->current_order.IsType(OT_GOTO_STATION) &&
+							IsBuoyTile(v->dest_tile) &&
+							DistanceManhattan(v->dest_tile, gp.new_tile) <= 3) {
+						/* We got within 3 tiles of our target buoy, so let's skip to our
+						* next order */
+						UpdateVehicleTimetable(v, true);
+						v->cur_order_index++;
+						v->current_order.MakeDummy();
+						InvalidateVehicleOrder(v);
+					} else {
+						/* Non-buoy orders really need to reach the tile */
+						if (v->dest_tile == gp.new_tile) {
+							if (v->current_order.IsType(OT_GOTO_DEPOT)) {
+								if ((gp.x & 0xF) == 8 && (gp.y & 0xF) == 8) {
+									VehicleEnterDepot(v);
+									return;
+								}
+							} else if (v->current_order.IsType(OT_GOTO_STATION)) {
+								v->last_station_visited = v->current_order.GetDestination();
 
-							/* Process station in the orderlist. */
-							Station *st = GetStation(v->current_order.GetDestination());
-							if (st->facilities & FACIL_DOCK) { // ugly, ugly workaround for problem with ships able to drop off cargo at wrong stations
-								ShipArrivesAt(v, st);
-								v->BeginLoading();
-							} else { // leave stations without docks right aways
-								v->current_order.MakeLeaveStation();
-								v->cur_order_index++;
-								InvalidateVehicleOrder(v);
+								/* Process station in the orderlist. */
+								Station *st = GetStation(v->current_order.GetDestination());
+								if (st->facilities & FACIL_DOCK) { // ugly, ugly workaround for problem with ships able to drop off cargo at wrong stations
+									ShipArrivesAt(v, st);
+									v->BeginLoading();
+								} else { // leave stations without docks right aways
+									v->current_order.MakeLeaveStation();
+									v->cur_order_index++;
+									InvalidateVehicleOrder(v);
+								}
 							}
 						}
 					}
 				}
 			}
+		} else {
+			DiagDirection diagdir;
+			/* New tile */
+			if (TileX(gp.new_tile) >= MapMaxX() || TileY(gp.new_tile) >= MapMaxY()) {
+				goto reverse_direction;
+			}
+
+			dir = ShipGetNewDirectionFromTiles(gp.new_tile, gp.old_tile);
+			assert(dir == DIR_NE || dir == DIR_SE || dir == DIR_SW || dir == DIR_NW);
+			diagdir = DirToDiagDir(dir);
+			tracks = GetAvailShipTracks(gp.new_tile, diagdir);
+			if (tracks == TRACK_BIT_NONE) goto reverse_direction;
+
+			/* Choose a direction, and continue if we find one */
+			track = ChooseShipTrack(v, gp.new_tile, diagdir, tracks);
+			if (track == INVALID_TRACK) goto reverse_direction;
+
+			b = _ship_subcoord[diagdir][track];
+
+			gp.x = (gp.x & ~0xF) | b[0];
+			gp.y = (gp.y & ~0xF) | b[1];
+
+			/* Call the landscape function and tell it that the vehicle entered the tile */
+			r = VehicleEnterTile(v, gp.new_tile, gp.x, gp.y);
+			if (HasBit(r, VETS_CANNOT_ENTER)) goto reverse_direction;
+
+			if (!HasBit(r, VETS_ENTERED_WORMHOLE)) {
+				v->tile = gp.new_tile;
+				v->u.ship.state = TrackToTrackBits(track);
+			}
+
+			v->direction = (Direction)b[2];
 		}
 	} else {
-		DiagDirection diagdir;
-		/* New tile */
-		if (TileX(gp.new_tile) >= MapMaxX() || TileY(gp.new_tile) >= MapMaxY()) {
-			goto reverse_direction;
+		/* On a bridge */
+		if (!IsTileType(gp.new_tile, MP_TUNNELBRIDGE) || !HasBit(VehicleEnterTile(v, gp.new_tile, gp.x, gp.y), VETS_ENTERED_WORMHOLE)) {
+			v->x_pos = gp.x;
+			v->y_pos = gp.y;
+			VehiclePositionChanged(v);
+			if (!(v->vehstatus & VS_HIDDEN)) EndVehicleMove(v);
+			return;
 		}
-
-		dir = ShipGetNewDirectionFromTiles(gp.new_tile, gp.old_tile);
-		assert(dir == DIR_NE || dir == DIR_SE || dir == DIR_SW || dir == DIR_NW);
-		diagdir = DirToDiagDir(dir);
-		tracks = GetAvailShipTracks(gp.new_tile, diagdir);
-		if (tracks == TRACK_BIT_NONE) goto reverse_direction;
-
-		/* Choose a direction, and continue if we find one */
-		track = ChooseShipTrack(v, gp.new_tile, diagdir, tracks);
-		if (track == INVALID_TRACK) goto reverse_direction;
-
-		b = _ship_subcoord[diagdir][track];
-
-		gp.x = (gp.x & ~0xF) | b[0];
-		gp.y = (gp.y & ~0xF) | b[1];
-
-		/* Call the landscape function and tell it that the vehicle entered the tile */
-		r = VehicleEnterTile(v, gp.new_tile, gp.x, gp.y);
-		if (HasBit(r, VETS_CANNOT_ENTER)) goto reverse_direction;
-
-		if (!HasBit(r, VETS_ENTERED_WORMHOLE)) {
-			v->tile = gp.new_tile;
-			v->u.ship.state = TrackToTrackBits(track);
-		}
-
-		v->direction = (Direction)b[2];
 	}
 
 	/* update image of ship, as well as delta XY */
--- a/src/signs_func.h	Tue Jun 17 10:32:49 2008 +0000
+++ b/src/signs_func.h	Tue Jun 17 13:22:13 2008 +0000
@@ -15,6 +15,7 @@
 
 /* signs_gui.cpp */
 void ShowRenameSignWindow(const Sign *si);
+void HandleClickOnSign(const Sign *si);
 
 void ShowSignList();
 
--- a/src/signs_gui.cpp	Tue Jun 17 10:32:49 2008 +0000
+++ b/src/signs_gui.cpp	Tue Jun 17 13:22:13 2008 +0000
@@ -8,6 +8,7 @@
 #include "textbuf_gui.h"
 #include "window_gui.h"
 #include "player_gui.h"
+#include "player_func.h"
 #include "signs_base.h"
 #include "signs_func.h"
 #include "debug.h"
@@ -301,6 +302,15 @@
 	_query_sign_edit_widgets,
 };
 
+void HandleClickOnSign(const Sign *si)
+{
+	if (_ctrl_pressed && si->owner == _local_player) {
+		RenameSign(si->index, "");
+		return;
+	}
+	ShowRenameSignWindow(si);
+}
+
 void ShowRenameSignWindow(const Sign *si)
 {
 	/* Delete all other edit windows and the save window */
--- a/src/slope_func.h	Tue Jun 17 10:32:49 2008 +0000
+++ b/src/slope_func.h	Tue Jun 17 13:22:13 2008 +0000
@@ -347,13 +347,11 @@
  * Returns the foundation needed to flatten a slope.
  * The returned foundation is either FOUNDATION_NONE if the tile was already flat, or FOUNDATION_LEVELED.
  *
- * @pre      The slope must not be steep.
  * @param s  The current #Slope.
  * @return   The needed #Foundation.
  */
 static inline Foundation FlatteningFoundation(Slope s)
 {
-	assert(!IsSteepSlope(s));
 	return (s == SLOPE_FLAT ? FOUNDATION_NONE : FOUNDATION_LEVELED);
 }
 
--- a/src/sortlist_type.h	Tue Jun 17 10:32:49 2008 +0000
+++ b/src/sortlist_type.h	Tue Jun 17 13:22:13 2008 +0000
@@ -7,6 +7,8 @@
 
 #include "core/enum_type.hpp"
 #include "core/bitmath_func.hpp"
+#include "core/mem_func.hpp"
+#include "core/sort_func.hpp"
 #include "misc/smallvec.h"
 #include "date_type.h"
 
@@ -30,7 +32,7 @@
 public:
 	typedef int CDECL SortFunction(const T*, const T*);
 
-public: // Temporary: public for conversion only
+protected:
 	SortFunction* const *func_list; ///< The sort criteria functions
 	SortListFlags flags;            ///< used to control sorting/resorting/etc.
 	uint8 sort_type;                ///< what criteria to sort on
@@ -55,21 +57,6 @@
 		this->resort_timer = DAY_TICKS * 10;
 	}
 
-	/**
-	 * Reverse the list
-	 */
-	void Reverse()
-	{
-		assert(this->IsSortable());
-
-		T *a = this->data;
-		T *b = a + (this->items - 1);
-
-		do {
-			Swap(*a, *b);
-		} while (++a < --b);
-	}
-
 public:
 	GUIList() :
 		func_list(NULL),
@@ -174,25 +161,23 @@
 	 *  Since that is the worst condition for the sort function
 	 *  reverse the list here.
 	 */
-	FORCEINLINE void ToggleSortOrder()
+	void ToggleSortOrder()
 	{
 		this->flags ^= VL_DESC;
 
-		if (this->IsSortable()) this->Reverse();
+		if (this->IsSortable()) MemReverseT(this->data, this->items);
 	}
 
 	/**
-	 * GnomeSort algorithm
-	 *  This sorting uses a slightly modifyied Gnome search.
-	 *  The basic Gnome search trys to sort already sorted
-	 *  list parts. The modification skips these. For the first
-	 *  sorting we use qsort since it is faster for irregular
-	 *  sorted data.
+	 * Sort the list.
+	 *  For the first sorting we use qsort since it is
+	 *  faster for irregular sorted data. After that we
+	 *  use gsort.
 	 *
 	 * @param compare The function to compare two list items
 	 * @return true if the list sequence has been altered
 	 * */
-	FORCEINLINE bool Sort(SortFunction *compare)
+	bool Sort(SortFunction *compare)
 	{
 		/* Do not sort if the resort bit is not set */
 		if (!HASBITS(this->flags, VL_RESORT)) return false;
@@ -208,40 +193,12 @@
 
 		if (HASBITS(this->flags, VL_FIRST_SORT)) {
 			CLRBITS(this->flags, VL_FIRST_SORT);
-			qsort(this->data, this->items, sizeof(T), (int (CDECL *)(const void *, const void *))compare);
 
-			if (desc) this->Reverse();
+			QSortT(this->data, this->items, compare, desc);
 			return true;
 		}
 
-		T *a = this->data;
-		T *b = a + 1;
-
-		uint length = this->items;
-		uint offset = 0; // Jump variable
-
-		while (length > 1) {
-			const int diff = compare(a, b);
-			if ((!desc && diff <= 0) || (desc && diff >= 0)) {
-				if (offset != 0) {
-					/* Jump back to the last direction switch point */
-					a += offset;
-					b += offset;
-					offset = 0;
-					continue;
-				}
-				a++;
-				b++;
-				length--;
-			} else {
-				Swap(*a, *b);
-				if (a != this->data) {
-					offset++;
-					a--;
-					b--;
-				}
-			}
-		}
+		GSortT(this->data, this->items, compare, desc);
 		return true;
 	}
 
@@ -292,7 +249,7 @@
 	void RebuildDone()
 	{
 		CLRBITS(this->flags, VL_REBUILD);
-		SETBITS(this->flags, VL_RESORT);
+		SETBITS(this->flags, VL_RESORT | VL_FIRST_SORT);
 	}
 };
 
--- a/src/station_cmd.cpp	Tue Jun 17 10:32:49 2008 +0000
+++ b/src/station_cmd.cpp	Tue Jun 17 13:22:13 2008 +0000
@@ -1102,7 +1102,7 @@
 		tile_delta = (axis == AXIS_X ? TileDiffXY(1, 0) : TileDiffXY(0, 1));
 		track = AxisToTrack(axis);
 
-		layout_ptr = (byte*)alloca(numtracks * plat_len);
+		layout_ptr = AllocaM(byte, numtracks * plat_len);
 		GetStationLayout(layout_ptr, numtracks, plat_len, statspec);
 
 		numtracks_orig = numtracks;
@@ -1584,7 +1584,7 @@
 CommandCost CmdRemoveRoadStop(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
 {
 	/* Make sure the specified tile is a road stop of the correct type */
-	if (!IsTileType(tile, MP_STATION) || !IsRoadStop(tile) || (uint32)GetRoadStopType(tile) != p2) return CMD_ERROR;
+	if (!IsTileType(tile, MP_STATION) || !IsRoadStop(tile) || (uint32)GetRoadStopType(tile) != GB(p2, 0, 1)) return CMD_ERROR;
 	Station *st = GetStationByTile(tile);
 	/* Save the stop info before it is removed */
 	bool is_drive_through = IsDriveThroughStopTile(tile);
--- a/src/strings.cpp	Tue Jun 17 10:32:49 2008 +0000
+++ b/src/strings.cpp	Tue Jun 17 13:22:13 2008 +0000
@@ -1213,7 +1213,7 @@
 	if (IsInsideMM(ind, (SPECSTR_RESOLUTION_START - 0x70E4), (SPECSTR_RESOLUTION_END - 0x70E4) + 1)) {
 		int i = ind - (SPECSTR_RESOLUTION_START - 0x70E4);
 		buff += snprintf(
-			buff, last - buff + 1, "%dx%d", _resolutions[i][0], _resolutions[i][1]
+			buff, last - buff + 1, "%dx%d", _resolutions[i].width, _resolutions[i].height
 		);
 		return buff;
 	}
--- a/src/table/bridge_land.h	Tue Jun 17 10:32:49 2008 +0000
+++ b/src/table/bridge_land.h	Tue Jun 17 13:22:13 2008 +0000
@@ -28,6 +28,12 @@
 # define MW(a) {a, PALETTE_TO_STRUCT_WHITE}
 # define MC(a) {a, PALETTE_TO_STRUCT_CONCRETE}
 
+static const PalSpriteID _aqueduct_sprites[] = {
+	{ SPR_AQUEDUCT_MIDDLE_X, PAL_NONE }, {                  0x0, PAL_NONE }, { SPR_AQUEDUCT_PILLAR_X, PAL_NONE }, {                  0x0, PAL_NONE },
+	{ SPR_AQUEDUCT_MIDDLE_Y, PAL_NONE }, {                  0x0, PAL_NONE }, { SPR_AQUEDUCT_PILLAR_Y, PAL_NONE }, {                  0x0, PAL_NONE },
+	{  SPR_AQUEDUCT_RAMP_SW, PAL_NONE }, { SPR_AQUEDUCT_RAMP_SE, PAL_NONE }, {  SPR_AQUEDUCT_RAMP_NE, PAL_NONE }, { SPR_AQUEDUCT_RAMP_NW, PAL_NONE },
+};
+
 static const PalSpriteID _bridge_sprite_table_4_0[] = {
 	{  0x9A9, PAL_NONE }, {  0x99F, PAL_NONE }, {  0x9B1, PAL_NONE }, {    0x0, PAL_NONE },
 	{  0x9A5, PAL_NONE }, {  0x997, PAL_NONE }, {  0x9AD, PAL_NONE }, {    0x0, PAL_NONE },
--- a/src/table/files.h	Tue Jun 17 10:32:49 2008 +0000
+++ b/src/table/files.h	Tue Jun 17 13:22:13 2008 +0000
@@ -33,7 +33,7 @@
 		{ "TRGT.GRF",      {0xfc, 0xde, 0x1d, 0x7e, 0x8a, 0x74, 0x19, 0x7d, 0x72, 0xa6, 0x26, 0x95, 0x88, 0x4b, 0x90, 0x9e} }
 	},
 	{ "SAMPLE.CAT",    {0x42, 0x2e, 0xa3, 0xdd, 0x07, 0x4d, 0x28, 0x59, 0xbb, 0x51, 0x63, 0x9a, 0x6e, 0x0e, 0x85, 0xda} },
-	{ "OPENTTDD.GRF",  {0xfa, 0x57, 0xbe, 0xb3, 0xb7, 0xe1, 0x9b, 0xa2, 0x38, 0x8f, 0x1a, 0xb7, 0xce, 0x2a, 0x93, 0x59} }
+	{ "OPENTTDD.GRF",  {0xbe, 0x26, 0xaf, 0xdf, 0x8f, 0x24, 0xba, 0x48, 0x8c, 0x87, 0xdd, 0xbc, 0xb3, 0xf1, 0x53, 0xae} }
 };
 
 static FileList files_win = {
@@ -46,5 +46,5 @@
 		{ "TRGTR.GRF",     {0xde, 0x53, 0x65, 0x05, 0x17, 0xfe, 0x66, 0x1c, 0xea, 0xa3, 0x13, 0x8c, 0x6e, 0xdb, 0x0e, 0xb8} }
 	},
 	{ "SAMPLE.CAT",    {0x92, 0x12, 0xe8, 0x1e, 0x72, 0xba, 0xdd, 0x4b, 0xbe, 0x1e, 0xae, 0xae, 0x66, 0x45, 0x8e, 0x10} },
-	{ "OPENTTDW.GRF",  {0x3e, 0xe0, 0x24, 0xcd, 0x32, 0xa0, 0xd1, 0xd3, 0x21, 0xbc, 0x31, 0x7f, 0x22, 0x13, 0x6e, 0x81} }
+	{ "OPENTTDW.GRF",  {0xa4, 0xbf, 0xe6, 0x1d, 0xdf, 0xef, 0x50, 0x8a, 0x15, 0x73, 0xa6, 0x63, 0x9d, 0x0f, 0x52, 0xb3} }
 };
--- a/src/table/railtypes.h	Tue Jun 17 10:32:49 2008 +0000
+++ b/src/table/railtypes.h	Tue Jun 17 13:22:13 2008 +0000
@@ -14,6 +14,7 @@
 	{ /* Main Sprites */
 		{ SPR_RAIL_TRACK_Y, SPR_RAIL_TRACK_N_S, SPR_RAIL_TRACK_BASE, SPR_RAIL_SINGLE_Y, SPR_RAIL_SINGLE_X,
 			SPR_RAIL_SINGLE_NORTH, SPR_RAIL_SINGLE_SOUTH, SPR_RAIL_SINGLE_EAST, SPR_RAIL_SINGLE_WEST,
+			SPR_TRACKS_FOR_SLOPES_RAIL_BASE,
 			SPR_CROSSING_OFF_X_RAIL,
 			SPR_TUNNEL_ENTRY_REAR_RAIL
 		},
@@ -69,6 +70,7 @@
 	{ /* Main Sprites */
 		{ SPR_RAIL_TRACK_Y, SPR_RAIL_TRACK_N_S, SPR_RAIL_TRACK_BASE, SPR_RAIL_SINGLE_Y, SPR_RAIL_SINGLE_X,
 			SPR_RAIL_SINGLE_NORTH, SPR_RAIL_SINGLE_SOUTH, SPR_RAIL_SINGLE_EAST, SPR_RAIL_SINGLE_WEST,
+			SPR_TRACKS_FOR_SLOPES_RAIL_BASE,
 			SPR_CROSSING_OFF_X_RAIL,
 			SPR_TUNNEL_ENTRY_REAR_RAIL
 		},
@@ -128,6 +130,7 @@
 	{ /* Main Sprites */
 		{ SPR_MONO_TRACK_Y, SPR_MONO_TRACK_N_S, SPR_MONO_TRACK_BASE, SPR_MONO_SINGLE_Y, SPR_MONO_SINGLE_X,
 			SPR_MONO_SINGLE_NORTH, SPR_MONO_SINGLE_SOUTH, SPR_MONO_SINGLE_EAST, SPR_MONO_SINGLE_WEST,
+			SPR_TRACKS_FOR_SLOPES_MONO_BASE,
 			SPR_CROSSING_OFF_X_MONO,
 			SPR_TUNNEL_ENTRY_REAR_MONO
 		},
@@ -183,6 +186,7 @@
 	{ /* Main sprites */
 		{ SPR_MGLV_TRACK_Y, SPR_MGLV_TRACK_N_S, SPR_MGLV_TRACK_BASE, SPR_MGLV_SINGLE_Y, SPR_MGLV_SINGLE_X,
 			SPR_MGLV_SINGLE_NORTH, SPR_MGLV_SINGLE_SOUTH, SPR_MGLV_SINGLE_EAST, SPR_MGLV_SINGLE_WEST,
+			SPR_TRACKS_FOR_SLOPES_MAGLEV_BASE,
 			SPR_CROSSING_OFF_X_MAGLEV,
 			SPR_TUNNEL_ENTRY_REAR_MAGLEV
 		},
--- a/src/table/sprites.h	Tue Jun 17 10:32:49 2008 +0000
+++ b/src/table/sprites.h	Tue Jun 17 13:22:13 2008 +0000
@@ -49,7 +49,7 @@
 
 	/* Extra graphic spritenumbers */
 	SPR_OPENTTD_BASE     = 4896,
-	OPENTTD_SPRITE_COUNT = 145,
+	OPENTTD_SPRITE_COUNT = 147,
 
 	/* Halftile-selection sprites */
 	SPR_HALFTILE_SELECTION_FLAT = SPR_OPENTTD_BASE,
@@ -132,7 +132,26 @@
 	SPR_CANALS_BASE   = SPR_SIGNALS_BASE + PRESIGNAL_SEMAPHORE_AND_PBS_SPRITE_COUNT,
 	CANALS_SPRITE_COUNT = 65,
 
-	SPR_SLOPES_BASE              = SPR_CANALS_BASE + CANALS_SPRITE_COUNT,
+	/* Sprites for the Aqueduct. */
+	SPR_AQUEDUCT_BASE     = SPR_CANALS_BASE + CANALS_SPRITE_COUNT,
+	SPR_AQUEDUCT_RAMP_SW  = SPR_AQUEDUCT_BASE + 0,
+	SPR_AQUEDUCT_RAMP_SE  = SPR_AQUEDUCT_BASE + 1,
+	SPR_AQUEDUCT_RAMP_NE  = SPR_AQUEDUCT_BASE + 2,
+	SPR_AQUEDUCT_RAMP_NW  = SPR_AQUEDUCT_BASE + 3,
+	SPR_AQUEDUCT_MIDDLE_X = SPR_AQUEDUCT_BASE + 4,
+	SPR_AQUEDUCT_MIDDLE_Y = SPR_AQUEDUCT_BASE + 5,
+	SPR_AQUEDUCT_PILLAR_X = SPR_AQUEDUCT_BASE + 6,
+	SPR_AQUEDUCT_PILLAR_Y = SPR_AQUEDUCT_BASE + 7,
+	AQUEDUCT_SPRITE_COUNT = 8,
+
+	/* Sprites for 'highlighting' tracks on sloped land. */
+ 	SPR_TRACKS_FOR_SLOPES_BASE        = SPR_AQUEDUCT_BASE + AQUEDUCT_SPRITE_COUNT,
+	SPR_TRACKS_FOR_SLOPES_RAIL_BASE   = SPR_TRACKS_FOR_SLOPES_BASE + 0,
+	SPR_TRACKS_FOR_SLOPES_MONO_BASE   = SPR_TRACKS_FOR_SLOPES_BASE + 4,
+	SPR_TRACKS_FOR_SLOPES_MAGLEV_BASE = SPR_TRACKS_FOR_SLOPES_BASE + 8,
+	TRACKS_FOR_SLOPES_SPRITE_COUNT = 12,
+
+	SPR_SLOPES_BASE              = SPR_TRACKS_FOR_SLOPES_BASE + TRACKS_FOR_SLOPES_SPRITE_COUNT,
 	SPR_SLOPES_INCLINED_OFFSET   = 15,
 	SPR_SLOPES_VIRTUAL_BASE      = SPR_SLOPES_BASE - SPR_SLOPES_INCLINED_OFFSET, // The original foundations (see SPR_FOUNDATION_BASE below) are mapped before the additional foundations.
 	SPR_TRKFOUND_BLOCK_SIZE      = 22, // The normal track foundation sprites are organized in blocks of 22.
@@ -1244,6 +1263,7 @@
 	SPR_IMG_SHIP_DEPOT    = 748,
 	SPR_IMG_SHIP_DOCK     = 746,
 	SPR_IMG_BOUY          = 693,
+	SPR_IMG_AQUEDUCT      = SPR_OPENTTD_BASE + 145,
 
 	/* music_gui.c */
 	SPR_IMG_SKIP_TO_PREV  = 709,
@@ -1346,6 +1366,7 @@
 	SPR_CURSOR_CANAL          = SPR_OPENTTD_BASE + 89,
 	SPR_CURSOR_LOCK           = SPR_OPENTTD_BASE + 87,
 	SPR_CURSOR_RIVER          = SPR_OPENTTD_BASE + 137,
+	SPR_CURSOR_AQUEDUCT       = SPR_OPENTTD_BASE + 146,
 
 	/* shared road & rail cursors */
 	SPR_CURSOR_BRIDGE         = 2593,
--- a/src/terraform_gui.cpp	Tue Jun 17 10:32:49 2008 +0000
+++ b/src/terraform_gui.cpp	Tue Jun 17 13:22:13 2008 +0000
@@ -135,7 +135,7 @@
 			DoCommandP(end_tile, start_tile, _ctrl_pressed, CcBuildCanal, CMD_BUILD_CANAL | CMD_MSG(STR_CANT_BUILD_CANALS));
 			break;
 		case DDSP_CREATE_RIVER:
-			DoCommandP(end_tile, start_tile, 2, CcBuildCanal, CMD_BUILD_CANAL | CMD_MSG(STR_CANT_BUILD_CANALS));
+			DoCommandP(end_tile, start_tile, 2, CcBuildCanal, CMD_BUILD_CANAL | CMD_MSG(STR_CANT_PLACE_RIVERS));
 			break;
 		default:
 			return false;
--- a/src/thread_pthread.cpp	Tue Jun 17 10:32:49 2008 +0000
+++ b/src/thread_pthread.cpp	Tue Jun 17 13:22:13 2008 +0000
@@ -102,8 +102,6 @@
 
 		pthread_join(m_thr, NULL);
 		m_thr = 0;
-
-		delete this;
 	}
 
 	/* virtual */ bool IsCurrent()
@@ -136,20 +134,14 @@
 		/* The new thread stops here so the calling thread can complete pthread_create() call */
 		sem_wait(&m_sem_start);
 
-		/* Did this thread die naturally/via exit, or did it join? */
-		bool exit = false;
-
 		/* Call the proc of the creator to continue this thread */
 		try {
 			m_proc(m_param);
 		} catch (...) {
-			exit = true;
 		}
 
 		/* Notify threads waiting for our completion */
 		sem_post(&m_sem_stop);
-
-		if (exit) delete this;
 	}
 };
 
--- a/src/toolbar_gui.cpp	Tue Jun 17 10:32:49 2008 +0000
+++ b/src/toolbar_gui.cpp	Tue Jun 17 13:22:13 2008 +0000
@@ -58,6 +58,55 @@
 	TB_LOWER
 };
 
+enum ToolbarNormalWidgets {
+	TBN_PAUSE         = 0,
+	TBN_FASTFORWARD,
+	TBN_SETTINGS,
+	TBN_SAVEGAME,
+	TBN_SMALLMAP,
+	TBN_TOWNDIRECTORY,
+	TBN_SUBSIDIES,
+	TBN_STATIONS,
+	TBN_FINANCES,
+	TBN_PLAYERS,
+	TBN_GRAPHICS,
+	TBN_LEAGUE,
+	TBN_INDUSTRIES,
+	TBN_VEHICLESTART,      ///< trains, actually.  So following are trucks, boats and planes
+	TBN_TRAINS        = TBN_VEHICLESTART,
+	TBN_ROADVEHS,
+	TBN_SHIPS,
+	TBN_AIRCRAFTS,
+	TBN_ZOOMIN,
+	TBN_ZOOMOUT,
+	TBN_RAILS,
+	TBN_ROADS,
+	TBN_WATER,
+	TBN_AIR,
+	TBN_LANDSCAPE,
+	TBN_MUSICSOUND,
+	TBN_NEWSREPORT,
+	TBN_HELP,
+	TBN_SWITCHBAR,         ///< only available when toolbar has been split
+};
+
+enum ToolbarScenEditorWidgets {
+	TBSE_PAUSE        = 0,
+	TBSE_FASTFORWARD,
+	TBSE_SAVESCENARIO = 3,
+	TBSE_SPACERPANEL,
+	TBSE_DATEBACKWARD = 6,
+	TBSE_DATEFORWARD,
+	TBSE_ZOOMIN       = 9,
+	TBSE_ZOOMOUT,
+	TBSE_LANDGENERATE,
+	TBSE_TOWNGENERATE,
+	TBSE_INDUSTRYGENERATE,
+	TBSE_BUILDROAD,
+	TBSE_PLANTTREES,
+	TBSE_PLACESIGNS,
+};
+
 static ToolbarMode _toolbar_mode;
 
 static void SelectSignTool()
@@ -140,17 +189,17 @@
 	if (IsTransparencySet(TO_HOUSES))                SetBit(x, 12);
 	if (IsTransparencySet(TO_SIGNS))                 SetBit(x, 13);
 
-	PopupMainToolbMenu(w, 2, STR_02C4_GAME_OPTIONS, 14, 0, 0, x);
+	PopupMainToolbMenu(w, TBN_SETTINGS, STR_02C4_GAME_OPTIONS, 14, 0, 0, x);
 }
 
 static void MenuClickSettings(int index)
 {
 	switch (index) {
-		case 0: ShowGameOptions();      return;
-		case 1: ShowGameDifficulty();   return;
-		case 2: ShowPatchesSelection(); return;
-		case 3: ShowNewGRFSettings(!_networking, true, true, &_grfconfig);   return;
-		case 4: ShowTransparencyToolbar(); break;
+		case  0: ShowGameOptions();                              return;
+		case  1: ShowGameDifficulty();                           return;
+		case  2: ShowPatchesSelection();                         return;
+		case  3: ShowNewGRFSettings(!_networking, true, true, &_grfconfig);   return;
+		case  4: ShowTransparencyToolbar();                      break;
 
 		case  6: ToggleBit(_display_opt, DO_SHOW_TOWN_NAMES);    break;
 		case  7: ToggleBit(_display_opt, DO_SHOW_STATION_NAMES); break;
@@ -168,12 +217,12 @@
 
 static void ToolbarSaveClick(Window *w)
 {
-	PopupMainToolbMenu(w, 3, STR_015C_SAVE_GAME, 4);
+	PopupMainToolbMenu(w, TBN_SAVEGAME, STR_015C_SAVE_GAME, 4);
 }
 
 static void ToolbarScenSaveOrLoad(Window *w)
 {
-	PopupMainToolbMenu(w, 3, STR_0292_SAVE_SCENARIO, 6);
+	PopupMainToolbMenu(w, TBSE_SAVESCENARIO, STR_0292_SAVE_SCENARIO, 6);
 }
 
 static void MenuClickSaveLoad(int index)
@@ -200,7 +249,7 @@
 
 static void ToolbarMapClick(Window *w)
 {
-	PopupMainToolbMenu(w, 4, STR_02DE_MAP_OF_WORLD, 3);
+	PopupMainToolbMenu(w, TBN_SMALLMAP, STR_02DE_MAP_OF_WORLD, 3);
 }
 
 static void MenuClickMap(int index)
@@ -226,7 +275,7 @@
 
 static void ToolbarTownClick(Window *w)
 {
-	PopupMainToolbMenu(w, 5, STR_02BB_TOWN_DIRECTORY, 1);
+	PopupMainToolbMenu(w, TBN_TOWNDIRECTORY, STR_02BB_TOWN_DIRECTORY, 1);
 }
 
 static void MenuClickTown(int index)
@@ -238,7 +287,7 @@
 
 static void ToolbarSubsidiesClick(Window *w)
 {
-	PopupMainToolbMenu(w, 6, STR_02DD_SUBSIDIES, 1);
+	PopupMainToolbMenu(w, TBN_SUBSIDIES, STR_02DD_SUBSIDIES, 1);
 }
 
 static void MenuClickSubsidies(int index)
@@ -250,7 +299,7 @@
 
 static void ToolbarStationsClick(Window *w)
 {
-	PopupMainPlayerToolbMenu(w, 7, 0);
+	PopupMainPlayerToolbMenu(w, TBN_STATIONS, 0);
 }
 
 static void MenuClickStations(int index)
@@ -262,7 +311,7 @@
 
 static void ToolbarFinancesClick(Window *w)
 {
-	PopupMainPlayerToolbMenu(w, 8, 0);
+	PopupMainPlayerToolbMenu(w, TBN_FINANCES, 0);
 }
 
 static void MenuClickFinances(int index)
@@ -274,7 +323,7 @@
 
 static void ToolbarPlayersClick(Window *w)
 {
-	PopupMainPlayerToolbMenu(w, 9, 0);
+	PopupMainPlayerToolbMenu(w, TBN_PLAYERS, 0);
 }
 
 static void MenuClickCompany(int index)
@@ -291,7 +340,7 @@
 
 static void ToolbarGraphsClick(Window *w)
 {
-	PopupMainToolbMenu(w, 10, STR_0154_OPERATING_PROFIT_GRAPH, (_toolbar_mode == TB_NORMAL) ? 6 : 8);
+	PopupMainToolbMenu(w, TBN_GRAPHICS, STR_0154_OPERATING_PROFIT_GRAPH, (_toolbar_mode == TB_NORMAL) ? 6 : 8);
 }
 
 static void MenuClickGraphs(int index)
@@ -313,7 +362,7 @@
 
 static void ToolbarLeagueClick(Window *w)
 {
-	PopupMainToolbMenu(w, 11, STR_015A_COMPANY_LEAGUE_TABLE, 2);
+	PopupMainToolbMenu(w, TBN_LEAGUE, STR_015A_COMPANY_LEAGUE_TABLE, 2);
 }
 
 static void MenuClickLeague(int index)
@@ -329,7 +378,7 @@
 static void ToolbarIndustryClick(Window *w)
 {
 	/* Disable build-industry menu if we are a spectator */
-	PopupMainToolbMenu(w, 12, STR_INDUSTRY_DIR, 2, (_current_player == PLAYER_SPECTATOR) ? (1 << 1) : 0);
+	PopupMainToolbMenu(w, TBN_INDUSTRIES, STR_INDUSTRY_DIR, 2, (_current_player == PLAYER_SPECTATOR) ? 2 : 0);
 }
 
 static void MenuClickIndustry(int index)
@@ -350,7 +399,7 @@
 	FOR_ALL_VEHICLES(v) {
 		if (v->type == veh && v->IsPrimaryVehicle()) ClrBit(dis, v->owner);
 	}
-	PopupMainPlayerToolbMenu(w, 13 + veh, dis);
+	PopupMainPlayerToolbMenu(w, TBN_VEHICLESTART + veh, dis);
 }
 
 
@@ -405,7 +454,7 @@
 static void ToolbarZoomInClick(Window *w)
 {
 	if (DoZoomInOutWindow(ZOOM_IN, FindWindowById(WC_MAIN_WINDOW, 0))) {
-		w->HandleButtonClick(17);
+		w->HandleButtonClick(TBN_ZOOMIN);
 		SndPlayFx(SND_15_BEEP);
 	}
 }
@@ -415,7 +464,7 @@
 static void ToolbarZoomOutClick(Window *w)
 {
 	if (DoZoomInOutWindow(ZOOM_OUT, FindWindowById(WC_MAIN_WINDOW, 0))) {
-		w->HandleButtonClick(18);
+		w->HandleButtonClick(TBN_ZOOMOUT);
 		SndPlayFx(SND_15_BEEP);
 	}
 }
@@ -425,7 +474,7 @@
 static void ToolbarBuildRailClick(Window *w)
 {
 	const Player *p = GetPlayer(_local_player);
-	PopupMainToolbMenu(w, 19, STR_1015_RAILROAD_CONSTRUCTION, RAILTYPE_END, ~p->avail_railtypes, _last_built_railtype);
+	PopupMainToolbMenu(w, TBN_RAILS, STR_1015_RAILROAD_CONSTRUCTION, RAILTYPE_END, ~p->avail_railtypes, _last_built_railtype);
 }
 
 static void MenuClickBuildRail(int index)
@@ -440,7 +489,7 @@
 {
 	const Player *p = GetPlayer(_local_player);
 	/* The standard road button is *always* available */
-	PopupMainToolbMenu(w, 20, STR_180A_ROAD_CONSTRUCTION, 2, ~(p->avail_roadtypes | ROADTYPES_ROAD), _last_built_roadtype);
+	PopupMainToolbMenu(w, TBN_ROADS, STR_180A_ROAD_CONSTRUCTION, 2, ~(p->avail_roadtypes | ROADTYPES_ROAD), _last_built_roadtype);
 }
 
 static void MenuClickBuildRoad(int index)
@@ -453,7 +502,7 @@
 
 static void ToolbarBuildWaterClick(Window *w)
 {
-	PopupMainToolbMenu(w, 21, STR_9800_DOCK_CONSTRUCTION, 1);
+	PopupMainToolbMenu(w, TBN_WATER, STR_9800_DOCK_CONSTRUCTION, 1);
 }
 
 static void MenuClickBuildWater(int index)
@@ -465,7 +514,7 @@
 
 static void ToolbarBuildAirClick(Window *w)
 {
-	PopupMainToolbMenu(w, 22, STR_A01D_AIRPORT_CONSTRUCTION, 1);
+	PopupMainToolbMenu(w, TBN_AIR, STR_A01D_AIRPORT_CONSTRUCTION, 1);
 }
 
 static void MenuClickBuildAir(int index)
@@ -477,7 +526,7 @@
 
 static void ToolbarForestClick(Window *w)
 {
-	PopupMainToolbMenu(w, 23, STR_LANDSCAPING, 3);
+	PopupMainToolbMenu(w, TBN_LANDSCAPE, STR_LANDSCAPING, 3);
 }
 
 static void MenuClickForest(int index)
@@ -493,7 +542,7 @@
 
 static void ToolbarMusicClick(Window *w)
 {
-	PopupMainToolbMenu(w, 24, STR_01D3_SOUND_MUSIC, 1);
+	PopupMainToolbMenu(w, TBN_MUSICSOUND, STR_01D3_SOUND_MUSIC, 1);
 }
 
 static void MenuClickMusicWindow(int index)
@@ -505,7 +554,7 @@
 
 static void ToolbarNewspaperClick(Window *w)
 {
-	PopupMainToolbMenu(w, 25, STR_0200_LAST_MESSAGE_NEWS_REPORT, 3);
+	PopupMainToolbMenu(w, TBN_NEWSREPORT, STR_0200_LAST_MESSAGE_NEWS_REPORT, 3);
 }
 
 static void MenuClickNewspaper(int index)
@@ -521,7 +570,7 @@
 
 static void ToolbarHelpClick(Window *w)
 {
-	PopupMainToolbMenu(w, 26, STR_02D5_LAND_BLOCK_INFO, 6);
+	PopupMainToolbMenu(w, TBN_HELP, STR_02D5_LAND_BLOCK_INFO, 6);
 }
 
 static void MenuClickSmallScreenshot()
@@ -556,7 +605,7 @@
 	}
 
 	SplitToolbar(w);
-	w->HandleButtonClick(27);
+	w->HandleButtonClick(TBN_SWITCHBAR);
 	SetWindowDirty(w);
 	SndPlayFx(SND_15_BEEP);
 }
@@ -567,7 +616,7 @@
 {
 	/* don't allow too fast scrolling */
 	if ((w->flags4 & WF_TIMEOUT_MASK) <= 2 << WF_TIMEOUT_SHL) {
-		w->HandleButtonClick(6);
+		w->HandleButtonClick(TBSE_DATEBACKWARD);
 		w->SetDirty();
 
 		_settings_newgame.game_creation.starting_year = Clamp(_settings_newgame.game_creation.starting_year - 1, MIN_YEAR, MAX_YEAR);
@@ -580,7 +629,7 @@
 {
 	/* don't allow too fast scrolling */
 	if ((w->flags4 & WF_TIMEOUT_MASK) <= 2 << WF_TIMEOUT_SHL) {
-		w->HandleButtonClick(7);
+		w->HandleButtonClick(TBSE_DATEFORWARD);
 		w->SetDirty();
 
 		_settings_newgame.game_creation.starting_year = Clamp(_settings_newgame.game_creation.starting_year + 1, MIN_YEAR, MAX_YEAR);
@@ -598,7 +647,7 @@
 static void ToolbarScenZoomIn(Window *w)
 {
 	if (DoZoomInOutWindow(ZOOM_IN, FindWindowById(WC_MAIN_WINDOW, 0))) {
-		w->HandleButtonClick(9);
+		w->HandleButtonClick(TBSE_ZOOMIN);
 		SndPlayFx(SND_15_BEEP);
 	}
 }
@@ -606,14 +655,14 @@
 static void ToolbarScenZoomOut(Window *w)
 {
 	if (DoZoomInOutWindow(ZOOM_OUT, FindWindowById(WC_MAIN_WINDOW, 0))) {
-		w->HandleButtonClick(10);
+		w->HandleButtonClick(TBSE_ZOOMOUT);
 		SndPlayFx(SND_15_BEEP);
 	}
 }
 
 static void ToolbarScenGenLand(Window *w)
 {
-	w->HandleButtonClick(11);
+	w->HandleButtonClick(TBSE_LANDGENERATE);
 	SndPlayFx(SND_15_BEEP);
 
 	ShowEditorTerraformToolbar();
@@ -622,35 +671,35 @@
 
 static void ToolbarScenGenTown(Window *w)
 {
-	w->HandleButtonClick(12);
+	w->HandleButtonClick(TBSE_TOWNGENERATE);
 	SndPlayFx(SND_15_BEEP);
 	ShowBuildTownWindow();
 }
 
 static void ToolbarScenGenIndustry(Window *w)
 {
-	w->HandleButtonClick(13);
+	w->HandleButtonClick(TBSE_INDUSTRYGENERATE);
 	SndPlayFx(SND_15_BEEP);
 	ShowBuildIndustryWindow();
 }
 
 static void ToolbarScenBuildRoad(Window *w)
 {
-	w->HandleButtonClick(14);
+	w->HandleButtonClick(TBSE_BUILDROAD);
 	SndPlayFx(SND_15_BEEP);
 	ShowBuildRoadScenToolbar();
 }
 
 static void ToolbarScenPlantTrees(Window *w)
 {
-	w->HandleButtonClick(15);
+	w->HandleButtonClick(TBSE_PLANTTREES);
 	SndPlayFx(SND_15_BEEP);
 	ShowBuildTreesToolbar();
 }
 
 static void ToolbarScenPlaceSign(Window *w)
 {
-	w->HandleButtonClick(16);
+	w->HandleButtonClick(TBSE_PLACESIGNS);
 	SndPlayFx(SND_15_BEEP);
 	SelectSignTool();
 }
@@ -666,16 +715,17 @@
 	/* There are 27 buttons plus some spacings if the space allows it */
 	uint button_width;
 	uint spacing;
-	if (w->width >= 27 * 22) {
+	if (w->width >= (int)w->widget_count * 22) {
 		button_width = 22;
-		spacing = w->width - (27 * button_width);
+		spacing = w->width - (w->widget_count * button_width);
 	} else {
-		button_width = w->width / 27;
+		button_width = w->width / w->widget_count;
 		spacing = 0;
 	}
+
 	uint extra_spacing_at[] = { 4, 8, 13, 17, 19, 24, 0 };
-
-	for (uint i = 0, x = 0, j = 0; i < 27; i++) {
+	uint i = 0;
+	for (uint x = 0, j = 0; i < w->widget_count; i++) {
 		if (extra_spacing_at[j] == i) {
 			j++;
 			uint add = spacing / (lengthof(extra_spacing_at) - j);
@@ -685,11 +735,11 @@
 
 		w->widget[i].type = WWT_IMGBTN;
 		w->widget[i].left = x;
-		x += (spacing != 0) ? button_width : (w->width - x) / (27 - i);
+		x += (spacing != 0) ? button_width : (w->width - x) / (w->widget_count - i);
 		w->widget[i].right = x - 1;
 	}
 
-	w->widget[27].type = WWT_EMPTY;
+	w->widget[i].type = WWT_EMPTY; // i now points to the last item
 	_toolbar_mode = TB_NORMAL;
 }
 
@@ -730,7 +780,7 @@
 	assert(max_icons >= 14 && max_icons <= 19);
 
 	/* first hide all icons */
-	for (uint i = 0; i < 27; i++) {
+	for (uint i = 0; i < w->widget_count; i++) {
 		w->widget[i].type = WWT_EMPTY;
 	}
 
@@ -782,8 +832,8 @@
 struct MainToolbarWindow : Window {
 	MainToolbarWindow(const WindowDesc *desc) : Window(desc)
 	{
-		this->SetWidgetDisabledState(0, _networking && !_network_server); // if not server, disable pause button
-		this->SetWidgetDisabledState(1, _networking); // if networking, disable fast-forward button
+		this->SetWidgetDisabledState(TBN_PAUSE, _networking && !_network_server); // if not server, disable pause button
+		this->SetWidgetDisabledState(TBN_FASTFORWARD, _networking); // if networking, disable fast-forward button
 
 		CLRBITS(this->flags4, WF_WHITE_BORDER_MASK);
 
@@ -801,12 +851,12 @@
 		/* If spectator, disable all construction buttons
 		* ie : Build road, rail, ships, airports and landscaping
 		* Since enabled state is the default, just disable when needed */
-		this->SetWidgetsDisabledState(_current_player == PLAYER_SPECTATOR, 19, 20, 21, 22, 23, WIDGET_LIST_END);
+		this->SetWidgetsDisabledState(_current_player == PLAYER_SPECTATOR, TBN_RAILS, TBN_ROADS, TBN_WATER, TBN_AIR, TBN_LANDSCAPE, WIDGET_LIST_END);
 		/* disable company list drop downs, if there are no companies */
-		this->SetWidgetsDisabledState(ActivePlayerCount() == 0, 7, 8, 13, 14, 15, 16, WIDGET_LIST_END);
+		this->SetWidgetsDisabledState(ActivePlayerCount() == TBN_PAUSE, TBN_STATIONS, TBN_FINANCES, TBN_TRAINS, TBN_ROADVEHS, TBN_SHIPS, TBN_AIRCRAFTS, WIDGET_LIST_END);
 
-		this->SetWidgetDisabledState(19, !CanBuildVehicleInfrastructure(VEH_TRAIN));
-		this->SetWidgetDisabledState(22, !CanBuildVehicleInfrastructure(VEH_AIRCRAFT));
+		this->SetWidgetDisabledState(TBN_RAILS, !CanBuildVehicleInfrastructure(VEH_TRAIN));
+		this->SetWidgetDisabledState(TBN_AIR, !CanBuildVehicleInfrastructure(VEH_AIRCRAFT));
 
 		this->DrawWidgets();
 	}
@@ -866,22 +916,16 @@
 		_place_proc(tile);
 	}
 
-	virtual void OnPlaceObjectAbort()
-	{
-		this->RaiseWidget(25);
-		this->SetDirty();
-	}
-
 	virtual void OnTick()
 	{
-		if (this->IsWidgetLowered(0) != !!_pause_game) {
-			this->ToggleWidgetLoweredState(0);
-			this->InvalidateWidget(0);
+		if (this->IsWidgetLowered(TBN_PAUSE) != !!_pause_game) {
+			this->ToggleWidgetLoweredState(TBN_PAUSE);
+			this->InvalidateWidget(TBN_PAUSE);
 		}
 
-		if (this->IsWidgetLowered(1) != !!_fast_forward) {
-			this->ToggleWidgetLoweredState(1);
-			this->InvalidateWidget(1);
+		if (this->IsWidgetLowered(TBN_FASTFORWARD) != !!_fast_forward) {
+			this->ToggleWidgetLoweredState(TBN_FASTFORWARD);
+			this->InvalidateWidget(TBN_FASTFORWARD);
 		}
 	}
 
@@ -896,7 +940,7 @@
 
 	virtual void OnTimeout()
 	{
-		for (uint i = 2; i < this->widget_count; i++) {
+		for (uint i = TBN_SETTINGS; i < this->widget_count; i++) {
 			if (this->IsWidgetLowered(i)) {
 				this->RaiseWidget(i);
 				this->InvalidateWidget(i);
@@ -906,7 +950,7 @@
 
 	virtual void OnInvalidateData(int data)
 	{
-		if (FindWindowById(WC_MAIN_WINDOW, 0) != NULL) HandleZoomMessage(this, FindWindowById(WC_MAIN_WINDOW, 0)->viewport, 17, 18);
+		if (FindWindowById(WC_MAIN_WINDOW, 0) != NULL) HandleZoomMessage(this, FindWindowById(WC_MAIN_WINDOW, 0)->viewport, TBN_ZOOMIN, TBN_ZOOMOUT);
 	}
 };
 
@@ -989,6 +1033,7 @@
 };
 
 struct ScenarioEditorToolbarWindow : Window {
+public:
 	ScenarioEditorToolbarWindow(const WindowDesc *desc) : Window(desc)
 	{
 		CLRBITS(this->flags4, WF_WHITE_BORDER_MASK);
@@ -1000,8 +1045,8 @@
 
 	virtual void OnPaint()
 	{
-		this->SetWidgetDisabledState(6, _settings_newgame.game_creation.starting_year <= MIN_YEAR);
-		this->SetWidgetDisabledState(7, _settings_newgame.game_creation.starting_year >= MAX_YEAR);
+		this->SetWidgetDisabledState(TBSE_DATEBACKWARD, _settings_newgame.game_creation.starting_year <= MIN_YEAR);
+		this->SetWidgetDisabledState(TBSE_DATEFORWARD, _settings_newgame.game_creation.starting_year >= MAX_YEAR);
 
 		/* Draw brown-red toolbar bg. */
 		GfxFillRect(0, 0, this->width - 1, this->height - 1, 0xB2);
@@ -1010,12 +1055,13 @@
 		this->DrawWidgets();
 
 		SetDParam(0, ConvertYMDToDate(_settings_newgame.game_creation.starting_year, 0, 1));
-		DrawStringCenteredTruncated(this->widget[6].right, this->widget[7].left, 6, STR_00AF, TC_FROMSTRING);
+		DrawStringCenteredTruncated(this->widget[TBSE_DATEBACKWARD].right, this->widget[TBSE_DATEFORWARD].left, 6, STR_00AF, TC_FROMSTRING);
 
 		/* We hide this panel when the toolbar space gets too small */
-		if (this->widget[4].left != this->widget[4].right) {
-			DrawStringCenteredTruncated(this->widget[4].left + 1, this->widget[4].right - 1,  1, STR_0221_OPENTTD, TC_FROMSTRING);
-			DrawStringCenteredTruncated(this->widget[4].left + 1, this->widget[4].right - 1, 11, STR_0222_SCENARIO_EDITOR, TC_FROMSTRING);
+		const Widget *panel = &this->widget[TBSE_SPACERPANEL];
+		if (panel->left != panel->right) {
+			DrawStringCenteredTruncated(panel->left + 1, panel->right - 1,  1, STR_0221_OPENTTD, TC_FROMSTRING);
+			DrawStringCenteredTruncated(panel->left + 1, panel->right - 1, 11, STR_0222_SCENARIO_EDITOR, TC_FROMSTRING);
 		}
 	}
 
@@ -1046,13 +1092,13 @@
 			case WKC_NUM_PLUS:
 			case WKC_EQUALS:
 			case WKC_SHIFT | WKC_EQUALS:
-			case WKC_SHIFT | WKC_F5: ToolbarZoomInClick(this); break;
+			case WKC_SHIFT | WKC_F5: ToolbarScenZoomIn(this); break;
 
 			/* those following are all fall through */
 			case WKC_NUM_MINUS:
 			case WKC_MINUS:
 			case WKC_SHIFT | WKC_MINUS:
-			case WKC_SHIFT | WKC_F6: ToolbarZoomOutClick(this); break;
+			case WKC_SHIFT | WKC_F6: ToolbarScenZoomOut(this); break;
 
 			case 'L': ShowEditorTerraformToolbar(); break;
 			case 'M': ShowSmallMap(); break;
@@ -1067,12 +1113,6 @@
 		_place_proc(tile);
 	}
 
-	virtual void OnPlaceObjectAbort()
-	{
-		this->RaiseWidget(25);
-		this->SetDirty();
-	}
-
 	virtual void OnResize(Point new_size, Point delta)
 	{
 		/* There are 15 buttons plus some spacings if the space allows it.
@@ -1093,8 +1133,7 @@
 		}
 		uint extra_spacing_at[] = { 3, 4, 7, 8, 10, 16, 0 };
 
-		/* Yes, it defines about 27 widgets for this toolbar */
-		for (uint i = 0, x = 0, j = 0, b = 0; i < 27; i++) {
+		for (uint i = 0, x = 0, j = 0, b = 0; i < this->widget_count; i++) {
 			switch (i) {
 				case 4:
 					this->widget[i].left = x;
@@ -1142,20 +1181,20 @@
 
 	virtual void OnTick()
 	{
-		if (this->IsWidgetLowered(0) != !!_pause_game) {
-			this->ToggleWidgetLoweredState(0);
+		if (this->IsWidgetLowered(TBSE_PAUSE) != !!_pause_game) {
+			this->ToggleWidgetLoweredState(TBSE_PAUSE);
 			this->SetDirty();
 		}
 
-		if (this->IsWidgetLowered(1) != !!_fast_forward) {
-			this->ToggleWidgetLoweredState(1);
+		if (this->IsWidgetLowered(TBSE_FASTFORWARD) != !!_fast_forward) {
+			this->ToggleWidgetLoweredState(TBSE_FASTFORWARD);
 			this->SetDirty();
 		}
 	}
 
 	virtual void OnInvalidateData(int data)
 	{
-		if (FindWindowById(WC_MAIN_WINDOW, 0) != NULL) HandleZoomMessage(this, FindWindowById(WC_MAIN_WINDOW, 0)->viewport, 17, 18);
+		if (FindWindowById(WC_MAIN_WINDOW, 0) != NULL) HandleZoomMessage(this, FindWindowById(WC_MAIN_WINDOW, 0)->viewport, TBSE_ZOOMIN, TBSE_ZOOMOUT);
 	}
 };
 
@@ -1409,7 +1448,7 @@
 	{
 		this->flags4 &= ~WF_WHITE_BORDER_MASK;
 		this->sel_index = (_local_player != PLAYER_SPECTATOR) ? _local_player : GetPlayerIndexFromMenu(0);
-		if (_networking && main_button == 9) {
+		if (_networking && main_button == TBN_PLAYERS) {
 			if (_local_player != PLAYER_SPECTATOR) {
 				this->sel_index++;
 			} else {
@@ -1433,7 +1472,7 @@
 		byte num = ActivePlayerCount();
 
 		/* Increase one to fit in PlayerList in the menu when in network */
-		if (_networking && this->main_button == 9) num++;
+		if (_networking && this->main_button == TBN_PLAYERS) num++;
 
 		if (this->item_count != num) {
 			this->item_count = num;
@@ -1457,7 +1496,7 @@
 		int gray = this->gray_items;
 
 		/* 9 = playerlist */
-		if (_networking && this->main_button == 9) {
+		if (_networking && this->main_button == TBN_PLAYERS) {
 			if (sel == 0) {
 				GfxFillRect(x, y, x + 238, y + 9, 0);
 			}
@@ -1496,7 +1535,7 @@
 			this->UpdatePlayerMenuHeight();
 			/* We have a new entry at the top of the list of menu 9 when networking
 				* so keep that in count */
-			if (_networking && this->main_button == 9) {
+			if (_networking && this->main_button == TBN_PLAYERS) {
 				if (index > 0) index = GetPlayerIndexFromMenu(index - 1) + 1;
 			} else {
 				index = GetPlayerIndexFromMenu(index);
@@ -1511,7 +1550,7 @@
 
 			/* We have a new entry at the top of the list of menu 9 when networking
 				* so keep that in count */
-			if (_networking && this->main_button == 9) {
+			if (_networking && this->main_button == TBN_PLAYERS) {
 				if (index > 0) index = GetPlayerIndexFromMenu(index - 1) + 1;
 			} else {
 				index = GetPlayerIndexFromMenu(index);
--- a/src/town_cmd.cpp	Tue Jun 17 10:32:49 2008 +0000
+++ b/src/town_cmd.cpp	Tue Jun 17 13:22:13 2008 +0000
@@ -1642,13 +1642,14 @@
  * @param random_bits required for newgrf houses
  * @pre house can be built here
  */
-static inline void ClearMakeHouseTile(TileIndex tile, TownID tid, byte counter, byte stage, HouseID type, byte random_bits)
+static inline void ClearMakeHouseTile(TileIndex tile, Town *t, byte counter, byte stage, HouseID type, byte random_bits)
 {
 	CommandCost cc = DoCommand(tile, 0, 0, DC_EXEC | DC_AUTO | DC_NO_WATER, CMD_LANDSCAPE_CLEAR);
 
 	assert(CmdSucceeded(cc));
 
-	MakeHouseTile(tile, tid, counter, stage, type, random_bits);
+	IncreaseBuildingCount(t, type);
+	MakeHouseTile(tile, t->index, counter, stage, type, random_bits);
 	if (GetHouseSpecs(type)->building_flags & BUILDING_IS_ANIMATED) AddAnimatedTile(tile);
 
 	MarkTileDirtyByTile(tile);
@@ -1665,14 +1666,14 @@
  * @param random_bits required for newgrf houses
  * @pre house can be built here
  */
-static void MakeTownHouse(TileIndex t, TownID tid, byte counter, byte stage, HouseID type, byte random_bits)
+static void MakeTownHouse(TileIndex t, Town *town, byte counter, byte stage, HouseID type, byte random_bits)
 {
 	BuildingFlags size = GetHouseSpecs(type)->building_flags;
 
-	ClearMakeHouseTile(t, tid, counter, stage, type, random_bits);
-	if (size & BUILDING_2_TILES_Y)   ClearMakeHouseTile(t + TileDiffXY(0, 1), tid, counter, stage, ++type, random_bits);
-	if (size & BUILDING_2_TILES_X)   ClearMakeHouseTile(t + TileDiffXY(1, 0), tid, counter, stage, ++type, random_bits);
-	if (size & BUILDING_HAS_4_TILES) ClearMakeHouseTile(t + TileDiffXY(1, 1), tid, counter, stage, ++type, random_bits);
+	ClearMakeHouseTile(t, town, counter, stage, type, random_bits);
+	if (size & BUILDING_2_TILES_Y)   ClearMakeHouseTile(t + TileDiffXY(0, 1), town, counter, stage, ++type, random_bits);
+	if (size & BUILDING_2_TILES_X)   ClearMakeHouseTile(t + TileDiffXY(1, 0), town, counter, stage, ++type, random_bits);
+	if (size & BUILDING_HAS_4_TILES) ClearMakeHouseTile(t + TileDiffXY(1, 1), town, counter, stage, ++type, random_bits);
 }
 
 
@@ -1929,11 +1930,6 @@
 			}
 
 			if ((hs->extra_flags & BUILDING_IS_HISTORICAL) && !_generating_world) continue;
-
-			if (HasBit(hs->callback_mask, CBM_HOUSE_ALLOW_CONSTRUCTION)) {
-				uint16 callback_res = GetHouseCallback(CBID_HOUSE_ALLOW_CONSTRUCTION, 0, 0, house, t, tile);
-				if (callback_res != CALLBACK_FAILED && GB(callback_res, 0, 8) == 0) continue;
-			}
 		}
 
 		if (_cur_year < hs->min_year || _cur_year > hs->max_year) continue;
@@ -1947,7 +1943,7 @@
 			SetBit(oneof, TOWN_HAS_STADIUM);
 		}
 
-		if (HASBITS(t->flags12 , oneof)) continue;
+		if (HASBITS(t->flags12, oneof)) continue;
 
 		/* Make sure there is no slope? */
 		bool noslope = (hs->building_flags & TILE_NOT_SLOPED) != 0;
@@ -1963,9 +1959,13 @@
 			/* 1x1 house checks are already done */
 		}
 
+		if (HasBit(hs->callback_mask, CBM_HOUSE_ALLOW_CONSTRUCTION)) {
+			uint16 callback_res = GetHouseCallback(CBID_HOUSE_ALLOW_CONSTRUCTION, 0, 0, house, t, tile);
+			if (callback_res != CALLBACK_FAILED && GB(callback_res, 0, 8) == 0) continue;
+		}
+
 		/* build the house */
 		t->num_houses++;
-		IncreaseBuildingCount(t, house);
 
 		/* Special houses that there can be only one of. */
 		t->flags12 |= oneof;
@@ -1986,7 +1986,7 @@
 			}
 		}
 
-		MakeTownHouse(tile, t->index, construction_counter, construction_stage, house, Random());
+		MakeTownHouse(tile, t, construction_counter, construction_stage, house, Random());
 
 		return true;
 	}
@@ -1995,9 +1995,10 @@
 }
 
 
-static void DoClearTownHouseHelper(TileIndex tile)
+static void DoClearTownHouseHelper(TileIndex tile, Town *t, HouseID house)
 {
 	assert(IsTileType(tile, MP_HOUSE));
+	DecreaseBuildingCount(t, house);
 	DoClearSquare(tile);
 	DeleteAnimatedTile(tile);
 }
@@ -2046,7 +2047,6 @@
 	}
 
 	t->num_houses--;
-	DecreaseBuildingCount(t, house);
 
 	/* Clear flags for houses that only may exist once/town. */
 	if (hs->building_flags & BUILDING_IS_CHURCH) {
@@ -2057,10 +2057,10 @@
 
 	/* Do the actual clearing of tiles */
 	uint eflags = hs->building_flags;
-	DoClearTownHouseHelper(tile);
-	if (eflags & BUILDING_2_TILES_X)   DoClearTownHouseHelper(tile + TileDiffXY(1, 0));
-	if (eflags & BUILDING_2_TILES_Y)   DoClearTownHouseHelper(tile + TileDiffXY(0, 1));
-	if (eflags & BUILDING_HAS_4_TILES) DoClearTownHouseHelper(tile + TileDiffXY(1, 1));
+	DoClearTownHouseHelper(tile, t, house);
+	if (eflags & BUILDING_2_TILES_Y)   DoClearTownHouseHelper(tile + TileDiffXY(0, 1), t, ++house);
+	if (eflags & BUILDING_2_TILES_X)   DoClearTownHouseHelper(tile + TileDiffXY(1, 0), t, ++house);
+	if (eflags & BUILDING_HAS_4_TILES) DoClearTownHouseHelper(tile + TileDiffXY(1, 1), t, ++house);
 }
 
 static bool IsUniqueTownName(const char *name)
--- a/src/town_gui.cpp	Tue Jun 17 10:32:49 2008 +0000
+++ b/src/town_gui.cpp	Tue Jun 17 13:22:13 2008 +0000
@@ -545,7 +545,7 @@
 		SetVScrollCount(this, this->towns.Length());
 
 		this->DrawWidgets();
-		this->DrawSortButtonState(this->towns.sort_type == 0 ? TDW_SORTNAME : TDW_SORTPOPULATION, this->towns.IsDescSortOrder() ? SBS_DOWN : SBS_UP);
+		this->DrawSortButtonState(this->towns.SortType() == 0 ? TDW_SORTNAME : TDW_SORTPOPULATION, this->towns.IsDescSortOrder() ? SBS_DOWN : SBS_UP);
 
 		{
 			int n = 0;
--- a/src/town_map.h	Tue Jun 17 10:32:49 2008 +0000
+++ b/src/town_map.h	Tue Jun 17 13:22:13 2008 +0000
@@ -265,7 +265,7 @@
 }
 
 /**
- * Set the year that this house was constructed (between 1920 and 2175).
+ * Set the year that this house was constructed.
  * @param t the tile of this house
  * @param year the year to set
  * @pre IsTileType(t, MP_HOUSE) && IsHouseCompleted(t)
@@ -273,11 +273,11 @@
 static inline void SetHouseConstructionYear(TileIndex t, Year year)
 {
 	assert(IsTileType(t, MP_HOUSE) && IsHouseCompleted(t));
-	_m[t].m5 = Clamp(year - ORIGINAL_BASE_YEAR, 0, 0xFF);
+	_m[t].m5 = Clamp(year - GetHouseSpecs(GetHouseType(t))->min_year, 0, 0xFF);
 }
 
 /**
- * Get the year that this house was constructed (between 1920 and 2175).
+ * Get the year that this house was constructed.
  * @param t the tile of this house
  * @pre IsTileType(t, MP_HOUSE)
  * @return year
@@ -285,7 +285,7 @@
 static inline Year GetHouseConstructionYear(TileIndex t)
 {
 	assert(IsTileType(t, MP_HOUSE));
-	return IsHouseCompleted(t) ? _m[t].m5 + ORIGINAL_BASE_YEAR : 0;
+	return IsHouseCompleted(t) ? _m[t].m5 + GetHouseSpecs(GetHouseType(t))->min_year : 0;
 }
 
 /**
--- a/src/town_type.h	Tue Jun 17 10:32:49 2008 +0000
+++ b/src/town_type.h	Tue Jun 17 13:22:13 2008 +0000
@@ -51,9 +51,6 @@
 	RATING_TUNNEL_BRIDGE_DOWN_STEP = -250,
 	RATING_TUNNEL_BRIDGE_MINIMUM   = 0,
 
-	RATING_INDUSTRY_DOWN_STEP = -1500,
-	RATING_INDUSTRY_MINIMUM   = RATING_MINIMUM,
-
 	RATING_ROAD_DOWN_STEP_INNER = -50, ///< removing a roadpiece in the middle
 	RATING_ROAD_DOWN_STEP_EDGE  = -18, ///< removing a roadpiece at the edge
 	RATING_ROAD_MINIMUM   = -100,
--- a/src/train_cmd.cpp	Tue Jun 17 10:32:49 2008 +0000
+++ b/src/train_cmd.cpp	Tue Jun 17 13:22:13 2008 +0000
@@ -211,6 +211,8 @@
 		u->u.rail.first_engine = v == u ? INVALID_ENGINE : first_engine;
 		u->u.rail.railtype = rvi_u->railtype;
 
+		if (IsTrainEngine(u)) first_engine = u->engine_type;
+
 		/* Set user defined data to its default value */
 		u->u.rail.user_def_data = rvi_u->user_def_data;
 	}
@@ -225,8 +227,6 @@
 
 		if (!HasBit(EngInfo(u->engine_type)->misc_flags, EF_RAIL_TILTS)) train_can_tilt = false;
 
-		if (IsTrainEngine(u)) first_engine = u->engine_type;
-
 		/* Cache wagon override sprite group. NULL is returned if there is none */
 		u->u.rail.cached_override = GetWagonOverrideSpriteSet(u->engine_type, u->cargo_type, u->u.rail.first_engine);
 
@@ -549,7 +549,7 @@
 		if (!IsCompatibleRail(rvi->railtype, GetRailType(tile))) return CMD_ERROR;
 
 		/* Allow for the wagon and the articulated parts, plus one to "terminate" the list. */
-		Vehicle **vl = (Vehicle**)alloca(sizeof(*vl) * (num_vehicles + 1));
+		Vehicle **vl = AllocaM(Vehicle*, num_vehicles + 1);
 		memset(vl, 0, sizeof(*vl) * (num_vehicles + 1));
 
 		if (!Vehicle::AllocateList(vl, num_vehicles))
@@ -716,7 +716,7 @@
 		if (!HasPowerOnRail(rvi->railtype, GetRailType(tile))) return CMD_ERROR;
 
 		/* Allow for the dual-heads and the articulated parts, plus one to "terminate" the list. */
-		Vehicle **vl = (Vehicle**)alloca(sizeof(*vl) * (num_vehicles + 1));
+		Vehicle **vl = AllocaM(Vehicle*, num_vehicles + 1);
 		memset(vl, 0, sizeof(*vl) * (num_vehicles + 1));
 
 		if (!Vehicle::AllocateList(vl, num_vehicles)) {
--- a/src/tunnelbridge_cmd.cpp	Tue Jun 17 10:32:49 2008 +0000
+++ b/src/tunnelbridge_cmd.cpp	Tue Jun 17 13:22:13 2008 +0000
@@ -227,9 +227,11 @@
 			if (!ValParamRailtype(railtype)) return CMD_ERROR;
 			break;
 
+		case TRANSPORT_WATER:
+			break;
+
 		default:
-			/* For now, only TRANSPORT_RAIL and TRANSPORT_ROAD are allowed.
-			 * But let not this stops us for preparing the future */
+			/* Airports don't have tunnels. */
 			return CMD_ERROR;
 	}
 
@@ -250,9 +252,11 @@
 		return_cmd_error(STR_500A_START_AND_END_MUST_BE_IN);
 	}
 
-	/* set and test bridge length, availability */
 	bridge_len = sx + sy - x - y - 1;
-	if (!CheckBridge_Stuff(bridge_type, bridge_len)) return_cmd_error(STR_5015_CAN_T_BUILD_BRIDGE_HERE);
+	if (transport_type != TRANSPORT_WATER) {
+		/* set and test bridge length, availability */
+		if (!CheckBridge_Stuff(bridge_type, bridge_len)) return_cmd_error(STR_5015_CAN_T_BUILD_BRIDGE_HERE);
+	}
 
 	/* retrieve landscape height and ensure it's on land */
 	tile_start = TileXY(x, y);
@@ -311,7 +315,7 @@
 	} else {
 		/* Build a new bridge. */
 
-		bool allow_on_slopes = (!_is_old_ai_player && _settings_game.construction.build_on_slopes);
+		bool allow_on_slopes = (!_is_old_ai_player && _settings_game.construction.build_on_slopes && transport_type != TRANSPORT_WATER);
 
 		/* Try and clear the start landscape */
 		ret = DoCommand(tile_start, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
@@ -331,6 +335,8 @@
 		if (CmdFailed(terraform_cost_south) || (terraform_cost_south.GetCost() != 0 && !allow_on_slopes))
 			return_cmd_error(STR_1000_LAND_SLOPED_IN_WRONG_DIRECTION);
 		cost.AddCost(terraform_cost_south);
+
+		if (transport_type == TRANSPORT_WATER && (tileh_start == SLOPE_FLAT || tileh_end == SLOPE_FLAT)) return_cmd_error(STR_1000_LAND_SLOPED_IN_WRONG_DIRECTION);
 	}
 
 	if (!replace_bridge) {
@@ -368,6 +374,11 @@
 				MakeRoadBridgeRamp(tile_end,   owner, bridge_type, ReverseDiagDir(dir), roadtypes);
 				break;
 
+			case TRANSPORT_WATER:
+				MakeAqueductBridgeRamp(tile_start, owner, dir);
+				MakeAqueductBridgeRamp(tile_end,   owner, ReverseDiagDir(dir));
+				break;
+
 			default:
 				NOT_REACHED();
 				break;
@@ -445,6 +456,9 @@
 			bridge_len = CalcBridgeLenCostFactor(bridge_len);
 
 		cost.AddCost((int64)bridge_len * _price.build_bridge * GetBridgeSpec(bridge_type)->price >> 8);
+
+		/* Aqueducts are a little more expensive. */
+		if (transport_type == TRANSPORT_WATER) cost.AddCost((int64)bridge_len * _price.clear_water);
 	}
 
 	return cost;
@@ -724,7 +738,7 @@
  * @param y Sprite Y position of front pillar.
  * @param z_bridge Absolute height of bridge bottom.
  */
-static void DrawBridgePillars(const PalSpriteID *psid, const TileInfo* ti, Axis axis, BridgeType type, int x, int y, int z_bridge)
+static void DrawBridgePillars(const PalSpriteID *psid, const TileInfo* ti, Axis axis, bool drawfarpillar, int x, int y, int z_bridge)
 {
 	/* Do not draw bridge pillars if they are invisible */
 	if (IsInvisibilitySet(TO_BRIDGES)) return;
@@ -732,8 +746,6 @@
 	SpriteID image = psid->sprite;
 
 	if (image != 0) {
-		bool drawfarpillar = !HasBit(GetBridgeSpec(type)->flags, 0);
-
 		/* "side" specifies the side the pillars stand on.
 		 * The length of the pillars is then set to the height of the bridge over the corners of this edge.
 		 *
@@ -926,7 +938,11 @@
 		if (ti->tileh == SLOPE_FLAT) base_offset += 4; // sloped bridge head
 
 		/* Table number 6 always refers to the bridge heads for any bridge type */
-		psid = &GetBridgeSpriteTable(GetBridgeType(ti->tile), 6)[base_offset];
+		if (transport_type != TRANSPORT_WATER) {
+			psid = &GetBridgeSpriteTable(GetBridgeType(ti->tile), 6)[base_offset];
+		} else {
+			psid = _aqueduct_sprites + base_offset;
+		}
 
 		if (!ice) {
 			DrawClearLandTile(ti, 3);
@@ -1023,44 +1039,43 @@
 	/* Z position of the bridge sprites relative to bridge height (downwards) */
 	static const int BRIDGE_Z_START = 3;
 
-	const PalSpriteID* psid;
-	uint base_offset;
-	TileIndex rampnorth;
-	TileIndex rampsouth;
-	TransportType transport_type;
-	Axis axis;
-	uint piece;
-	BridgeType type;
-	int x;
-	int y;
-	uint z;
-
 	if (!IsBridgeAbove(ti->tile)) return;
 
-	rampnorth = GetNorthernBridgeEnd(ti->tile);
-	rampsouth = GetSouthernBridgeEnd(ti->tile);
-	transport_type = GetTunnelBridgeTransportType(rampsouth);
+	TileIndex rampnorth = GetNorthernBridgeEnd(ti->tile);
+	TileIndex rampsouth = GetSouthernBridgeEnd(ti->tile);
+	TransportType transport_type = GetTunnelBridgeTransportType(rampsouth);
 
-	axis = GetBridgeAxis(ti->tile);
-	piece = CalcBridgePiece(
+	Axis axis = GetBridgeAxis(ti->tile);
+	uint piece = CalcBridgePiece(
 		GetTunnelBridgeLength(ti->tile, rampnorth) + 1,
 		GetTunnelBridgeLength(ti->tile, rampsouth) + 1
 	);
-	type = GetBridgeType(rampsouth);
 
-	if (transport_type == TRANSPORT_RAIL) {
-		base_offset = GetRailTypeInfo(GetRailType(rampsouth))->bridge_offset;
+	const PalSpriteID *psid;
+	bool drawfarpillar;
+	if (transport_type != TRANSPORT_WATER) {
+		BridgeType type =  GetBridgeType(rampsouth);
+		drawfarpillar = !HasBit(GetBridgeSpec(type)->flags, 0);
+
+		uint base_offset;
+		if (transport_type == TRANSPORT_RAIL) {
+			base_offset = GetRailTypeInfo(GetRailType(rampsouth))->bridge_offset;
+		} else {
+			base_offset = 8;
+		}
+
+		psid = base_offset + GetBridgeSpriteTable(type, piece);
 	} else {
-		base_offset = 8;
+		drawfarpillar = true;
+		psid = _aqueduct_sprites;
 	}
 
-	psid = base_offset + GetBridgeSpriteTable(type, piece);
 	if (axis != AXIS_X) psid += 4;
 
-	x = ti->x;
-	y = ti->y;
+	int x = ti->x;
+	int y = ti->y;
 	uint bridge_z = GetBridgeHeight(rampsouth);
-	z = bridge_z - BRIDGE_Z_START;
+	uint z = bridge_z - BRIDGE_Z_START;
 
 	/* Add a bounding box, that separates the bridge from things below it. */
 	AddSortableSpriteToDraw(SPR_EMPTY_BOUNDING_BOX, PAL_NONE, x, y, 16, 16, 1, bridge_z - TILE_HEIGHT + BB_Z_SEPARATOR);
@@ -1125,7 +1140,7 @@
 		}
 	} else if (_settings_client.gui.bridge_pillars) {
 		/* draw pillars below for high bridges */
-		DrawBridgePillars(psid, ti, axis, type, x, y, z);
+		DrawBridgePillars(psid, ti, axis, drawfarpillar, x, y, z);
 	}
 }
 
@@ -1182,11 +1197,12 @@
 
 static void GetTileDesc_TunnelBridge(TileIndex tile, TileDesc *td)
 {
+	TransportType tt = GetTunnelBridgeTransportType(tile);
+
 	if (IsTunnel(tile)) {
-		td->str = (GetTunnelBridgeTransportType(tile) == TRANSPORT_RAIL) ?
-			STR_5017_RAILROAD_TUNNEL : STR_5018_ROAD_TUNNEL;
-	} else { //so it must be a bridge
-		td->str = GetBridgeSpec(GetBridgeType(tile))->transport_name[GetTunnelBridgeTransportType(tile)];
+		td->str = (tt == TRANSPORT_RAIL) ? STR_5017_RAILROAD_TUNNEL : STR_5018_ROAD_TUNNEL;
+	} else { // IsBridge(tile)
+		td->str = (tt == TRANSPORT_WATER) ? STR_AQUEDUCT : GetBridgeSpec(GetBridgeType(tile))->transport_name[tt];
 	}
 	td->owner[0] = GetTileOwner(tile);
 }
@@ -1246,9 +1262,9 @@
 		if (CmdFailed(DoCommand(tile, 0, 0, DC_EXEC | DC_BANKRUPT, CMD_LANDSCAPE_CLEAR))) {
 			/* When clearing the bridge/tunnel failed there are still vehicles on/in
 			 * the bridge/tunnel. As all *our* vehicles are already removed, they
-			 * must be of another owner. Therefor this must be a road bridge/tunnel.
+			 * must be of another owner. Therefore this can't be rail tunnel/bridge.
 			 * In that case we can safely reassign the ownership to OWNER_NONE. */
-			assert(GetTunnelBridgeTransportType(tile) == TRANSPORT_ROAD);
+			assert(GetTunnelBridgeTransportType(tile) != TRANSPORT_RAIL);
 			SetTileOwner(tile, OWNER_NONE);
 		}
 	}
@@ -1342,7 +1358,7 @@
 		}
 	} else { // IsBridge(tile)
 
-		if (v->IsPrimaryVehicle()) {
+		if (v->IsPrimaryVehicle() && v->type != VEH_SHIP) {
 			/* modify speed of vehicle */
 			uint16 spd = GetBridgeSpec(GetBridgeType(tile))->speed;
 
@@ -1358,29 +1374,51 @@
 				case DIAGDIR_SW: if ((x & 0xF) != TILE_SIZE - 1) return VETSB_CONTINUE; break;
 				case DIAGDIR_NW: if ((y & 0xF) != 0)             return VETSB_CONTINUE; break;
 			}
-			if (v->type == VEH_TRAIN) {
-				v->u.rail.track = TRACK_BIT_WORMHOLE;
-				ClrBit(v->u.rail.flags, VRF_GOINGUP);
-				ClrBit(v->u.rail.flags, VRF_GOINGDOWN);
-			} else {
-				v->u.road.state = RVSB_WORMHOLE;
+			switch (v->type) {
+				case VEH_TRAIN:
+					v->u.rail.track = TRACK_BIT_WORMHOLE;
+					ClrBit(v->u.rail.flags, VRF_GOINGUP);
+					ClrBit(v->u.rail.flags, VRF_GOINGDOWN);
+					break;
+
+				case VEH_ROAD:
+					v->u.road.state = RVSB_WORMHOLE;
+					break;
+
+				case VEH_SHIP:
+					v->u.ship.state = TRACK_BIT_WORMHOLE;
+					break;
+
+				default: NOT_REACHED();
 			}
 			return VETSB_ENTERED_WORMHOLE;
 		} else if (DirToDiagDir(v->direction) == ReverseDiagDir(dir)) {
 			v->tile = tile;
-			if (v->type == VEH_TRAIN) {
-				if (v->u.rail.track == TRACK_BIT_WORMHOLE) {
-					v->u.rail.track = (DiagDirToAxis(dir) == AXIS_X ? TRACK_BIT_X : TRACK_BIT_Y);
-					return VETSB_ENTERED_WORMHOLE;
-				}
-			} else {
-				if (v->u.road.state == RVSB_WORMHOLE) {
-					v->u.road.state = _road_exit_tunnel_state[dir];
-					v->u.road.frame = 0;
-					return VETSB_ENTERED_WORMHOLE;
-				}
+			switch (v->type) {
+				case VEH_TRAIN:
+					if (v->u.rail.track == TRACK_BIT_WORMHOLE) {
+						v->u.rail.track = (DiagDirToAxis(dir) == AXIS_X ? TRACK_BIT_X : TRACK_BIT_Y);
+						return VETSB_ENTERED_WORMHOLE;
+					}
+					break;
+
+				case VEH_ROAD:
+					if (v->u.road.state == RVSB_WORMHOLE) {
+						v->u.road.state = _road_exit_tunnel_state[dir];
+						v->u.road.frame = 0;
+						return VETSB_ENTERED_WORMHOLE;
+					}
+					break;
+
+				case VEH_SHIP:
+					if (v->u.ship.state == TRACK_BIT_WORMHOLE) {
+						v->u.ship.state = (DiagDirToAxis(dir) == AXIS_X ? TRACK_BIT_X : TRACK_BIT_Y);
+						return VETSB_ENTERED_WORMHOLE;
+					}
+					break;
+
+				default: NOT_REACHED();
 			}
-			return VETSB_CONTINUE;
 		}
 	}
 	return VETSB_CONTINUE;
@@ -1388,7 +1426,7 @@
 
 static CommandCost TerraformTile_TunnelBridge(TileIndex tile, uint32 flags, uint z_new, Slope tileh_new)
 {
-	if (_settings_game.construction.build_on_slopes && AutoslopeEnabled() && IsBridge(tile)) {
+	if (_settings_game.construction.build_on_slopes && AutoslopeEnabled() && IsBridge(tile) && GetTunnelBridgeTransportType(tile) != TRANSPORT_WATER) {
 		DiagDirection direction = GetTunnelBridgeDirection(tile);
 		Axis axis = DiagDirToAxis(direction);
 		CommandCost res;
--- a/src/vehicle.cpp	Tue Jun 17 10:32:49 2008 +0000
+++ b/src/vehicle.cpp	Tue Jun 17 13:22:13 2008 +0000
@@ -206,7 +206,7 @@
 /** Procedure called for every vehicle found in tunnel/bridge in the hash map */
 static void *GetVehicleTunnelBridgeProc(Vehicle *v, void *data)
 {
-	if (v->type != VEH_TRAIN && v->type != VEH_ROAD) return NULL;
+	if (v->type != VEH_TRAIN && v->type != VEH_ROAD && v->type != VEH_SHIP) return NULL;
 
 	_error_message = VehicleInTheWayErrMsg(v);
 	return v;
--- a/src/vehicle_gui.cpp	Tue Jun 17 10:32:49 2008 +0000
+++ b/src/vehicle_gui.cpp	Tue Jun 17 13:22:13 2008 +0000
@@ -31,6 +31,8 @@
 #include "vehicle_func.h"
 #include "autoreplace_gui.h"
 #include "core/alloc_func.hpp"
+#include "core/mem_func.hpp"
+#include "core/sort_func.hpp"
 #include "string_func.h"
 #include "settings_type.h"
 #include "widgets/dropdown_func.h"
@@ -42,9 +44,8 @@
 #include "table/strings.h"
 
 Sorting _sorting;
-static bool   _internal_sort_order;     // descending/ascending
 
-typedef int CDECL VehicleSortListingTypeFunction(const void*, const void*);
+typedef int CDECL VehicleSortListingTypeFunction(const Vehicle* const *, const Vehicle* const *);
 
 static VehicleSortListingTypeFunction VehicleNumberSorter;
 static VehicleSortListingTypeFunction VehicleNameSorter;
@@ -89,40 +90,30 @@
 
 void BuildVehicleList(VehicleListBase *vl, PlayerID owner, uint16 index, uint16 window_type)
 {
-	if (!(vl->vehicles.flags & VL_REBUILD)) return;
+	if (!vl->vehicles.NeedRebuild()) return;
 
 	DEBUG(misc, 3, "Building vehicle list for player %d at station %d", owner, index);
 
 	GenerateVehicleSortList(&vl->vehicles, vl->vehicle_type, owner, index, window_type);
 
-	vl->vehicles.flags &= ~VL_REBUILD;
-	vl->vehicles.flags |= VL_RESORT;
+	vl->vehicles.RebuildDone();
 }
 
 /* cached values for VehicleNameSorter to spare many GetString() calls */
 static const Vehicle *_last_vehicle[2] = { NULL, NULL };
-static char           _last_name[2][64] = { "", "" };
 
 void SortVehicleList(VehicleListBase *vl)
 {
-	if (!(vl->vehicles.flags & VL_RESORT)) return;
+	if (vl->vehicles.Sort(_vehicle_sorter[vl->vehicles.SortType()])) return;
 
 	/* invalidate cached values for name sorter - vehicle names could change */
 	_last_vehicle[0] = _last_vehicle[1] = NULL;
-
-	_internal_sort_order = (vl->vehicles.flags & VL_DESC) != 0;
-	qsort((void*)vl->vehicles.Begin(), vl->vehicles.Length(), sizeof(*vl->vehicles.Begin()),
-		_vehicle_sorter[vl->vehicles.sort_type]);
-
-	vl->vehicles.resort_timer = DAY_TICKS * PERIODIC_RESORT_DAYS;
-	vl->vehicles.flags &= ~VL_RESORT;
 }
 
 void DepotSortList(VehicleList *list)
 {
-	_internal_sort_order = 0;
 	if (list->Length() < 2) return;
-	qsort((void*)list->Begin(), list->Length(), sizeof(*list->Begin()), _vehicle_sorter[0]);
+	QSortT(list->Begin(), list->Length(), _vehicle_sorter[0]);
 }
 
 /** draw the vehicle profit button in the vehicle list window. */
@@ -507,183 +498,136 @@
 }
 
 
-/* if the sorting criteria had the same value, sort vehicle by unitnumber */
-#define VEHICLEUNITNUMBERSORTER(r, a, b) {if (r == 0) {r = a->unitnumber - b->unitnumber;}}
-
-static int CDECL VehicleNumberSorter(const void *a, const void *b)
-{
-	const Vehicle* va = *(const Vehicle**)a;
-	const Vehicle* vb = *(const Vehicle**)b;
-	int r = va->unitnumber - vb->unitnumber;
-
-	return (_internal_sort_order & 1) ? -r : r;
-}
-
-static int CDECL VehicleNameSorter(const void *a, const void *b)
+/** Sort vehicles by their number */
+static int CDECL VehicleNumberSorter(const Vehicle* const *a, const Vehicle* const *b)
 {
-	const Vehicle* va = *(const Vehicle**)a;
-	const Vehicle* vb = *(const Vehicle**)b;
-	int r;
-
-	if (va != _last_vehicle[0]) {
-		_last_vehicle[0] = va;
-		SetDParam(0, va->index);
-		GetString(_last_name[0], STR_VEHICLE_NAME, lastof(_last_name[0]));
-	}
-
-	if (vb != _last_vehicle[1]) {
-		_last_vehicle[1] = vb;
-		SetDParam(0, vb->index);
-		GetString(_last_name[1], STR_VEHICLE_NAME, lastof(_last_name[1]));
-	}
-
-	r = strcmp(_last_name[0], _last_name[1]); // sort by name
-
-	VEHICLEUNITNUMBERSORTER(r, va, vb);
-
-	return (_internal_sort_order & 1) ? -r : r;
+	return (*a)->unitnumber - (*b)->unitnumber;
 }
 
-static int CDECL VehicleAgeSorter(const void *a, const void *b)
+/** Sort vehicles by their name */
+static int CDECL VehicleNameSorter(const Vehicle* const *a, const Vehicle* const *b)
 {
-	const Vehicle* va = *(const Vehicle**)a;
-	const Vehicle* vb = *(const Vehicle**)b;
-	int r = va->age - vb->age;
-
-	VEHICLEUNITNUMBERSORTER(r, va, vb);
+	static char last_name[2][64];
 
-	return (_internal_sort_order & 1) ? -r : r;
-}
+	if (*a != _last_vehicle[0]) {
+		_last_vehicle[0] = *a;
+		SetDParam(0, (*a)->index);
+		GetString(last_name[0], STR_VEHICLE_NAME, lastof(last_name[0]));
+	}
 
-static int CDECL VehicleProfitThisYearSorter(const void *a, const void *b)
-{
-	const Vehicle* va = *(const Vehicle**)a;
-	const Vehicle* vb = *(const Vehicle**)b;
-	int r = ClampToI32(va->GetDisplayProfitThisYear() - vb->GetDisplayProfitThisYear());
+	if (*b != _last_vehicle[1]) {
+		_last_vehicle[1] = *b;
+		SetDParam(0, (*b)->index);
+		GetString(last_name[1], STR_VEHICLE_NAME, lastof(last_name[1]));
+	}
 
-	VEHICLEUNITNUMBERSORTER(r, va, vb);
-
-	return (_internal_sort_order & 1) ? -r : r;
+	int r = strcmp(last_name[0], last_name[1]);
+	return (r != 0) ? r : VehicleNumberSorter(a, b);
 }
 
-static int CDECL VehicleProfitLastYearSorter(const void *a, const void *b)
+/** Sort vehicles by their age */
+static int CDECL VehicleAgeSorter(const Vehicle* const *a, const Vehicle* const *b)
 {
-	const Vehicle* va = *(const Vehicle**)a;
-	const Vehicle* vb = *(const Vehicle**)b;
-	int r = ClampToI32(va->GetDisplayProfitLastYear() - vb->GetDisplayProfitLastYear());
-
-	VEHICLEUNITNUMBERSORTER(r, va, vb);
-
-	return (_internal_sort_order & 1) ? -r : r;
+	int r = (*a)->age - (*b)->age;
+	return (r != 0) ? r : VehicleNumberSorter(a, b);
 }
 
-static int CDECL VehicleCargoSorter(const void *a, const void *b)
+/** Sort vehicles by this year profit */
+static int CDECL VehicleProfitThisYearSorter(const Vehicle* const *a, const Vehicle* const *b)
 {
-	const Vehicle* va = *(const Vehicle**)a;
-	const Vehicle* vb = *(const Vehicle**)b;
-	const Vehicle* v;
-	AcceptedCargo cargoa;
-	AcceptedCargo cargob;
+	int r = ClampToI32((*a)->GetDisplayProfitThisYear() - (*b)->GetDisplayProfitThisYear());
+	return (r != 0) ? r : VehicleNumberSorter(a, b);
+}
+
+/** Sort vehicles by last year profit */
+static int CDECL VehicleProfitLastYearSorter(const Vehicle* const *a, const Vehicle* const *b)
+{
+	int r = ClampToI32((*a)->GetDisplayProfitLastYear() - (*b)->GetDisplayProfitLastYear());
+	return (r != 0) ? r : VehicleNumberSorter(a, b);
+}
+
+/** Sort vehicles by their cargo */
+static int CDECL VehicleCargoSorter(const Vehicle* const *a, const Vehicle* const *b)
+{
+	const Vehicle *v;
+	AcceptedCargo diff;
+	MemSetT(diff, 0);
+
+	/* Append the cargo of the connected weagons */
+	for (v = *a; v != NULL; v = v->Next()) diff[v->cargo_type] += v->cargo_cap;
+	for (v = *b; v != NULL; v = v->Next()) diff[v->cargo_type] -= v->cargo_cap;
+
 	int r = 0;
-
-	memset(cargoa, 0, sizeof(cargoa));
-	memset(cargob, 0, sizeof(cargob));
-	for (v = va; v != NULL; v = v->Next()) cargoa[v->cargo_type] += v->cargo_cap;
-	for (v = vb; v != NULL; v = v->Next()) cargob[v->cargo_type] += v->cargo_cap;
-
 	for (CargoID i = 0; i < NUM_CARGO; i++) {
-		r = cargoa[i] - cargob[i];
+		r = diff[i];
 		if (r != 0) break;
 	}
 
-	VEHICLEUNITNUMBERSORTER(r, va, vb);
-
-	return (_internal_sort_order & 1) ? -r : r;
-}
-
-static int CDECL VehicleReliabilitySorter(const void *a, const void *b)
-{
-	const Vehicle* va = *(const Vehicle**)a;
-	const Vehicle* vb = *(const Vehicle**)b;
-	int r = va->reliability - vb->reliability;
-
-	VEHICLEUNITNUMBERSORTER(r, va, vb);
-
-	return (_internal_sort_order & 1) ? -r : r;
-}
-
-static int CDECL VehicleMaxSpeedSorter(const void *a, const void *b)
-{
-	const Vehicle* va = *(const Vehicle**)a;
-	const Vehicle* vb = *(const Vehicle**)b;
-	int r;
-
-	if (va->type == VEH_TRAIN && vb->type == VEH_TRAIN) {
-		r = va->u.rail.cached_max_speed - vb->u.rail.cached_max_speed;
-	} else {
-		r = va->max_speed - vb->max_speed;
-	}
-
-	VEHICLEUNITNUMBERSORTER(r, va, vb);
-
-	return (_internal_sort_order & 1) ? -r : r;
+	return (r != 0) ? r : VehicleNumberSorter(a, b);
 }
 
-static int CDECL VehicleModelSorter(const void *a, const void *b)
+/** Sort vehicles by their reliability */
+static int CDECL VehicleReliabilitySorter(const Vehicle* const *a, const Vehicle* const *b)
 {
-	const Vehicle* va = *(const Vehicle**)a;
-	const Vehicle* vb = *(const Vehicle**)b;
-	int r = va->engine_type - vb->engine_type;
-
-	VEHICLEUNITNUMBERSORTER(r, va, vb);
-
-	return (_internal_sort_order & 1) ? -r : r;
+	int r = (*a)->reliability - (*b)->reliability;
+	return (r != 0) ? r : VehicleNumberSorter(a, b);
 }
 
-static int CDECL VehicleValueSorter(const void *a, const void *b)
+/** Sort vehicles by their max speed */
+static int CDECL VehicleMaxSpeedSorter(const Vehicle* const *a, const Vehicle* const *b)
 {
-	const Vehicle* va = *(const Vehicle**)a;
-	const Vehicle* vb = *(const Vehicle**)b;
-	const Vehicle *u;
-	Money valuea = 0, valueb = 0;
-
-	for (u = va; u != NULL; u = u->Next()) valuea += u->value;
-	for (u = vb; u != NULL; u = u->Next()) valueb += u->value;
-
-	int r = ClampToI32(valuea - valueb);
-
-	VEHICLEUNITNUMBERSORTER(r, va, vb);
-
-	return (_internal_sort_order & 1) ? -r : r;
+	int r = 0;
+	if ((*a)->type == VEH_TRAIN && (*b)->type == VEH_TRAIN) {
+		r = (*a)->u.rail.cached_max_speed - (*b)->u.rail.cached_max_speed;
+	} else {
+		r = (*a)->max_speed - (*b)->max_speed;
+	}
+	return (r != 0) ? r : VehicleNumberSorter(a, b);
 }
 
-static int CDECL VehicleLengthSorter(const void *a, const void *b)
+/** Sort vehicles by model */
+static int CDECL VehicleModelSorter(const Vehicle* const *a, const Vehicle* const *b)
 {
-	const Vehicle *va = *(const Vehicle**)a;
-	const Vehicle *vb = *(const Vehicle**)b;
+	int r = (*a)->engine_type - (*b)->engine_type;
+	return (r != 0) ? r : VehicleNumberSorter(a, b);
+}
+
+/** Sort vehciles by their value */
+static int CDECL VehicleValueSorter(const Vehicle* const *a, const Vehicle* const *b)
+{
+	const Vehicle *u;
+	Money diff = 0;
+
+	for (u = *a; u != NULL; u = u->Next()) diff += u->value;
+	for (u = *b; u != NULL; u = u->Next()) diff -= u->value;
+
+	int r = ClampToI32(diff);
+	return (r != 0) ? r : VehicleNumberSorter(a, b);
+}
+
+/** Sort vehicles by their length */
+static int CDECL VehicleLengthSorter(const Vehicle* const *a, const Vehicle* const *b)
+{
 	int r = 0;
-
-	switch (va->type) {
+	switch ((*a)->type) {
 		case VEH_TRAIN:
-			r = va->u.rail.cached_total_length - vb->u.rail.cached_total_length;
+			r = (*a)->u.rail.cached_total_length - (*b)->u.rail.cached_total_length;
 			break;
 
-		case VEH_ROAD:
-			for (const Vehicle *u = va; u != NULL; u = u->Next()) r += u->u.road.cached_veh_length;
-			for (const Vehicle *u = vb; u != NULL; u = u->Next()) r -= u->u.road.cached_veh_length;
-			break;
+		case VEH_ROAD: {
+			const Vehicle *u;
+			for (u = *a; u != NULL; u = u->Next()) r += u->u.road.cached_veh_length;
+			for (u = *b; u != NULL; u = u->Next()) r -= u->u.road.cached_veh_length;
+		} break;
 
 		default: NOT_REACHED();
 	}
-
-	VEHICLEUNITNUMBERSORTER(r, va, vb);
-
-	return (_internal_sort_order & 1) ? -r : r;
+	return (r != 0) ? r : VehicleNumberSorter(a, b);
 }
 
 void InitializeGUI()
 {
-	memset(&_sorting, 0, sizeof(_sorting));
+	MemSetT(&_sorting, 0);
 }
 
 /** Assigns an already open vehicle window to a new vehicle.
@@ -915,15 +859,16 @@
 			default: NOT_REACHED(); break;
 		}
 
-		this->vehicles.flags = VL_REBUILD | (this->sorting->order ? VL_DESC : VL_NONE);
-		this->vehicles.sort_type = this->sorting->criteria;
-		this->vehicles.resort_timer = DAY_TICKS * PERIODIC_RESORT_DAYS; // Set up resort timer
+		this->vehicles.SetListing(*this->sorting);
+		this->vehicles.ForceRebuild();
+		this->vehicles.NeedResort();
 
 		this->FindWindowPlacementAndResize(desc);
 	}
 
 	~VehicleListWindow()
 	{
+		*this->sorting = this->vehicles.GetListing();
 	}
 
 	virtual void OnPaint()
@@ -988,9 +933,9 @@
 		this->DrawWidgets();
 
 		/* draw sorting criteria string */
-		DrawString(85, 15, _vehicle_sort_listing[this->vehicles.sort_type], TC_BLACK);
+		DrawString(85, 15, _vehicle_sort_listing[this->vehicles.SortType()], TC_BLACK);
 		/* draw arrow pointing up/down for ascending/descending sorting */
-		this->DrawSortButtonState(VLW_WIDGET_SORT_ORDER, this->vehicles.flags & VL_DESC ? SBS_DOWN : SBS_UP);
+		this->DrawSortButtonState(VLW_WIDGET_SORT_ORDER, this->vehicles.IsDescSortOrder() ? SBS_DOWN : SBS_UP);
 
 		max = min(this->vscroll.pos + this->vscroll.cap, this->vehicles.Length());
 		for (i = this->vscroll.pos; i < max; ++i) {
@@ -1030,14 +975,11 @@
 	{
 		switch (widget) {
 			case VLW_WIDGET_SORT_ORDER: /* Flip sorting method ascending/descending */
-				this->vehicles.flags ^= VL_DESC;
-				this->vehicles.flags |= VL_RESORT;
-
-				this->sorting->order = !!(this->vehicles.flags & VL_DESC);
+				this->vehicles.ToggleSortOrder();
 				this->SetDirty();
 				break;
 			case VLW_WIDGET_SORT_BY_PULLDOWN:/* Select sorting criteria dropdown menu */
-				ShowDropDownMenu(this, _vehicle_sort_listing, this->vehicles.sort_type, VLW_WIDGET_SORT_BY_PULLDOWN, 0, (this->vehicle_type == VEH_TRAIN || this->vehicle_type == VEH_ROAD) ? 0 : (1 << 10));
+				ShowDropDownMenu(this, _vehicle_sort_listing, this->vehicles.SortType(), VLW_WIDGET_SORT_BY_PULLDOWN, 0, (this->vehicle_type == VEH_TRAIN || this->vehicle_type == VEH_ROAD) ? 0 : (1 << 10));
 				return;
 			case VLW_WIDGET_LIST: { /* Matrix to show vehicles */
 				uint32 id_v = (pt.y - PLY_WND_PRC__OFFSET_TOP_WIDGET) / this->resize.step_height;
@@ -1090,12 +1032,7 @@
 	{
 		switch (widget) {
 			case VLW_WIDGET_SORT_BY_PULLDOWN:
-				if (this->vehicles.sort_type != index) {
-					/* value has changed -> resort */
-					this->vehicles.flags |= VL_RESORT;
-					this->vehicles.sort_type = index;
-					this->sorting->criteria = this->vehicles.sort_type;
-				}
+				this->vehicles.SetSortType(index);
 				break;
 			case VLW_WIDGET_MANAGE_VEHICLES_DROPDOWN:
 				assert(this->vehicles.Length() != 0);
@@ -1128,13 +1065,11 @@
 	virtual void OnTick()
 	{
 		if (_pause_game != 0) return;
-		if (--this->vehicles.resort_timer == 0) {
+		if (this->vehicles.NeedResort()) {
 			StationID station = ((this->window_number & VLW_MASK) == VLW_STATION_LIST) ? GB(this->window_number, 16, 16) : INVALID_STATION;
 			PlayerID owner = (PlayerID)this->caption_color;
 
 			DEBUG(misc, 3, "Periodic resort %d list player %d at station %d", this->vehicle_type, owner, station);
-			this->vehicles.resort_timer = DAY_TICKS * PERIODIC_RESORT_DAYS;
-			this->vehicles.flags |= VL_RESORT;
 			this->SetDirty();
 		}
 	}
@@ -1147,7 +1082,11 @@
 
 	virtual void OnInvalidateData(int data)
 	{
-		this->vehicles.flags |= (data == 0 ? VL_REBUILD : VL_RESORT);
+		if (data == 0) {
+			this->vehicles.ForceRebuild();
+		} else {
+			this->vehicles.ForceResort();
+		}
 	}
 };
 
--- a/src/video/cocoa/cocoa_v.mm	Tue Jun 17 10:32:49 2008 +0000
+++ b/src/video/cocoa/cocoa_v.mm	Tue Jun 17 13:22:13 2008 +0000
@@ -206,8 +206,8 @@
 	count = _cocoa_subdriver->ListModes(modes, lengthof(modes));
 
 	for (i = 0; i < count; i++) {
-		_resolutions[i][0] = modes[i].x;
-		_resolutions[i][1] = modes[i].y;
+		_resolutions[i].width  = modes[i].x;
+		_resolutions[i].height = modes[i].y;
 	}
 
 	_num_resolutions = count;
@@ -317,8 +317,8 @@
 	/* Don't create a window or enter fullscreen if we're just going to show a dialog. */
 	if (_cocoa_video_dialog) return NULL;
 
-	width = _cur_resolution[0];
-	height = _cur_resolution[1];
+	width  = _cur_resolution.width;
+	height = _cur_resolution.height;
 	bpp = BlitterFactoryBase::GetCurrentBlitter()->GetScreenDepth();
 
 	_cocoa_subdriver = QZ_CreateSubdriver(width, height, bpp, _fullscreen, true);
--- a/src/video/dedicated_v.cpp	Tue Jun 17 10:32:49 2008 +0000
+++ b/src/video/dedicated_v.cpp	Tue Jun 17 13:22:13 2008 +0000
@@ -138,10 +138,10 @@
 {
 	int bpp = BlitterFactoryBase::GetCurrentBlitter()->GetScreenDepth();
 	if (bpp == 0) _dedicated_video_mem = NULL;
-	else          _dedicated_video_mem = MallocT<byte>(_cur_resolution[0] * _cur_resolution[1] * (bpp / 8));
+	else          _dedicated_video_mem = MallocT<byte>(_cur_resolution.width * _cur_resolution.height * (bpp / 8));
 
-	_screen.width = _screen.pitch = _cur_resolution[0];
-	_screen.height = _cur_resolution[1];
+	_screen.width  = _screen.pitch = _cur_resolution.width;
+	_screen.height = _cur_resolution.height;
 	ScreenSizeChanged();
 
 	SetDebugString("net=6");
--- a/src/video/null_v.cpp	Tue Jun 17 10:32:49 2008 +0000
+++ b/src/video/null_v.cpp	Tue Jun 17 13:22:13 2008 +0000
@@ -15,8 +15,8 @@
 const char *VideoDriver_Null::Start(const char* const *parm)
 {
 	this->ticks = GetDriverParamInt(parm, "ticks", 1000);
-	_screen.width = _screen.pitch = _cur_resolution[0];
-	_screen.height = _cur_resolution[1];
+	_screen.width  = _screen.pitch = _cur_resolution.width;
+	_screen.height = _cur_resolution.height;
 	ScreenSizeChanged();
 
 	/* Do not render, nor blit */
--- a/src/video/sdl_v.cpp	Tue Jun 17 10:32:49 2008 +0000
+++ b/src/video/sdl_v.cpp	Tue Jun 17 13:22:13 2008 +0000
@@ -96,7 +96,7 @@
 	}
 }
 
-static const uint16 default_resolutions[][2] = {
+static const Dimension default_resolutions[] = {
 	{ 640,  480},
 	{ 800,  600},
 	{1024,  768},
@@ -134,12 +134,12 @@
 			if (w >= 640 && h >= 480) {
 				int j;
 				for (j = 0; j < n; j++) {
-					if (_resolutions[j][0] == w && _resolutions[j][1] == h) break;
+					if (_resolutions[j].width == w && _resolutions[j].height == h) break;
 				}
 
 				if (j == n) {
-					_resolutions[j][0] = w;
-					_resolutions[j][1] = h;
+					_resolutions[j].width  = w;
+					_resolutions[j].height = h;
 					if (++n == lengthof(_resolutions)) break;
 				}
 			}
@@ -160,21 +160,21 @@
 
 	// is the wanted mode among the available modes?
 	for (i = 0; i != _num_resolutions; i++) {
-		if (*w == _resolutions[i][0] && *h == _resolutions[i][1]) return;
+		if (*w == _resolutions[i].width && *h == _resolutions[i].height) return;
 	}
 
 	// use the closest possible resolution
 	best = 0;
-	delta = abs((_resolutions[0][0] - *w) * (_resolutions[0][1] - *h));
+	delta = abs((_resolutions[0].width - *w) * (_resolutions[0].height - *h));
 	for (i = 1; i != _num_resolutions; ++i) {
-		uint newdelta = abs((_resolutions[i][0] - *w) * (_resolutions[i][1] - *h));
+		uint newdelta = abs((_resolutions[i].width - *w) * (_resolutions[i].height - *h));
 		if (newdelta < delta) {
 			best = i;
 			delta = newdelta;
 		}
 	}
-	*w = _resolutions[best][0];
-	*h = _resolutions[best][1];
+	*w = _resolutions[best].width;
+	*h = _resolutions[best].height;
 }
 
 #ifndef ICON_DIR
@@ -441,7 +441,7 @@
 	DEBUG(driver, 1, "SDL: using driver '%s'", buf);
 
 	GetVideoModes();
-	CreateMainSurface(_cur_resolution[0], _cur_resolution[1]);
+	CreateMainSurface(_cur_resolution.width, _cur_resolution.height);
 	MarkWholeScreenDirty();
 
 	SDL_CALL SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
@@ -534,7 +534,7 @@
 {
 	_fullscreen = fullscreen;
 	GetVideoModes(); // get the list of available video modes
-	if (_num_resolutions == 0 || !this->ChangeResolution(_cur_resolution[0], _cur_resolution[1])) {
+	if (_num_resolutions == 0 || !this->ChangeResolution(_cur_resolution.width, _cur_resolution.height)) {
 		// switching resolution failed, put back full_screen to original status
 		_fullscreen ^= true;
 		return false;
--- a/src/video/video_driver.hpp	Tue Jun 17 10:32:49 2008 +0000
+++ b/src/video/video_driver.hpp	Tue Jun 17 13:22:13 2008 +0000
@@ -6,6 +6,7 @@
 #define VIDEO_VIDEO_DRIVER_HPP
 
 #include "../driver.h"
+#include "../core/geometry_type.hpp"
 
 class VideoDriver: public Driver {
 public:
@@ -35,7 +36,7 @@
 extern VideoDriver *_video_driver;
 extern char _ini_videodriver[32];
 extern int _num_resolutions;
-extern uint16 _resolutions[32][2];
-extern uint16 _cur_resolution[2];
+extern Dimension _resolutions[32];
+extern Dimension _cur_resolution;
 
 #endif /* VIDEO_VIDEO_DRIVER_HPP */
--- a/src/video/win32_v.cpp	Tue Jun 17 10:32:49 2008 +0000
+++ b/src/video/win32_v.cpp	Tue Jun 17 13:22:13 2008 +0000
@@ -36,7 +36,7 @@
 bool _window_maximize;
 uint _display_hz;
 uint _fullscreen_bpp;
-static uint16 _bck_resolution[2];
+static Dimension _bck_resolution;
 #if !defined(UNICODE)
 uint _codepage;
 #endif
@@ -371,10 +371,7 @@
 			return 0;
 
 		case WM_DESTROY:
-			if (_window_maximize) {
-				_cur_resolution[0] = _bck_resolution[0];
-				_cur_resolution[1] = _bck_resolution[1];
-			}
+			if (_window_maximize) _cur_resolution = _bck_resolution;
 			return 0;
 
 		case WM_LBUTTONDOWN:
@@ -530,10 +527,7 @@
 				/* Set maximized flag when we maximize (obviously), but also when we
 				 * switched to fullscreen from a maximized state */
 				_window_maximize = (wParam == SIZE_MAXIMIZED || (_window_maximize && _fullscreen));
-				if (_window_maximize) {
-					_bck_resolution[0] = _cur_resolution[0];
-					_bck_resolution[1] = _cur_resolution[1];
-				}
+				if (_window_maximize) _bck_resolution = _cur_resolution;
 				ClientSizeChanged(LOWORD(lParam), HIWORD(lParam));
 			}
 			return 0;
@@ -713,7 +707,7 @@
 	return true;
 }
 
-static const uint16 default_resolutions[][2] = {
+static const Dimension default_resolutions[] = {
 	{  640,  480 },
 	{  800,  600 },
 	{ 1024,  768 },
@@ -746,7 +740,7 @@
 			uint j;
 
 			for (j = 0; j < n; j++) {
-				if (_resolutions[j][0] == dm.dmPelsWidth && _resolutions[j][1] == dm.dmPelsHeight) break;
+				if (_resolutions[j].width == (int)dm.dmPelsWidth && _resolutions[j].height == (int)dm.dmPelsHeight) break;
 			}
 
 			/* In the previous loop we have checked already existing/added resolutions if
@@ -754,8 +748,8 @@
 			 * looped all and found none, add the new one to the list. If we have reached the
 			 * maximum amount of resolutions, then quit querying the display */
 			if (j == n) {
-				_resolutions[j][0] = dm.dmPelsWidth;
-				_resolutions[j][1] = dm.dmPelsHeight;
+				_resolutions[j].width  = dm.dmPelsWidth;
+				_resolutions[j].height = dm.dmPelsHeight;
 				if (++n == lengthof(_resolutions)) break;
 			}
 		}
@@ -784,13 +778,13 @@
 
 	FindResolutions();
 
-	DEBUG(driver, 2, "Resolution for display: %dx%d", _cur_resolution[0], _cur_resolution[1]);
+	DEBUG(driver, 2, "Resolution for display: %dx%d", _cur_resolution.width, _cur_resolution.height);
 
 	// fullscreen uses those
-	_wnd.width_org = _cur_resolution[0];
-	_wnd.height_org = _cur_resolution[1];
+	_wnd.width_org  = _cur_resolution.width;
+	_wnd.height_org = _cur_resolution.height;
 
-	AllocateDibSection(_cur_resolution[0], _cur_resolution[1]);
+	AllocateDibSection(_cur_resolution.width, _cur_resolution.height);
 	MakeWindow(_fullscreen);
 
 	MarkWholeScreenDirty();
--- a/src/viewport.cpp	Tue Jun 17 10:32:49 2008 +0000
+++ b/src/viewport.cpp	Tue Jun 17 13:22:13 2008 +0000
@@ -81,7 +81,7 @@
 	const SubSprite *sub;           ///< only draw a rectangular part of the sprite
 	int32 x;
 	int32 y;
-	ChildScreenSpriteToDraw *next;
+	int next;                       ///< next child to draw (-1 at the end)
 };
 
 struct ParentSpriteToDraw {
@@ -103,7 +103,6 @@
 	int zmax;                       ///< maximal world Z coordinate of bounding box
 
 	int first_child;                ///< the first child to draw.
-	int last_child;                 ///< the last sprite to draw.
 	bool comparison_done;           ///< Used during sprite sorting: true if sprite has been compared with all other sprites
 };
 
@@ -677,10 +676,9 @@
 	ps->zmax = z + max(bb_offset_z, dz) - 1;
 
 	ps->comparison_done = false;
-	ps->first_child = _vd.child_screen_sprites_to_draw.items;
-	ps->last_child  = _vd.child_screen_sprites_to_draw.items;
-
-	_vd.last_child = &ps->last_child;
+	ps->first_child = -1;
+
+	_vd.last_child = &ps->first_child;
 
 	if (_vd.combine_sprites == 1) _vd.combine_sprites = 2;
 }
@@ -718,17 +716,22 @@
 		pal = PALETTE_TO_TRANSPARENT;
 	}
 
-	/* Append the sprite to the active ChildSprite list.
-	 * If the active ParentSprite is a foundation, update last_foundation_child as well. */
+	*_vd.last_child = _vd.child_screen_sprites_to_draw.items;
+
 	ChildScreenSpriteToDraw *cs = _vd.child_screen_sprites_to_draw.Append();
 	cs->image = image;
 	cs->pal = pal;
 	cs->sub = sub;
 	cs->x = x;
 	cs->y = y;
-	cs->next = NULL;
-
-	*_vd.last_child = _vd.child_screen_sprites_to_draw.items;
+	cs->next = -1;
+
+	/* Append the sprite to the active ChildSprite list.
+	 * If the active ParentSprite is a foundation, update last_foundation_child as well.
+	 * Note: ChildSprites of foundations are NOT sequential in the vector, as selection sprites are added at last. */
+	if (_vd.last_foundation_child[0] == _vd.last_child) _vd.last_foundation_child[0] = &cs->next;
+	if (_vd.last_foundation_child[1] == _vd.last_child) _vd.last_foundation_child[1] = &cs->next;
+	_vd.last_child = &cs->next;
 }
 
 /* Returns a StringSpriteToDraw */
@@ -1375,8 +1378,10 @@
 		const ParentSpriteToDraw *ps = *it;
 		if (ps->image != SPR_EMPTY_BOUNDING_BOX) DrawSprite(ps->image, ps->pal, ps->x, ps->y, ps->sub);
 
-		const ChildScreenSpriteToDraw *last = csstdv->Get(ps->last_child);
-		for (const ChildScreenSpriteToDraw *cs = csstdv->Get(ps->first_child); cs != last; cs++) {
+		int child_idx = ps->first_child;
+		while (child_idx >= 0) {
+			const ChildScreenSpriteToDraw *cs = csstdv->Get(child_idx);
+			child_idx = cs->next;
 			DrawSprite(cs->image, cs->pal, ps->left + cs->x, ps->top + cs->y, cs->sub);
 		}
 	}
@@ -1895,7 +1900,7 @@
 						y <  si->sign.top + 12 &&
 						x >= si->sign.left &&
 						x <  si->sign.left + si->sign.width_1) {
-					ShowRenameSignWindow(si);
+					HandleClickOnSign(si);
 					return true;
 				}
 			}
@@ -1909,7 +1914,7 @@
 						y <  si->sign.top + 24 &&
 						x >= si->sign.left &&
 						x <  si->sign.left + si->sign.width_1 * 2) {
-					ShowRenameSignWindow(si);
+					HandleClickOnSign(si);
 					return true;
 				}
 			}
@@ -1925,7 +1930,7 @@
 						y <  si->sign.top + ScaleByZoom(12, vp->zoom) &&
 						x >= si->sign.left &&
 						x <  si->sign.left + ScaleByZoom(si->sign.width_2, vp->zoom)) {
-					ShowRenameSignWindow(si);
+					HandleClickOnSign(si);
 					return true;
 				}
 			}
--- a/src/water_cmd.cpp	Tue Jun 17 10:32:49 2008 +0000
+++ b/src/water_cmd.cpp	Tue Jun 17 13:22:13 2008 +0000
@@ -40,6 +40,7 @@
 #include "newgrf_cargo.h"
 #include "effectvehicle_func.h"
 #include "oldpool_func.h"
+#include "tunnelbridge_map.h"
 
 #include "table/sprites.h"
 #include "table/strings.h"
@@ -482,13 +483,19 @@
 {
 	switch (GetTileType(tile)) {
 		case MP_WATER:
-			if (!IsCoast(tile)) return true;
-			switch (GetTileSlope(tile, NULL)) {
-				case SLOPE_W: return (from == DIR_SE) || (from == DIR_E) || (from == DIR_NE);
-				case SLOPE_S: return (from == DIR_NE) || (from == DIR_N) || (from == DIR_NW);
-				case SLOPE_E: return (from == DIR_NW) || (from == DIR_W) || (from == DIR_SW);
-				case SLOPE_N: return (from == DIR_SW) || (from == DIR_S) || (from == DIR_SE);
-				default: return false;
+			switch (GetWaterTileType(tile)) {
+				default: NOT_REACHED();
+				case WATER_TILE_DEPOT: case WATER_TILE_CLEAR: return true;
+				case WATER_TILE_LOCK: return DiagDirToAxis(GetLockDirection(tile)) == DiagDirToAxis(DirToDiagDir(from));
+
+				case WATER_TILE_COAST:
+					switch (GetTileSlope(tile, NULL)) {
+						case SLOPE_W: return (from == DIR_SE) || (from == DIR_E) || (from == DIR_NE);
+						case SLOPE_S: return (from == DIR_NE) || (from == DIR_N) || (from == DIR_NW);
+						case SLOPE_E: return (from == DIR_NW) || (from == DIR_W) || (from == DIR_SW);
+						case SLOPE_N: return (from == DIR_SW) || (from == DIR_S) || (from == DIR_SE);
+						default: return false;
+					}
 			}
 
 		case MP_RAILWAY:
@@ -506,6 +513,7 @@
 
 		case MP_STATION:  return IsCustomFSMportsSpecIndex(tile) || IsOilRig(tile) || (IsDock(tile) && GetTileSlope(tile, NULL) == SLOPE_FLAT) || IsBuoy(tile);
 		case MP_INDUSTRY: return (GetIndustrySpec(GetIndustryType(tile))->behaviour & INDUSTRYBEH_BUILT_ONWATER) != 0;
+		case MP_TUNNELBRIDGE: return GetTunnelBridgeTransportType(tile) == TRANSPORT_WATER && ReverseDiagDir(GetTunnelBridgeDirection(tile)) == DirToDiagDir(from);
 		default:          return false;
 	}
 }
@@ -726,15 +734,16 @@
 {
 	switch (GetWaterTileType(tile)) {
 		case WATER_TILE_CLEAR:
-			if (!IsCanal(tile)) {
-				td->str = STR_3804_WATER;
-			} else {
-				td->str = STR_LANDINFO_CANAL;
+			switch (GetWaterClass(tile)) {
+				case WATER_CLASS_SEA:   td->str = STR_3804_WATER;     break;
+				case WATER_CLASS_CANAL: td->str = STR_LANDINFO_CANAL; break;
+				case WATER_CLASS_RIVER: td->str = STR_LANDINFO_RIVER; break;
+				default: assert(0); break;
 			}
 			break;
 		case WATER_TILE_COAST: td->str = STR_3805_COAST_OR_RIVERBANK; break;
-		case WATER_TILE_LOCK : td->str = STR_LANDINFO_LOCK; break;
-		case WATER_TILE_DEPOT: td->str = STR_3806_SHIP_DEPOT; break;
+		case WATER_TILE_LOCK : td->str = STR_LANDINFO_LOCK;           break;
+		case WATER_TILE_DEPOT: td->str = STR_3806_SHIP_DEPOT;         break;
 		default: assert(0); break;
 	}
 
--- a/src/win32.cpp	Tue Jun 17 10:32:49 2008 +0000
+++ b/src/win32.cpp	Tue Jun 17 13:22:13 2008 +0000
@@ -474,7 +474,7 @@
 
 	_ident = GetTickCount(); // something pretty unique
 
-	MakeCRCTable((uint32*)alloca(256 * sizeof(uint32)));
+	MakeCRCTable(AllocaM(uint32, 256));
 	_crash_msg = output = (char*)LocalAlloc(LMEM_FIXED, 8192);
 
 	{
--- a/src/window.cpp	Tue Jun 17 10:32:49 2008 +0000
+++ b/src/window.cpp	Tue Jun 17 13:22:13 2008 +0000
@@ -1809,7 +1809,6 @@
 	DecreaseWindowCounters();
 	HandlePlacePresize();
 	UpdateTileSelection();
-	HandleKeyScrolling();
 
 	if (!VpHandlePlaceSizingDrag())  return;
 	if (!HandleDragDrop())           return;
@@ -1949,6 +1948,7 @@
  */
 void InputLoop()
 {
+	HandleKeyScrolling();
 	HandleMouseEvents();
 	HandleAutoscroll();
 }
--- a/src/yapf/follow_track.hpp	Tue Jun 17 10:32:49 2008 +0000
+++ b/src/yapf/follow_track.hpp	Tue Jun 17 13:22:13 2008 +0000
@@ -264,7 +264,7 @@
 		}
 
 		// tunnel holes and bridge ramps can be entered only from proper direction
-		if (!IsWaterTT() && IsTileType(m_new_tile, MP_TUNNELBRIDGE)) {
+		if (IsTileType(m_new_tile, MP_TUNNELBRIDGE)) {
 			if (IsTunnel(m_new_tile)) {
 				if (!m_is_tunnel) {
 					DiagDirection tunnel_enterdir = GetTunnelBridgeDirection(m_new_tile);
--- a/src/yapf/yapf_ship.cpp	Tue Jun 17 10:32:49 2008 +0000
+++ b/src/yapf/yapf_ship.cpp	Tue Jun 17 13:22:13 2008 +0000
@@ -109,6 +109,9 @@
 			/* new trackdir does not match the next one when going straight */
 			c += 10;
 		}
+
+		c += YAPF_TILE_LENGTH * tf->m_tiles_skipped;
+
 		// apply it
 		n.m_cost = n.m_parent->m_cost + c;
 		return true;