(svn r13600) [NoAI] -Sync: with trunk r13508:13599. noai
authorrubidium
Sat, 21 Jun 2008 13:40:17 +0000
branchnoai
changeset 11044 097ea3e7ec56
parent 11043 e44adcf4ed4d
child 11048 186fcb00d2a5
(svn r13600) [NoAI] -Sync: with trunk r13508:13599.
changelog.txt
known-bugs.txt
os/debian/changelog
os/win32/installer/install.nsi
projects/openttd_vs80.vcproj
projects/openttd_vs90.vcproj
readme.txt
source.list
src/blitter/32bpp_anim.cpp
src/blitter/32bpp_base.hpp
src/blitter/8bpp_optimized.cpp
src/blitter/8bpp_optimized.hpp
src/blitter/factory.hpp
src/bridge_gui.cpp
src/core/endian_func.hpp
src/core/endian_type.hpp
src/core/mem_func.hpp
src/core/smallvec_type.hpp
src/core/sort_func.hpp
src/date.cpp
src/date_func.h
src/date_type.h
src/driver.cpp
src/endian_check.cpp
src/engine_gui.cpp
src/fios.h
src/gamelog.cpp
src/gfx.cpp
src/gfx_func.h
src/gfx_type.h
src/graph_gui.cpp
src/group_gui.cpp
src/lang/english.txt
src/main_gui.cpp
src/minilzo.cpp
src/misc/blob.hpp
src/misc/smallvec.h
src/newgrf.cpp
src/newgrf_house.cpp
src/newgrf_industrytiles.cpp
src/newgrf_spritegroup.cpp
src/openttd.cpp
src/order_cmd.cpp
src/os/macosx/splash.cpp
src/players.cpp
src/rail_cmd.cpp
src/roadveh_cmd.cpp
src/screenshot.cpp
src/settings.cpp
src/settings_gui.cpp
src/signal.cpp
src/sortlist_type.h
src/sound.cpp
src/sound/cocoa_s.cpp
src/squirrel_helper.hpp
src/station_cmd.cpp
src/strings.cpp
src/table/palettes.h
src/terraform_gui.cpp
src/toolbar_gui.cpp
src/town_cmd.cpp
src/town_gui.cpp
src/vehicle_gui.cpp
src/vehicle_gui.h
src/vehiclelist.h
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/zoom_type.h
--- a/changelog.txt	Sat Jun 21 13:35:29 2008 +0000
+++ b/changelog.txt	Sat Jun 21 13:40:17 2008 +0000
@@ -1,3 +1,111 @@
+0.6.1 (2008-06-01)
+------------------------------------------------------------------------
+- Fix: Industry tiles would sometimes tell they need a 'level' slope when they do not want the slope (r13348)
+- Fix: Attempts to make the old AI perform better (r13217, r13221, r13222)
+
+
+0.6.1-RC2 (2008-05-21)
+------------------------------------------------------------------------
+- Fix: Do not send rcon commands of the server to the first client but do directly execute those on the server (r13137)
+- Fix: For multiheaded engines, halve power and running cost when used instead of when loading, to allow callback values to work properly (r13074)
+- Fix: Loading of TTDP savegames with rivers in them [FS#2005] (r13066)
+- Fix: Update build industry window when raw_industry_construction setting is modified (r13060)
+- Fix: Revert changes to multihead engine weight -- the original values were correct (r13023)
+- Fix: Debugging was not possible with MSVC 2008 (r12996)
+- Fix: List used for sorting GRFs was not freed (r12993)
+- Fix: Default difficulty settings were different to TTD's original settings [FS#1977] (r12951)
+- Fix: All vehicles would be available when an original scenario would be played [FS#1982] (r12948)
+- Fix: Keep only first 15 bits for non failed callback results (r12947)
+- Fix: Reading/modifying invalid data under some circumstances (r12943)
+- Fix: Minor errors related to industries accepted/produced cargo (r12933)
+- Fix: Town rating was affected even after the test run (r12920)
+- Fix: Flood road tiles even when there are road works in progress [FS#1965] (r12919)
+- Fix: Do not initialize Station struct with tile=0, buoys will never change that value [FS#1960] (r12915)
+- Fix: Game crash when a spectator/server tried to show an engine with no owner when a NewGRF requested a specific variable (r12914)
+- Fix: Report reverse sprite status (FD/FE) to NewGRF for manually toggled vehicles (r12910)
+- Fix: Vehicles going twice to a depot when the automatic service interfered with the current order [FS#1985] (r12629)
+
+
+0.6.1-RC1 (2008-04-26)
+------------------------------------------------------------------------
+- Fix: Vehicle groups, engine replacement rules and player/company names were not properly reset/freed after bankrupt (r12906)
+- Fix: Remove trams from savegames saved in OTTD without tram support, it is better than to simply crash [FS#1953] (r12904)
+- Fix: GCC on FreeBSD does not support -dumpmachine causing configure to fail. Use g++ instead [FS#1928] (r12876)
+- Fix: Make the town rating tests use less memory and much quicker (r12859)
+- Fix: Usage of AutoPtr made (trying to) build stuff very (time) expensive (r12857, r12855)
+- Fix: Ensure that prop 25 is set for all vehicles in the consist before other properties as it could cause desyncs (r12856)
+- Fix: Too much catenary was drawn about tunnel entrances, middle bridge pieces and non-rail station tiles (r12853, r12852)
+- Fix: Use YAPF for fairly old savegames from before YAPF was introduced (r12845)
+- Fix: The industry tick trigger should only be triggered once every 256 ticks, not every tick... Also bail out of the triggers a little earlier if you know they are not going to happen anyway (r12844)
+- Fix: Inconsistent use of 8/15-bitness of NewGRF callback results with respect to TTDP's implementation of the specification (r12819, r12818, r12759)
+- Fix: Possible out of bounds array access (r12809)
+- Fix: Enforce autorenew values range in command (r12808)
+- Fix: Vehicles could break down during loading and keep loading. The intention of the break down code is not to break down when having zero speed, therefor break downs now do not happen when loading [FS#1938] (r12795)
+- Fix: [OSX] In some rare cases when using an uncalibrated monitor the system colour space could not be retrieved. Show an error when this happens instead of just trying an assertion (r12776)
+- Fix: Slope checking for NewGRFs failed (r12759)
+- Fix: Check the TILE_NOT_SLOPED flag of the _north_ tile of multi-tile houses to decide if autoslope is allowed (r12717)
+- Fix: Do not move windows below the toolbar on resizes unless they would go behind the toolbar [FS#1904] (r12714)
+- Fix: Increase default sound buffer size only for Vista [FS#1914] (r12708)
+- Fix: Do not crash very hard on unrecognised savegames, just go back to the intro menu instead (r12707)
+- Fix: In some cases a news messages would not be shown [FS#1906] (r12683)
+- Fix: Removing road pieces from a town gave you twice the intended penalty [FS#1920] (r12682)
+- Fix: When a road vehicle has a tram only stop multiple times in a row in it's orders, only the first one would be skipped [FS#1918] (r12678)
+- Fix: Colour remaps on station sprites only worked for company colours [FS#1902] (r12674)
+- Fix: Remove buggy buoys at tile 0 from old TTDP savegames (r12642)
+- Fix: Possible NULL pointer dereference when reading some NewGRF data [FS#1913] (r12637)
+- Fix: Infinite loop in case your compiler decides that enums are unsigned by default (r12622)
+- Fix: The convert signal button disallowed signal dragging when the signal GUI was closed (r12577)
+- Fix: Binding to a specific IP could cause OpenTTD to not register properly with the masterserver if one has multiple external interfaces (r12574)
+- Fix: min() has 32bit arguments, clamping of 64bit values did not work (r12572)
+- Fix: Towns could not terraform when inflation rised terraform prices enough (r12564)
+- Fix: Do not affect town rating change by the order in which we examine stations (r12561)
+- Fix: Redraw the signal GUI when the signal drag density changes in the patch settings and vice versa (r12553)
+- Fix: Do not install scenarios into the current user's homedir when running 'make install', that is silly. Simply always install scenarios system wide instead (r12542)
+
+
+0.6.0 (2008-04-01)
+------------------------------------------------------------------------
+- Fix: Final formatting of some string codes from NewGRFs was not done correctly [FS#1889] (r12488)
+- Fix: Timetable times for aircraft were always doubled [FS#1883] (r12477)
+- Fix: Remove broken endian-dependent code and unnecessary rgb to bgr swapping [FS#1880] (r12453)
+- Fix: Do not 'disable' the drawing of autorail overlays when the tile is 'error'-marked (red pulsating selection) [FS#1871] (r12439)
+- Fix: Plural rule for Icelandic was wrong (r12417)
+
+
+0.6.0-RC1 (2008-03-26)
+------------------------------------------------------------------------
+- Feature: Show whether a town is a "city" in the town description title bar (r12391)
+- Feature: Increase house animation frame number from 32 to 128 (r12347)
+- Fix: Loading of TTD savegames (r12399, r12401)
+- Fix: Vehicle lists related to stations not closed when the station is deleted [FS#1872] (r12393)
+- Fix: Trams failing to turn on bridge heads/tunnel entrances [FS#1851] (r123890)
+- Fix: Train could break apart when reversed while partially in a depot [FS#1841] (r12386, r12384)
+- Fix: Non-breaking spaces should not be broken (r12385)
+- Fix: Check return of AfterLoadGame for success or failure when loading TTD games [FS#1860] (r12383)
+- Fix: Use 'items' unit for batteries, fizzy drinks, toys and bubbles in total cargo tab [FS#1864] (r12382)
+- Fix: The number of houses wasn't computed right [FS#1835, FS#1535] (r12381)
+- Fix: Update train acceleration and max speed after setting cached value to ensure the correct max speed is used with disabled real acceleration (r12380)
+- Fix: Refresh vehicle details window when cached values are updated (r12378)
+- Fix: Set cached value for vehicle property 25 before other cached values [FS#1854] (r12377)
+- Fix: Don't close a dropmenu when clicking on a dropdown widget (r12374)
+- Fix: win32 music driver fails if path is too long or if containing non-latin chars [FS#1849] (r12373, r12372)
+- Fix: Do not let window hide behind the main toolbar after resizing the screen [FS#1823] (r12371)
+- Fix: Close language drop down when parent window is clicked/closed [FS#1853] (r12370)
+- Fix: Reset train speed limits when _patches.realistic_acceleration changes (r12369)
+- Fix: Commands were sent to clients waiting for map download causing 'executing command from the past' error [FS#1650] (r12367)
+- Fix: Do not allow building 'zero' road bits (r12363)
+- Fix: Randomize variable 8F only once per callback 28 (r12362)
+- Fix: openttdd.grf was using the wrong colours for glyphs due to a grfcodec bug (fixed in grfcodec 0.9.10 r1837) (r12360)
+- Fix: Some callback-results were treated as 8 bit, when they were 15 bit, and vice versa (r12352, r12358)
+- Fix: Do not try to flood water tile [FS#1836] (r12350)
+- Fix: NTP skipped junction just after bridge end (r12348)
+- Fix: Remove duplicated and inconsistent code wrt. autoreplace with rules in both vehicles' group and ALL_GROUP [FS#1748, FS#1825] (r12346)
+- Fix: Don't try to restore backupped timetable when timetabling is disabled [FS#1828] (r12345)
+- Fix: Slow helicopters never got the 'chance' to finish the landing routine (r12343)
+- Fix: GRM buffer for cargos was incorrect size [FS#1827] (r12341)
+- Fix: Recalculate cached train data after clearing reversing flag when entering depot (r12339)
+
+
 0.6.0-beta5 (2008-03-04)
 ------------------------------------------------------------------------
 - Feature: Vehicle variable FE bit 5, 6 and 8 [FS#1812] (r12331, r12330)
@@ -15,7 +123,7 @@
 - Fix: Include prop 25 data for all train parts, not just those that carry cargo (r12314)
 - Fix: YAPF and NTP did not apply penalty for uphill tracks on steep slopes (r12313)
 - Fix: Restore timetable from backupped orders and add group ID to the backup [FS#1549] (r12296)
-- Fix: Do not draw trees nor lamps between tram tracks  (r12290) [FS#1807]
+- Fix: Do not draw trees nor lamps between tram tracks (r12290) [FS#1807]
 - Fix: [Win32] Do not create save dir on install (r12269)
 - Fix: Autoreplace did not update vehicle index for timetable window [FS#1805] (r12261)
 - Fix: GetProductionAroundTiles() may fail if only the second production slot exists (r12258)
@@ -26,7 +134,7 @@
 - Fix: When loading a savegame fails, do not start creating a new game, just go straight back to the intro screen (r12202)
 - Fix: Force AI to build rail or road instead of bridges if possible, so it doesn't build bridges everywhere (r12200)
 - Fix: "Transparent buildings" now only toggles buildings, so show tick when buildings are transparent [FS#1789] (r12198)
-- Fix: Show correct last year profit when the train had negative income  [FS#1788] (r12197)
+- Fix: Show correct last year profit when the train had negative income [FS#1788] (r12197)
 - Fix: There can be oil rigs at map borders, do not set water class for them [FS#1787] (r12195)
 - Fix: Do not start overtaking if the RV reaches wrong-way one-way-road in the next tiles (r12191)
 - Fix: Assert when trying to play tile sound at NW border of map (placing buyos, leveling land) [FS#1784] (r12186)
--- a/known-bugs.txt	Sat Jun 21 13:35:29 2008 +0000
+++ b/known-bugs.txt	Sat Jun 21 13:40:17 2008 +0000
@@ -11,15 +11,23 @@
 If the bug report is closed, it has been fixed, which then can be verified
 in the latest SVN version of /trunk.
 
-Bugs for 0.6.0-beta5
+Bugs for 0.6.1
 ------------------------------------------------------------------------
 URL: http://bugs.openttd.org
 
+- 1944	Road vehicles not picking empty drivethrough platform
+- 1923	Unique names not always enforced
+- 1891	Go to depot for servicing is forgotten
+- 1890	Airplanes copy helipcopters goto heliport order
+- 1885	Almost all unserved industries die in big maps
+- 1868	In depot, cannot move wagon from another line before first wagon in a wagon-only line
+- 1858	Industry legend in small map overwrites buttons
+- 1852	Minor tram reversing glitches
+- 1802	Path with space in configure fails
+- 1793	Inconsistent travel time for fast trains
 - 1762	Strange Autoreplace behaviour
-- 1711	Gravel and Clay have no worth
+- 1752	User input is not checked
 - 1693	Removing road does not reset owner
-- 1495	Long vehicles block multistop station
-- 1487	Ending_year is never written to
 - 1473	Train not going to available platform
 - 1404	Spinner widget interprets one click as many
 - 1264	Autoreplace for multiple NewGRF DMU sets fails
--- a/os/debian/changelog	Sat Jun 21 13:35:29 2008 +0000
+++ b/os/debian/changelog	Sat Jun 21 13:40:17 2008 +0000
@@ -4,6 +4,36 @@
 
  -- Matthijs Kooijman <m.kooijman@student.utwente.nl>  Sat, 22 Mar 2007 21:07:05 +0100
 
+openttd (0.6.1-1) unstable; urgency=low
+
+  * New upstream release.
+
+ -- Matthijs Kooijman <m.kooijman@student.utwente.nl>  Sun, 01 Jun 2008 15:35:00 +0200
+
+openttd (0.6.1~RC2-1) unstable; urgency=low
+
+  * New upstream release.
+
+ -- Matthijs Kooijman <m.kooijman@student.utwente.nl>  Wed, 21 May 2008 00:05:00 +0200
+
+openttd (0.6.1~RC1-1) unstable; urgency=low
+
+  * New upstream release.
+
+ -- Matthijs Kooijman <m.kooijman@student.utwente.nl>  Sat, 26 Apr 2008 22:55:00 +0200
+
+openttd (0.6.0-1) unstable; urgency=low
+
+  * New upstream release.
+
+ -- Matthijs Kooijman <m.kooijman@student.utwente.nl>  Tue, 01 Apr 2008 13:33:37 +0100
+
+openttd (0.6.0~RC1-1) unstable; urgency=low
+
+  * New upstream release.
+
+ -- Matthijs Kooijman <m.kooijman@student.utwente.nl>  Wed, 26 Mar 2008 15:51:40 +0100
+
 openttd (0.6.0~beta5) unstable; urgency=low
 
   * New upstream release.
--- a/os/win32/installer/install.nsi	Sat Jun 21 13:35:29 2008 +0000
+++ b/os/win32/installer/install.nsi	Sat Jun 21 13:40:17 2008 +0000
@@ -1,9 +1,9 @@
 !define APPNAME "OpenTTD"   ; Define application name
-!define APPVERSION "0.6.0"  ; Define application version
-!define INSTALLERVERSION 43 ; NEED TO UPDATE THIS FOR EVERY RELEASE!!!
+!define APPVERSION "0.6.1"  ; Define application version
+!define INSTALLERVERSION 48 ; NEED TO UPDATE THIS FOR EVERY RELEASE!!!
 
 !define APPURLLINK "http://www.openttd.org"
-!define APPNAMEANDVERSION "${APPNAME} ${APPVERSION}-beta5"
+!define APPNAMEANDVERSION "${APPNAME} ${APPVERSION}"
 !define APPVERSIONINTERNAL "${APPVERSION}.0" ; Needs to be of the format X.X.X.X
 
 !define MUI_ICON "..\..\..\media\openttd.ico"
--- a/projects/openttd_vs80.vcproj	Sat Jun 21 13:35:29 2008 +0000
+++ b/projects/openttd_vs80.vcproj	Sat Jun 21 13:40:17 2008 +0000
@@ -456,10 +456,6 @@
 				>
 			</File>
 			<File
-				RelativePath=".\..\src\core\alloc_func.cpp"
-				>
-			</File>
-			<File
 				RelativePath=".\..\src\animated_tile.cpp"
 				>
 			</File>
@@ -472,10 +468,6 @@
 				>
 			</File>
 			<File
-				RelativePath=".\..\src\core\bitmath_func.cpp"
-				>
-			</File>
-			<File
 				RelativePath=".\..\src\bmp.cpp"
 				>
 			</File>
@@ -684,10 +676,6 @@
 				>
 			</File>
 			<File
-				RelativePath=".\..\src\core\random_func.cpp"
-				>
-			</File>
-			<File
 				RelativePath=".\..\src\rev.cpp"
 				>
 			</File>
@@ -812,14 +800,6 @@
 				>
 			</File>
 			<File
-				RelativePath=".\..\src\core\alloc_func.hpp"
-				>
-			</File>
-			<File
-				RelativePath=".\..\src\core\alloc_type.hpp"
-				>
-			</File>
-			<File
 				RelativePath=".\..\src\animated_tile_func.h"
 				>
 			</File>
@@ -852,10 +832,6 @@
 				>
 			</File>
 			<File
-				RelativePath=".\..\src\core\bitmath_func.hpp"
-				>
-			</File>
-			<File
 				RelativePath=".\..\src\bmp.h"
 				>
 			</File>
@@ -996,10 +972,6 @@
 				>
 			</File>
 			<File
-				RelativePath=".\..\src\core\endian_func.hpp"
-				>
-			</File>
-			<File
 				RelativePath=".\..\src\engine_base.h"
 				>
 			</File>
@@ -1016,10 +988,6 @@
 				>
 			</File>
 			<File
-				RelativePath=".\..\src\core\enum_type.hpp"
-				>
-			</File>
-			<File
 				RelativePath=".\..\src\fiber.hpp"
 				>
 			</File>
@@ -1048,10 +1016,6 @@
 				>
 			</File>
 			<File
-				RelativePath=".\..\src\core\geometry_type.hpp"
-				>
-			</File>
-			<File
 				RelativePath=".\..\src\gfx_func.h"
 				>
 			</File>
@@ -1116,10 +1080,6 @@
 				>
 			</File>
 			<File
-				RelativePath=".\..\src\core\math_func.hpp"
-				>
-			</File>
-			<File
 				RelativePath=".\..\src\md5.h"
 				>
 			</File>
@@ -1300,10 +1260,6 @@
 				>
 			</File>
 			<File
-				RelativePath=".\..\src\core\overflowsafe_type.hpp"
-				>
-			</File>
-			<File
 				RelativePath=".\..\src\pathfind.h"
 				>
 			</File>
@@ -1348,10 +1304,6 @@
 				>
 			</File>
 			<File
-				RelativePath=".\..\src\core\random_func.hpp"
-				>
-			</File>
-			<File
 				RelativePath=".\..\src\rev.h"
 				>
 			</File>
@@ -1685,6 +1637,74 @@
 			</File>
 		</Filter>
 		<Filter
+			Name="Core Source Code"
+			>
+			<File
+				RelativePath=".\..\src\core\alloc_func.hpp"
+				>
+			</File>
+			<File
+				RelativePath=".\..\src\core\alloc_func.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\..\src\core\alloc_type.hpp"
+				>
+			</File>
+			<File
+				RelativePath=".\..\src\core\bitmath_func.hpp"
+				>
+			</File>
+			<File
+				RelativePath=".\..\src\core\bitmath_func.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\..\src\core\endian_func.hpp"
+				>
+			</File>
+			<File
+				RelativePath=".\..\src\core\endian_type.hpp"
+				>
+			</File>
+			<File
+				RelativePath=".\..\src\core\enum_type.hpp"
+				>
+			</File>
+			<File
+				RelativePath=".\..\src\core\geometry_type.hpp"
+				>
+			</File>
+			<File
+				RelativePath=".\..\src\core\math_func.hpp"
+				>
+			</File>
+			<File
+				RelativePath=".\..\src\core\mem_func.hpp"
+				>
+			</File>
+			<File
+				RelativePath=".\..\src\core\overflowsafe_type.hpp"
+				>
+			</File>
+			<File
+				RelativePath=".\..\src\core\random_func.hpp"
+				>
+			</File>
+			<File
+				RelativePath=".\..\src\core\random_func.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\..\src\core\smallvec_type.hpp"
+				>
+			</File>
+			<File
+				RelativePath=".\..\src\core\sort_func.hpp"
+				>
+			</File>
+		</Filter>
+		<Filter
 			Name="GUI Source Code"
 			>
 			<File
@@ -2928,10 +2948,6 @@
 				>
 			</File>
 			<File
-				RelativePath=".\..\src\misc\smallvec.h"
-				>
-			</File>
-			<File
 				RelativePath=".\..\src\misc\str.hpp"
 				>
 			</File>
--- a/projects/openttd_vs90.vcproj	Sat Jun 21 13:35:29 2008 +0000
+++ b/projects/openttd_vs90.vcproj	Sat Jun 21 13:40:17 2008 +0000
@@ -453,10 +453,6 @@
 				>
 			</File>
 			<File
-				RelativePath=".\..\src\core\alloc_func.cpp"
-				>
-			</File>
-			<File
 				RelativePath=".\..\src\animated_tile.cpp"
 				>
 			</File>
@@ -469,10 +465,6 @@
 				>
 			</File>
 			<File
-				RelativePath=".\..\src\core\bitmath_func.cpp"
-				>
-			</File>
-			<File
 				RelativePath=".\..\src\bmp.cpp"
 				>
 			</File>
@@ -681,10 +673,6 @@
 				>
 			</File>
 			<File
-				RelativePath=".\..\src\core\random_func.cpp"
-				>
-			</File>
-			<File
 				RelativePath=".\..\src\rev.cpp"
 				>
 			</File>
@@ -809,14 +797,6 @@
 				>
 			</File>
 			<File
-				RelativePath=".\..\src\core\alloc_func.hpp"
-				>
-			</File>
-			<File
-				RelativePath=".\..\src\core\alloc_type.hpp"
-				>
-			</File>
-			<File
 				RelativePath=".\..\src\animated_tile_func.h"
 				>
 			</File>
@@ -849,10 +829,6 @@
 				>
 			</File>
 			<File
-				RelativePath=".\..\src\core\bitmath_func.hpp"
-				>
-			</File>
-			<File
 				RelativePath=".\..\src\bmp.h"
 				>
 			</File>
@@ -993,10 +969,6 @@
 				>
 			</File>
 			<File
-				RelativePath=".\..\src\core\endian_func.hpp"
-				>
-			</File>
-			<File
 				RelativePath=".\..\src\engine_base.h"
 				>
 			</File>
@@ -1013,10 +985,6 @@
 				>
 			</File>
 			<File
-				RelativePath=".\..\src\core\enum_type.hpp"
-				>
-			</File>
-			<File
 				RelativePath=".\..\src\fiber.hpp"
 				>
 			</File>
@@ -1045,10 +1013,6 @@
 				>
 			</File>
 			<File
-				RelativePath=".\..\src\core\geometry_type.hpp"
-				>
-			</File>
-			<File
 				RelativePath=".\..\src\gfx_func.h"
 				>
 			</File>
@@ -1113,10 +1077,6 @@
 				>
 			</File>
 			<File
-				RelativePath=".\..\src\core\math_func.hpp"
-				>
-			</File>
-			<File
 				RelativePath=".\..\src\md5.h"
 				>
 			</File>
@@ -1297,10 +1257,6 @@
 				>
 			</File>
 			<File
-				RelativePath=".\..\src\core\overflowsafe_type.hpp"
-				>
-			</File>
-			<File
 				RelativePath=".\..\src\pathfind.h"
 				>
 			</File>
@@ -1345,10 +1301,6 @@
 				>
 			</File>
 			<File
-				RelativePath=".\..\src\core\random_func.hpp"
-				>
-			</File>
-			<File
 				RelativePath=".\..\src\rev.h"
 				>
 			</File>
@@ -1682,6 +1634,74 @@
 			</File>
 		</Filter>
 		<Filter
+			Name="Core Source Code"
+			>
+			<File
+				RelativePath=".\..\src\core\alloc_func.hpp"
+				>
+			</File>
+			<File
+				RelativePath=".\..\src\core\alloc_func.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\..\src\core\alloc_type.hpp"
+				>
+			</File>
+			<File
+				RelativePath=".\..\src\core\bitmath_func.hpp"
+				>
+			</File>
+			<File
+				RelativePath=".\..\src\core\bitmath_func.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\..\src\core\endian_func.hpp"
+				>
+			</File>
+			<File
+				RelativePath=".\..\src\core\endian_type.hpp"
+				>
+			</File>
+			<File
+				RelativePath=".\..\src\core\enum_type.hpp"
+				>
+			</File>
+			<File
+				RelativePath=".\..\src\core\geometry_type.hpp"
+				>
+			</File>
+			<File
+				RelativePath=".\..\src\core\math_func.hpp"
+				>
+			</File>
+			<File
+				RelativePath=".\..\src\core\mem_func.hpp"
+				>
+			</File>
+			<File
+				RelativePath=".\..\src\core\overflowsafe_type.hpp"
+				>
+			</File>
+			<File
+				RelativePath=".\..\src\core\random_func.hpp"
+				>
+			</File>
+			<File
+				RelativePath=".\..\src\core\random_func.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\..\src\core\smallvec_type.hpp"
+				>
+			</File>
+			<File
+				RelativePath=".\..\src\core\sort_func.hpp"
+				>
+			</File>
+		</Filter>
+		<Filter
 			Name="GUI Source Code"
 			>
 			<File
@@ -2925,10 +2945,6 @@
 				>
 			</File>
 			<File
-				RelativePath=".\..\src\misc\smallvec.h"
-				>
-			</File>
-			<File
 				RelativePath=".\..\src\misc\str.hpp"
 				>
 			</File>
--- a/readme.txt	Sat Jun 21 13:35:29 2008 +0000
+++ b/readme.txt	Sat Jun 21 13:40:17 2008 +0000
@@ -1,6 +1,6 @@
 OpenTTD README
-Last updated:    2008-03-04
-Release version: 0.6.0-beta5
+Last updated:    2008-06-01
+Release version: 0.6.1
 ------------------------------------------------------------------------
 
 
--- a/source.list	Sat Jun 21 13:35:29 2008 +0000
+++ b/source.list	Sat Jun 21 13:40:17 2008 +0000
@@ -1,10 +1,8 @@
 # Source Files
 airport.cpp
-core/alloc_func.cpp
 animated_tile.cpp
 articulated_vehicles.cpp
 aystar.cpp
-core/bitmath_func.cpp
 bmp.cpp
 callback_table.cpp
 cargopacket.cpp
@@ -62,7 +60,6 @@
 players.cpp
 queue.cpp
 rail.cpp
-core/random_func.cpp
 rev.cpp
 road.cpp
 saveload.cpp
@@ -128,8 +125,6 @@
 aircraft.h
 airport.h
 airport_movement.h
-core/alloc_func.hpp
-core/alloc_type.hpp
 animated_tile_func.h
 articulated_vehicles.h
 autoreplace_base.h
@@ -138,7 +133,6 @@
 autoreplace_type.h
 autoslope.h
 aystar.h
-core/bitmath_func.hpp
 bmp.h
 bridge.h
 callback_table.h
@@ -174,12 +168,10 @@
 effectvehicle_func.h
 effectvehicle_base.h
 elrail_func.h
-core/endian_func.hpp
 engine_base.h
 engine_func.h
 engine_gui.h
 engine_type.h
-core/enum_type.hpp
 fiber.hpp
 fileio.h
 fios.h
@@ -187,7 +179,6 @@
 functions.h
 gamelog.h
 genworld.h
-core/geometry_type.hpp
 gfx_func.h
 gfx_type.h
 gfxinit.h
@@ -204,7 +195,6 @@
 lzoconf.h
 map_func.h
 map_type.h
-core/math_func.hpp
 md5.h
 minilzo.h
 mixer.h
@@ -250,7 +240,6 @@
 order_base.h
 order_func.h
 order_type.h
-core/overflowsafe_type.hpp
 pathfind.h
 player_base.h
 player_face.h
@@ -262,7 +251,6 @@
 rail.h
 rail_gui.h
 rail_type.h
-core/random_func.hpp
 rev.h
 road_cmd.h
 road_func.h
@@ -361,6 +349,24 @@
 video/cocoa/cocoa_v.h
 #end
 
+# Core Source Code
+core/alloc_func.hpp
+core/alloc_func.cpp
+core/alloc_type.hpp
+core/bitmath_func.hpp
+core/bitmath_func.cpp
+core/endian_func.hpp
+core/endian_type.hpp
+core/enum_type.hpp
+core/geometry_type.hpp
+core/math_func.hpp
+core/mem_func.hpp
+core/overflowsafe_type.hpp
+core/random_func.hpp
+core/random_func.cpp
+core/smallvec_type.hpp
+core/sort_func.hpp
+
 # GUI Source Code
 aircraft_gui.cpp
 airport_gui.cpp
@@ -689,7 +695,6 @@
 misc/dbg_helpers.h
 misc/fixedsizearray.hpp
 misc/hashtable.hpp
-misc/smallvec.h
 misc/str.hpp
 misc/strapi.hpp
 
--- a/src/blitter/32bpp_anim.cpp	Sat Jun 21 13:35:29 2008 +0000
+++ b/src/blitter/32bpp_anim.cpp	Sat Jun 21 13:40:17 2008 +0000
@@ -4,6 +4,7 @@
 
 #include "../stdafx.h"
 #include "../core/alloc_func.hpp"
+#include "../core/math_func.hpp"
 #include "../gfx_func.h"
 #include "../zoom_func.h"
 #include "../debug.h"
@@ -291,20 +292,28 @@
 void Blitter_32bppAnim::PaletteAnimate(uint start, uint count)
 {
 	assert(!_screen_disable_anim);
-	uint8 *anim = this->anim_buf;
 
 	/* Never repaint the transparency pixel */
-	if (start == 0) start++;
+	if (start == 0) {
+		start++;
+		count--;
+	}
+
+	const uint8 *anim = this->anim_buf;
+	uint32 *dst = (uint32 *)_screen.dst_ptr;
 
 	/* Let's walk the anim buffer and try to find the pixels */
-	for (int y = 0; y < this->anim_buf_height; y++) {
-		for (int x = 0; x < this->anim_buf_width; x++) {
-			if (*anim >= start && *anim <= start + count) {
+	for (int y = this->anim_buf_height; y != 0 ; y--) {
+		for (int x = this->anim_buf_width; x != 0 ; x--) {
+			uint colour = *anim;
+			if (IsInsideBS(colour, start, count)) {
 				/* Update this pixel */
-				this->SetPixel(_screen.dst_ptr, x, y, *anim);
+				*dst = LookupColourInPalette(colour);
 			}
+			dst++;
 			anim++;
 		}
+		dst += _screen.pitch - this->anim_buf_width;
 	}
 
 	/* Make sure the backend redraws the whole screen */
--- a/src/blitter/32bpp_base.hpp	Sat Jun 21 13:35:29 2008 +0000
+++ b/src/blitter/32bpp_base.hpp	Sat Jun 21 13:40:17 2008 +0000
@@ -37,11 +37,10 @@
 
 	/**
 	 * Look up the colour in the current palette.
-	 **/
-	static inline uint32 LookupColourInPalette(uint8 index)
+	 */
+	static inline uint32 LookupColourInPalette(uint index)
 	{
-		if (index == 0) return 0x00000000; // Full transparent pixel */
-		return ComposeColour(0xFF, _cur_palette[index].r, _cur_palette[index].g, _cur_palette[index].b);
+		return _cur_palette[index];
 	}
 
 	/**
--- a/src/blitter/8bpp_optimized.cpp	Sat Jun 21 13:35:29 2008 +0000
+++ b/src/blitter/8bpp_optimized.cpp	Sat Jun 21 13:40:17 2008 +0000
@@ -14,10 +14,11 @@
 void Blitter_8bppOptimized::Draw(Blitter::BlitterParams *bp, BlitterMode mode, ZoomLevel zoom)
 {
 	/* Find the offset of this zoom-level */
-	uint offset = ((const uint8 *)bp->sprite)[(int)(zoom - ZOOM_LVL_BEGIN) * 2] | ((const byte *)bp->sprite)[(int)(zoom - ZOOM_LVL_BEGIN) * 2 + 1] << 8;
+	const SpriteData *sprite_src = (const SpriteData *)bp->sprite;
+	uint offset = sprite_src->offset[zoom];
 
 	/* Find where to start reading in the source sprite */
-	const uint8 *src = (const uint8 *)bp->sprite + offset;
+	const uint8 *src = sprite_src->data + offset;
 	uint8 *dst_line = (uint8 *)bp->dst + bp->top * bp->pitch + bp->left;
 
 	/* Skip over the top lines in the source image */
@@ -101,7 +102,7 @@
 Sprite *Blitter_8bppOptimized::Encode(SpriteLoader::Sprite *sprite, Blitter::AllocatorProc *allocator)
 {
 	/* Make memory for all zoom-levels */
-	uint memory = (int)(ZOOM_LVL_END - ZOOM_LVL_BEGIN) * sizeof(uint16);
+	uint memory = sizeof(SpriteData);
 
 	for (ZoomLevel i = ZOOM_LVL_BEGIN; i < ZOOM_LVL_END; i++) {
 		memory += UnScaleByZoom(sprite->height, i) * UnScaleByZoom(sprite->width, i);
@@ -109,15 +110,14 @@
 
 	/* We have no idea how much memory we really need, so just guess something */
 	memory *= 5;
-	byte *temp_dst = MallocT<byte>(memory);
-	byte *dst = &temp_dst[(ZOOM_LVL_END - ZOOM_LVL_BEGIN) * 2];
+	SpriteData *temp_dst = (SpriteData *)MallocT<byte>(memory);
+	byte *dst = temp_dst->data;
 
 	/* Make the sprites per zoom-level */
 	for (ZoomLevel i = ZOOM_LVL_BEGIN; i < ZOOM_LVL_END; i++) {
 		/* Store the index table */
-		uint index = dst - temp_dst;
-		temp_dst[i * 2] = index & 0xFF;
-		temp_dst[i * 2 + 1] = (index >> 8) & 0xFF;
+		uint offset = dst - temp_dst->data;
+		temp_dst->offset[i] = offset;
 
 		/* cache values, because compiler can't cache it */
 		int scaled_height = UnScaleByZoom(sprite->height, i);
@@ -179,7 +179,7 @@
 		}
 	}
 
-	uint size = dst - temp_dst;
+	uint size = dst - (byte *)temp_dst;
 
 	/* Safety check, to make sure we guessed the size correctly */
 	assert(size < memory);
--- a/src/blitter/8bpp_optimized.hpp	Sat Jun 21 13:35:29 2008 +0000
+++ b/src/blitter/8bpp_optimized.hpp	Sat Jun 21 13:40:17 2008 +0000
@@ -10,6 +10,11 @@
 
 class Blitter_8bppOptimized : public Blitter_8bppBase {
 public:
+	struct SpriteData {
+		uint32 offset[ZOOM_LVL_COUNT]; ///< offsets (from .data) to streams for different zoom levels
+		byte data[VARARRAY_SIZE];      ///< data, all zoomlevels
+	};
+
 	/* virtual */ void Draw(Blitter::BlitterParams *bp, BlitterMode mode, ZoomLevel zoom);
 	/* virtual */ Sprite *Encode(SpriteLoader::Sprite *sprite, Blitter::AllocatorProc *allocator);
 
--- a/src/blitter/factory.hpp	Sat Jun 21 13:35:29 2008 +0000
+++ b/src/blitter/factory.hpp	Sat Jun 21 13:40:17 2008 +0000
@@ -70,6 +70,13 @@
 	{
 		const char *default_blitter = "8bpp-optimized";
 
+#if defined(__APPLE__)
+		/* MacOS X 10.5 removed 8bpp fullscreen support.
+		 * Because of this we will pick 32bpp by default */
+		if (MacOSVersionIsAtLeast(10, 5, 0)) {
+			default_blitter = "32bpp-anim";
+		}
+#endif /* defined(__APPLE__) */
 		if (GetBlitters().size() == 0) return NULL;
 		const char *bname = (StrEmpty(name)) ? default_blitter : name;
 
--- a/src/bridge_gui.cpp	Sat Jun 21 13:35:29 2008 +0000
+++ b/src/bridge_gui.cpp	Sat Jun 21 13:40:17 2008 +0000
@@ -60,7 +60,7 @@
 class BuildBridgeWindow : public Window {
 private:
 	/* Runtime saved values */
-	static uint last_size;
+	static uint16 last_size;
 	static Listing last_sorting;
 
 	/* Constants for sorting the bridges */
@@ -132,9 +132,8 @@
 			this->vscroll.cap = 4;
 		} else {
 			/* Resize the bridge selection window if we used a bigger one the last time */
-			this->vscroll.cap = (this->vscroll.count > this->last_size) ? this->last_size : this->vscroll.count;
+			this->vscroll.cap = min(this->last_size, this->vscroll.count);
 			ResizeWindow(this, 0, (this->vscroll.cap - 4) * this->resize.step_height);
-			this->widget[BBSW_BRIDGE_LIST].data = (this->vscroll.cap << 8) + 1;
 		}
 
 		this->FindWindowPlacementAndResize(desc);
@@ -151,7 +150,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;
 
@@ -222,12 +221,12 @@
 		this->widget[BBSW_BRIDGE_LIST].data = (this->vscroll.cap << 8) + 1;
 		SetVScrollCount(this, this->bridges->Length());
 
-		this->last_size = this->vscroll.cap;
+		this->last_size = max(this->vscroll.cap, this->last_size);
 	}
 };
 
 /* Set the default size of the Build Bridge Window */
-uint BuildBridgeWindow::last_size = 4;
+uint16 BuildBridgeWindow::last_size = 4;
 /* Set the default sorting for the bridges */
 Listing BuildBridgeWindow::last_sorting = {false, 0};
 
--- a/src/core/endian_func.hpp	Sat Jun 21 13:35:29 2008 +0000
+++ b/src/core/endian_func.hpp	Sat Jun 21 13:40:17 2008 +0000
@@ -5,26 +5,11 @@
 #ifndef ENDIAN_FUNC_H
 #define ENDIAN_FUNC_H
 
+#include "endian_type.hpp"
 #include "bitmath_func.hpp"
 
-#if defined(ARM) || defined(__arm__) || defined(__alpha__)
-	#define OTTD_ALIGNMENT
-#endif
-
-/* Windows has always LITTLE_ENDIAN */
-#if defined(WIN32) || defined(__OS2__) || defined(WIN64)
-	#define TTD_LITTLE_ENDIAN
-#elif !defined(TESTING)
-	/* Else include endian[target/host].h, which has the endian-type, autodetected by the Makefile */
-	#if defined(STRGEN)
-		#include "endian_host.h"
-	#else
-		#include "endian_target.h"
-	#endif
-#endif /* WIN32 || __OS2__ || WIN64 */
-
 /* Setup alignment and conversion macros */
-#if defined(TTD_BIG_ENDIAN)
+#if TTD_ENDIAN == TTD_BIG_ENDIAN
 	#define FROM_BE16(x) (x)
 	#define FROM_BE32(x) (x)
 	#define TO_BE16(x)   (x)
@@ -46,7 +31,7 @@
 	#define TO_LE16(x)   (x)
 	#define TO_LE32(x)   (x)
 	#define TO_LE32X(x)  (x)
-#endif /* TTD_BIG_ENDIAN */
+#endif /* TTD_ENDIAN == TTD_BIG_ENDIAN */
 
 static inline uint16 ReadLE16Aligned(const void *x)
 {
@@ -55,11 +40,11 @@
 
 static inline uint16 ReadLE16Unaligned(const void *x)
 {
-#ifdef OTTD_ALIGNMENT
+#if OTTD_ALIGNMENT == 1
 	return ((const byte*)x)[0] | ((const byte*)x)[1] << 8;
 #else
 	return FROM_LE16(*(const uint16*)x);
-#endif
+#endif /* OTTD_ALIGNMENT == 1 */
 }
 
 #endif /* ENDIAN_FUNC_HPP */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/core/endian_type.hpp	Sat Jun 21 13:40:17 2008 +0000
@@ -0,0 +1,29 @@
+/* $Id$ */
+
+/** @file endian_type.hpp Definition of various endian-dependant macros. */
+
+#ifndef ENDIAN_TYPE_H
+#define ENDIAN_TYPE_H
+
+#if defined(ARM) || defined(__arm__) || defined(__alpha__)
+	#define OTTD_ALIGNMENT 1
+#else
+	#define OTTD_ALIGNMENT 0
+#endif
+
+#define TTD_LITTLE_ENDIAN 0
+#define TTD_BIG_ENDIAN 1
+
+/* Windows has always LITTLE_ENDIAN */
+#if defined(WIN32) || defined(__OS2__) || defined(WIN64)
+	#define TTD_ENDIAN TTD_LITTLE_ENDIAN
+#elif !defined(TESTING)
+	/* Else include endian[target/host].h, which has the endian-type, autodetected by the Makefile */
+	#if defined(STRGEN)
+		#include "endian_host.h"
+	#else
+		#include "endian_target.h"
+	#endif
+#endif /* WIN32 || __OS2__ || WIN64 */
+
+#endif /* ENDIAN_TYPE_HPP */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/core/mem_func.hpp	Sat Jun 21 13:40:17 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/smallvec_type.hpp	Sat Jun 21 13:40:17 2008 +0000
@@ -0,0 +1,165 @@
+/* $Id$ */
+
+/** @file smallvec_type.hpp Simple vector class that allows allocating an item without the need to copy this->data needlessly. */
+
+#ifndef SMALLVEC_TYPE_HPP
+#define SMALLVEC_TYPE_HPP
+
+#include "alloc_func.hpp"
+#include "math_func.hpp"
+
+/**
+ * Simple vector template class.
+ *
+ * @note There are no asserts in the class so you have
+ *       to care about that you grab an item which is
+ *       inside the list.
+ *
+ * @param T The type of the items stored
+ * @param S The steps of allocation
+ */
+template <typename T, uint S>
+class SmallVector {
+protected:
+	T *data;       ///< The pointer to the first item
+	uint items;    ///< The number of items stored
+	uint capacity; ///< The avalible space for storing items
+
+public:
+	SmallVector() : data(NULL), items(0), capacity(0) { }
+
+	~SmallVector()
+	{
+		free(this->data);
+	}
+
+	/**
+	 * Remove all items from the list.
+	 */
+	void Clear()
+	{
+		/* In fact we just reset the item counter avoiding the need to
+		 * probably reallocate the same amount of memory the list was
+		 * previously using. */
+		this->items = 0;
+	}
+
+	/**
+	 * Compact the list down to the smallest block size boundary.
+	 */
+	void Compact()
+	{
+		uint capacity = Align(this->items, S);
+		if (capacity >= this->capacity) return;
+
+		this->capacity = capacity;
+		this->data = ReallocT(this->data, this->capacity);
+	}
+
+	/**
+	 * Append an item and return it.
+	 */
+	T *Append()
+	{
+		if (this->items == this->capacity) {
+			this->capacity += S;
+			this->data = ReallocT(this->data, this->capacity);
+		}
+
+		return &this->data[this->items++];
+	}
+
+	/**
+	 * Get the number of items in the list.
+	 */
+	uint Length() const
+	{
+		return this->items;
+	}
+
+	/**
+	 * Get the pointer to the first item (const)
+	 *
+	 * @return the pointer to the first item
+	 */
+	const T *Begin() const
+	{
+		return this->data;
+	}
+
+	/**
+	 * Get the pointer to the first item
+	 *
+	 * @return the pointer to the first item
+	 */
+	T *Begin()
+	{
+		return this->data;
+	}
+
+	/**
+	 * Get the pointer behind the last valid item (const)
+	 *
+	 * @return the pointer behind the last valid item
+	 */
+	const T *End() const
+	{
+		return &this->data[this->items];
+	}
+
+	/**
+	 * Get the pointer behind the last valid item
+	 *
+	 * @return the pointer behind the last valid item
+	 */
+	T *End()
+	{
+		return &this->data[this->items];
+	}
+
+	/**
+	 * Get the pointer to item "number" (const)
+	 *
+	 * @param index the position of the item
+	 * @return the pointer to the item
+	 */
+	const T *Get(uint index) const
+	{
+		return &this->data[index];
+	}
+
+	/**
+	 * Get the pointer to item "number"
+	 *
+	 * @param index the position of the item
+	 * @return the pointer to the item
+	 */
+	T *Get(uint index)
+	{
+		return &this->data[index];
+	}
+
+	/**
+	 * Get item "number" (const)
+	 *
+	 * @param index the positon of the item
+	 * @return the item
+	 */
+	const T &operator[](uint index) const
+	{
+		return this->data[index];
+	}
+
+	/**
+	 * Get item "number"
+	 *
+	 * @param index the positon of the item
+	 * @return the item
+	 */
+	T &operator[](uint index)
+	{
+		return this->data[index];
+	}
+};
+
+#endif /* SMALLVEC_TYPE_HPP */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/core/sort_func.hpp	Sat Jun 21 13:40:17 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/date.cpp	Sat Jun 21 13:35:29 2008 +0000
+++ b/src/date.cpp	Sat Jun 21 13:40:17 2008 +0000
@@ -77,11 +77,6 @@
 	ACCUM_SEP, ACCUM_OCT, ACCUM_NOV, ACCUM_DEC,
 };
 
-static inline bool IsLeapYear(Year yr)
-{
-	return yr % 4 == 0 && (yr % 100 != 0 || yr % 400 == 0);
-}
-
 /**
  * Converts a Date to a Year, Month & Day.
  * @param date the date to convert from
--- a/src/date_func.h	Sat Jun 21 13:35:29 2008 +0000
+++ b/src/date_func.h	Sat Jun 21 13:40:17 2008 +0000
@@ -16,4 +16,9 @@
 void ConvertDateToYMD(Date date, YearMonthDay *ymd);
 Date ConvertYMDToDate(Year year, Month month, Day day);
 
+static inline bool IsLeapYear(Year yr)
+{
+	return yr % 4 == 0 && (yr % 100 != 0 || yr % 400 == 0);
+}
+
 #endif /* DATE_FUNC_H */
--- a/src/date_type.h	Sat Jun 21 13:35:29 2008 +0000
+++ b/src/date_type.h	Sat Jun 21 13:40:17 2008 +0000
@@ -46,8 +46,8 @@
 
 struct YearMonthDay {
 	Year  year;
-	Month month;
-	Day   day;
+	Month month; ///< 0 - 11
+	Day   day;   ///< 1 - 31
 };
 
 static const Year INVALID_YEAR = -1;
--- a/src/driver.cpp	Sat Jun 21 13:35:29 2008 +0000
+++ b/src/driver.cpp	Sat Jun 21 13:40:17 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];
--- a/src/endian_check.cpp	Sat Jun 21 13:35:29 2008 +0000
+++ b/src/endian_check.cpp	Sat Jun 21 13:40:17 2008 +0000
@@ -12,6 +12,21 @@
 #include <stdio.h>
 #include <string.h>
 
+/** Supported endian types */
+enum Endian {
+	ENDIAN_LITTLE, ///< little endian
+	ENDIAN_BIG     ///< big endian
+};
+
+/**
+ * Shortcut to printf("#define TTD_ENDIAN TTD_*_ENDIAN")
+ * @param endian endian type to define
+ */
+static inline void printf_endian(Endian endian)
+{
+	printf("#define TTD_ENDIAN %s\n", endian == ENDIAN_LITTLE ? "TTD_LITTLE_ENDIAN" : "TTD_BIG_ENDIAN");
+}
+
 /**
  * Main call of the endian_check program
  * @param argc argument count
@@ -30,23 +45,23 @@
 	printf("#ifndef ENDIAN_H\n#define ENDIAN_H\n");
 
 	if (force_LE == 1) {
-		printf("#define TTD_LITTLE_ENDIAN\n");
+		printf_endian(ENDIAN_LITTLE);
 	} else if (force_BE == 1) {
-		printf("#define TTD_BIG_ENDIAN\n");
+		printf_endian(ENDIAN_BIG);
 	} else if (force_PREPROCESSOR == 1) {
 		/* Support for universal binaries on OSX
 		 * Universal binaries supports both PPC and x86
 		 * If a compiler for OSX gets this setting, it will always pick the correct endian and no test is needed
 		 */
 		printf("#ifdef __BIG_ENDIAN__\n");
-		printf("#define TTD_BIG_ENDIAN\n");
+		printf_endian(ENDIAN_BIG);
 		printf("#else\n");
-		printf("#define TTD_LITTLE_ENDIAN\n");
+		printf_endian(ENDIAN_LITTLE);
 		printf("#endif\n");
 	} else if (*(short*)endian_test == 1 ) {
-		printf("#define TTD_LITTLE_ENDIAN\n");
+		printf_endian(ENDIAN_LITTLE);
 	} else {
-		printf("#define TTD_BIG_ENDIAN\n");
+		printf_endian(ENDIAN_BIG);
 	}
 	printf("#endif\n");
 
--- a/src/engine_gui.cpp	Sat Jun 21 13:35:29 2008 +0000
+++ b/src/engine_gui.cpp	Sat Jun 21 13:40:17 2008 +0000
@@ -16,6 +16,7 @@
 #include "newgrf_engine.h"
 #include "strings_func.h"
 #include "engine_gui.h"
+#include "articulated_vehicles.h"
 
 #include "table/strings.h"
 #include "table/sprites.h"
@@ -117,21 +118,34 @@
 	AllocateWindowDescFront<EnginePreviewWindow>(&_engine_preview_desc, engine);
 }
 
+static uint GetTotalCapacityOfArticulatedParts(EngineID engine, VehicleType type)
+{
+	uint total = 0;
+
+	uint16 *cap = GetCapacityOfArticulatedParts(engine, type);
+	for (uint c = 0; c < NUM_CARGO; c++) {
+		total += cap[c];
+	}
+
+	return total;
+}
+
 static void DrawTrainEngineInfo(EngineID engine, int x, int y, int maxw)
 {
 	const RailVehicleInfo *rvi = RailVehInfo(engine);
 	int multihead = (rvi->railveh_type == RAILVEH_MULTIHEAD) ? 1 : 0;
 
-	SetDParam(0, (_price.build_railvehicle >> 3) * rvi->base_cost >> 5);
-	SetDParam(2, rvi->max_speed * 10 / 16);
-	SetDParam(3, rvi->power << multihead);
-	SetDParam(1, rvi->weight << multihead);
+	SetDParam(0, (_price.build_railvehicle >> 3) * GetEngineProperty(engine, 0x17, rvi->base_cost) >> 5);
+	SetDParam(2, GetEngineProperty(engine, 0x09, rvi->max_speed) * 10 / 16);
+	SetDParam(3, GetEngineProperty(engine, 0x0B, rvi->power) << multihead);
+	SetDParam(1, GetEngineProperty(engine, 0x16, rvi->weight) << multihead);
 
-	SetDParam(4, rvi->running_cost * GetPriceByIndex(rvi->running_cost_class) >> 8 << multihead);
+	SetDParam(4, GetEngineProperty(engine, 0x0D, rvi->running_cost) * GetPriceByIndex(rvi->running_cost_class) >> 8 << multihead);
 
-	if (rvi->capacity != 0) {
+	uint capacity = GetTotalCapacityOfArticulatedParts(engine, VEH_TRAIN);
+	if (capacity != 0) {
 		SetDParam(5, rvi->cargo_type);
-		SetDParam(6, rvi->capacity << multihead);
+		SetDParam(6, capacity << multihead);
 	} else {
 		SetDParam(5, CT_INVALID);
 	}
@@ -141,11 +155,11 @@
 static void DrawAircraftEngineInfo(EngineID engine, int x, int y, int maxw)
 {
 	const AircraftVehicleInfo *avi = AircraftVehInfo(engine);
-	SetDParam(0, (_price.aircraft_base >> 3) * avi->base_cost >> 5);
+	SetDParam(0, (_price.aircraft_base >> 3) * GetEngineProperty(engine, 0x0B, avi->base_cost) >> 5);
 	SetDParam(1, avi->max_speed * 10 / 16);
 	SetDParam(2, avi->passenger_capacity);
 	SetDParam(3, avi->mail_capacity);
-	SetDParam(4, avi->running_cost * _price.aircraft_running >> 8);
+	SetDParam(4, GetEngineProperty(engine, 0x0E, avi->running_cost) * _price.aircraft_running >> 8);
 
 	DrawStringMultiCenter(x, y, STR_A02E_COST_MAX_SPEED_CAPACITY, maxw);
 }
@@ -154,11 +168,11 @@
 {
 	const RoadVehicleInfo *rvi = RoadVehInfo(engine);
 
-	SetDParam(0, (_price.roadveh_base >> 3) * rvi->base_cost >> 5);
+	SetDParam(0, (_price.roadveh_base >> 3) * GetEngineProperty(engine, 0x11, rvi->base_cost) >> 5);
 	SetDParam(1, rvi->max_speed * 10 / 32);
 	SetDParam(2, rvi->running_cost * GetPriceByIndex(rvi->running_cost_class) >> 8);
 	SetDParam(3, rvi->cargo_type);
-	SetDParam(4, rvi->capacity);
+	SetDParam(4, GetTotalCapacityOfArticulatedParts(engine, VEH_ROAD));
 
 	DrawStringMultiCenter(x, y, STR_902A_COST_SPEED_RUNNING_COST, maxw);
 }
@@ -166,11 +180,11 @@
 static void DrawShipEngineInfo(EngineID engine, int x, int y, int maxw)
 {
 	const ShipVehicleInfo *svi = ShipVehInfo(engine);
-	SetDParam(0, svi->base_cost * (_price.ship_base >> 3) >> 5);
-	SetDParam(1, svi->max_speed * 10 / 32);
+	SetDParam(0, GetEngineProperty(engine, 0x0A, svi->base_cost) * (_price.ship_base >> 3) >> 5);
+	SetDParam(1, GetEngineProperty(engine, 0x0B, svi->max_speed) * 10 / 32);
 	SetDParam(2, svi->cargo_type);
-	SetDParam(3, svi->capacity);
-	SetDParam(4, svi->running_cost * _price.ship_running >> 8);
+	SetDParam(3, GetEngineProperty(engine, 0x0D, svi->capacity));
+	SetDParam(4, GetEngineProperty(engine, 0x0F, svi->running_cost) * _price.ship_running >> 8);
 	DrawStringMultiCenter(x, y, STR_982E_COST_MAX_SPEED_CAPACITY, maxw);
 }
 
--- a/src/fios.h	Sat Jun 21 13:35:29 2008 +0000
+++ b/src/fios.h	Sat Jun 21 13:40:17 2008 +0000
@@ -6,7 +6,7 @@
 #define FIOS_H
 
 #include "strings_type.h"
-#include "misc/smallvec.h"
+#include "core/smallvec_type.hpp"
 
 enum {
 	/**
--- a/src/gamelog.cpp	Sat Jun 21 13:35:29 2008 +0000
+++ b/src/gamelog.cpp	Sat Jun 21 13:40:17 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/gfx.cpp	Sat Jun 21 13:35:29 2008 +0000
+++ b/src/gfx.cpp	Sat Jun 21 13:40:17 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"
@@ -1312,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	Sat Jun 21 13:35:29 2008 +0000
+++ b/src/gfx_func.h	Sat Jun 21 13:40:17 2008 +0000
@@ -60,9 +60,9 @@
 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 Colour _cur_palette[256];
+extern Dimension _resolutions[32];
+extern Dimension _cur_resolution;
+extern Colour _cur_palette[256]; ///< Current palette. Entry 0 has to be always fully transparent!
 
 void HandleKeypress(uint32 key);
 void HandleCtrlChanged();
--- a/src/gfx_type.h	Sat Jun 21 13:35:29 2008 +0000
+++ b/src/gfx_type.h	Sat Jun 21 13:40:17 2008 +0000
@@ -5,6 +5,7 @@
 #ifndef GFX_TYPE_H
 #define GFX_TYPE_H
 
+#include "core/endian_type.hpp"
 #include "core/enum_type.hpp"
 #include "core/geometry_type.hpp"
 #include "zoom_type.h"
@@ -142,9 +143,13 @@
 };
 
 struct Colour {
-	byte r;
-	byte g;
-	byte b;
+#if TTD_ENDIAN == TTD_BIG_ENDIAN
+	uint8 a, r, g, b; ///< colour channels in BE order
+#else
+	uint8 b, g, r, a; ///< colour channels in LE order
+#endif /* TTD_ENDIAN == TTD_BIG_ENDIAN */
+
+	operator uint32 () { return *(uint32 *)this; }
 };
 
 enum FontSize {
--- a/src/graph_gui.cpp	Sat Jun 21 13:35:29 2008 +0000
+++ b/src/graph_gui.cpp	Sat Jun 21 13:40:17 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	Sat Jun 21 13:35:29 2008 +0000
+++ b/src/group_gui.cpp	Sat Jun 21 13:40:17 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 = this->vehicle_sorter_names[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, this->vehicle_sorter_names, 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/lang/english.txt	Sat Jun 21 13:35:29 2008 +0000
+++ b/src/lang/english.txt	Sat Jun 21 13:40:17 2008 +0000
@@ -1292,6 +1292,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})
@@ -3163,6 +3166,7 @@
 STR_NEWGRF_ERROR_OTTD_VERSION_NUMBER                            :{STRING} requires OpenTTD version {STRING} or better.
 STR_NEWGRF_ERROR_AFTER_TRANSLATED_FILE                          :the GRF file it was designed to translate
 STR_NEWGRF_ERROR_TOO_MANY_NEWGRFS_LOADED                        :Too many NewGRFs are loaded.
+STR_NEWGRF_ERROR_STATIC_GRF_CAUSES_DESYNC                       :Loading {STRING} as static NewGRF with {STRING} could cause desyncs.
 
 STR_NEWGRF_ADD                                                  :{BLACK}Add
 STR_NEWGRF_ADD_TIP                                              :{BLACK}Add a NewGRF file to the list
--- a/src/main_gui.cpp	Sat Jun 21 13:35:29 2008 +0000
+++ b/src/main_gui.cpp	Sat Jun 21 13:40:17 2008 +0000
@@ -447,8 +447,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/minilzo.cpp	Sat Jun 21 13:35:29 2008 +0000
+++ b/src/minilzo.cpp	Sat Jun 21 13:40:17 2008 +0000
@@ -230,9 +230,9 @@
 #  error "LZO_ALIGNED_OK_4 must not be defined on this system"
 #endif
 
-#define LZO_LITTLE_ENDIAN	   1234
-#define LZO_BIG_ENDIAN		  4321
-#define LZO_PDP_ENDIAN		  3412
+#define LZO_LITTLE_ENDIAN 1234
+#define LZO_BIG_ENDIAN    4321
+#define LZO_PDP_ENDIAN    3412
 
 #if !defined(LZO_BYTE_ORDER)
 #  if defined(MFX_BYTE_ORDER)
--- a/src/misc/blob.hpp	Sat Jun 21 13:35:29 2008 +0000
+++ b/src/misc/blob.hpp	Sat Jun 21 13:40:17 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/misc/smallvec.h	Sat Jun 21 13:35:29 2008 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,109 +0,0 @@
-/* $Id$ */
-
-/** @file smallvec.h Simple vector class that allows allocating an item without the need to copy this->data needlessly. */
-
-#ifndef SMALLVEC_H
-#define SMALLVEC_H
-
-#include "../core/alloc_func.hpp"
-#include "../core/math_func.hpp"
-
-template <typename T, uint S>
-struct SmallVector {
-	T *data;
-	uint items;
-	uint capacity;
-
-	SmallVector() : data(NULL), items(0), capacity(0) { }
-
-	~SmallVector()
-	{
-		free(this->data);
-	}
-
-	/**
-	 * Remove all items from the list.
-	 */
-	void Clear()
-	{
-		/* In fact we just reset the item counter avoiding the need to
-		 * probably reallocate the same amount of memory the list was
-		 * previously using. */
-		this->items = 0;
-	}
-
-	/**
-	 * Compact the list down to the smallest block size boundary.
-	 */
-	void Compact()
-	{
-		uint capacity = Align(this->items, S);
-		if (capacity >= this->capacity) return;
-
-		this->capacity = capacity;
-		this->data = ReallocT(this->data, this->capacity);
-	}
-
-	/**
-	 * Append an item and return it.
-	 */
-	T *Append()
-	{
-		if (this->items == this->capacity) {
-			this->capacity += S;
-			this->data = ReallocT(this->data, this->capacity);
-		}
-
-		return &this->data[this->items++];
-	}
-
-	/**
-	 * Get the number of items in the list.
-	 */
-	uint Length() const
-	{
-		return this->items;
-	}
-
-	const T *Begin() const
-	{
-		return this->data;
-	}
-
-	T *Begin()
-	{
-		return this->data;
-	}
-
-	const T *End() const
-	{
-		return &this->data[this->items];
-	}
-
-	T *End()
-	{
-		return &this->data[this->items];
-	}
-
-	const T *Get(uint index) const
-	{
-		return &this->data[index];
-	}
-
-	T *Get(uint index)
-	{
-		return &this->data[index];
-	}
-
-	const T &operator[](uint index) const
-	{
-		return this->data[index];
-	}
-
-	T &operator[](uint index)
-	{
-		return this->data[index];
-	}
-};
-
-#endif /* SMALLVEC_H */
--- a/src/newgrf.cpp	Sat Jun 21 13:35:29 2008 +0000
+++ b/src/newgrf.cpp	Sat Jun 21 13:40:17 2008 +0000
@@ -46,6 +46,7 @@
 #include "road_func.h"
 #include "player_base.h"
 #include "settings_type.h"
+#include "network/network.h"
 #include "map_func.h"
 #include <map>
 
@@ -3565,9 +3566,13 @@
 			*value = Clamp(_cur_year, ORIGINAL_BASE_YEAR, ORIGINAL_MAX_YEAR) - ORIGINAL_BASE_YEAR;
 			return true;
 
-		case 0x02: // current month
-			*value = _cur_month;
+		case 0x02: { // detailed date information: month of year (bit 0-7), day of month (bit 8-12), leap year (bit 15), day of year (bit 16-24)
+			YearMonthDay ymd;
+			ConvertDateToYMD(_date, &ymd);
+			Date start_of_year = ConvertYMDToDate(ymd.year, 0, 1);
+			*value = ymd.month | (ymd.day - 1) << 8 | (IsLeapYear(ymd.year) ? 1 << 15 : 0) | (_date - start_of_year) << 16;
 			return true;
+		}
 
 		case 0x03: // current climate, 0=temp, 1=arctic, 2=trop, 3=toyland
 			*value = _settings_game.game_creation.landscape;
@@ -3800,6 +3805,29 @@
 	}
 }
 
+/**
+ * Disable a static NewGRF when it is influencing another (non-static)
+ * NewGRF as this could cause desyncs.
+ *
+ * We could just tell the NewGRF querying that the file doesn't exist,
+ * but that might give unwanted results. Disabling the NewGRF gives the
+ * best result as no NewGRF author can complain about that.
+ * @param c the NewGRF to disable.
+ */
+static void DisableStaticNewGRFInfluencingNonStaticNewGRFs(GRFConfig *c)
+{
+	if (c->error != NULL) {
+		free(c->error->custom_message);
+		free(c->error->data);
+		free(c->error);
+	}
+	c->status = GCS_DISABLED;
+	c->error  = CallocT<GRFError>(1);
+	c->error->data = strdup(_cur_grfconfig->name);
+	c->error->severity = STR_NEWGRF_ERROR_MSG_FATAL;
+	c->error->message  = STR_NEWGRF_ERROR_STATIC_GRF_CAUSES_DESYNC;
+}
+
 /* Action 0x07 */
 /* Action 0x09 */
 static void SkipIf(byte *buf, size_t len)
@@ -3853,7 +3881,12 @@
 	if (param == 0x88 && condtype != 0x0B && condtype != 0x0C) {
 		/* GRF ID checks */
 
-		const GRFConfig *c = GetGRFConfig(cond_val);
+		GRFConfig *c = GetGRFConfig(cond_val);
+
+		if (c != NULL && HasBit(c->flags, GCF_STATIC) && !HasBit(_cur_grfconfig->flags, GCF_STATIC) && c->status != GCS_DISABLED && _networking) {
+			DisableStaticNewGRFInfluencingNonStaticNewGRFs(c);
+			c = NULL;
+		}
 
 		if (condtype != 10 && c == NULL) {
 			grfmsg(7, "SkipIf: GRFID 0x%08X unknown, skipping test", BSWAP32(cond_val));
@@ -4455,7 +4488,12 @@
 		} else {
 			/* Read another GRF File's parameter */
 			const GRFFile *file = GetFileByGRFID(data);
-			if (file == NULL || src1 >= file->param_end) {
+			GRFConfig *c = GetGRFConfig(data);
+			if (c != NULL && HasBit(c->status, GCF_STATIC) && !HasBit(_cur_grfconfig->status, GCF_STATIC) && _networking) {
+				/* Disable the read GRF if it is a static NewGRF. */
+				DisableStaticNewGRFInfluencingNonStaticNewGRFs(c);
+				src1 = 0;
+			} else if (file == NULL || src1 >= file->param_end || (c != NULL && c->status == GCS_DISABLED)) {
 				src1 = 0;
 			} else {
 				src1 = file->param[src1];
--- a/src/newgrf_house.cpp	Sat Jun 21 13:35:29 2008 +0000
+++ b/src/newgrf_house.cpp	Sat Jun 21 13:40:17 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);
 	}
@@ -324,15 +330,15 @@
 
 	if (GB(image, 0, SPRITE_WIDTH) != 0) DrawGroundSprite(image, pal);
 
-	/* End now, if houses are invisible */
-	if (IsInvisibilitySet(TO_HOUSES)) return;
-
 	foreach_draw_tile_seq(dtss, dts->seq) {
 		if (GB(dtss->image.sprite, 0, SPRITE_WIDTH) == 0) continue;
 
 		image = dtss->image.sprite;
 		pal   = dtss->image.pal;
 
+		/* Stop drawing sprite sequence once we meet a sprite that doesn't have to be opaque */
+		if (IsInvisibilitySet(TO_HOUSES) && !HasBit(image, SPRITE_MODIFIER_OPAQUE)) return;
+
 		if (IS_CUSTOM_SPRITE(image)) image += stage;
 
 		if ((HasBit(image, SPRITE_MODIFIER_OPAQUE) || !IsTransparencySet(TO_HOUSES)) && HasBit(image, PALETTE_MODIFIER_COLOR)) {
--- a/src/newgrf_industrytiles.cpp	Sat Jun 21 13:35:29 2008 +0000
+++ b/src/newgrf_industrytiles.cpp	Sat Jun 21 13:40:17 2008 +0000
@@ -187,15 +187,15 @@
 
 	if (GB(image, 0, SPRITE_WIDTH) != 0) DrawGroundSprite(image, pal);
 
-	/* End now if industries are invisible */
-	if (IsInvisibilitySet(TO_INDUSTRIES)) return;
-
 	foreach_draw_tile_seq(dtss, dts->seq) {
 		if (GB(dtss->image.sprite, 0, SPRITE_WIDTH) == 0) continue;
 
 		image = dtss->image.sprite;
 		pal   = dtss->image.pal;
 
+		/* Stop drawing sprite sequence once we meet a sprite that doesn't have to be opaque */
+		if (IsInvisibilitySet(TO_INDUSTRIES) && !HasBit(image, SPRITE_MODIFIER_OPAQUE)) return;
+
 		if (IS_CUSTOM_SPRITE(image)) image += stage;
 
 		if (HasBit(image, PALETTE_MODIFIER_COLOR)) {
--- a/src/newgrf_spritegroup.cpp	Sat Jun 21 13:35:29 2008 +0000
+++ b/src/newgrf_spritegroup.cpp	Sat Jun 21 13:40:17 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/openttd.cpp	Sat Jun 21 13:35:29 2008 +0000
+++ b/src/openttd.cpp	Sat Jun 21 13:40:17 2008 +0000
@@ -292,7 +292,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) {
@@ -300,8 +300,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()
@@ -386,7 +386,7 @@
 	int i;
 	const char *optformat;
 	char musicdriver[32], sounddriver[32], videodriver[32], blitter[32], ai[32];
-	int resolution[2] = {0, 0};
+	Dimension resolution = {0, 0};
 	Year startyear = INVALID_YEAR;
 	uint generation_seed = GENERATE_NEW_SEED;
 	bool save_config = true;
@@ -452,7 +452,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)
@@ -507,14 +507,14 @@
 	if (!StrEmpty(videodriver)) ttd_strlcpy(_ini_videodriver, videodriver, sizeof(_ini_videodriver));
 	if (!StrEmpty(blitter))     ttd_strlcpy(_ini_blitter, blitter, sizeof(_ini_blitter));
 	if (!StrEmpty(ai)) AI_ForceAI(ai);
-	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_cmd.cpp	Sat Jun 21 13:35:29 2008 +0000
+++ b/src/order_cmd.cpp	Sat Jun 21 13:40:17 2008 +0000
@@ -1644,7 +1644,7 @@
  * @param order the order the vehicle currently has
  * @param v the vehicle to update
  */
-static bool UpdateOrderDest(Vehicle *v, const Order *order)
+static bool UpdateOrderDest(Vehicle *v, const Order *order, int conditional_depth = 0)
 {
 	switch (order->GetType()) {
 		case OT_GOTO_STATION:
@@ -1691,7 +1691,13 @@
 			} else {
 				v->cur_order_index++;
 			}
-			return false;
+
+			if (conditional_depth > v->num_orders) return false;
+
+			/* Get the current order */
+			if (v->cur_order_index >= v->num_orders) v->cur_order_index = 0;
+
+			return UpdateOrderDest(v, GetVehicleOrder(v, v->cur_order_index), conditional_depth + 1);
 		}
 
 		default:
--- a/src/os/macosx/splash.cpp	Sat Jun 21 13:35:29 2008 +0000
+++ b/src/os/macosx/splash.cpp	Sat Jun 21 13:40:17 2008 +0000
@@ -124,11 +124,13 @@
 				}
 
 				for (i = 0; i < num_palette; i++) {
+					_cur_palette[i].a = i == 0 ? 0 : 0xff;
 					_cur_palette[i].r = palette[i].red;
 					_cur_palette[i].g = palette[i].green;
 					_cur_palette[i].b = palette[i].blue;
 				}
 
+				_cur_palette[0xff].a = 0xff;
 				_cur_palette[0xff].r = 0;
 				_cur_palette[0xff].g = 0;
 				_cur_palette[0xff].b = 0;
--- a/src/players.cpp	Sat Jun 21 13:35:29 2008 +0000
+++ b/src/players.cpp	Sat Jun 21 13:40:17 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"
@@ -816,6 +817,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 */
@@ -1033,12 +1033,13 @@
 {
 	const Player* p;
 	const Player* pl[MAX_PLAYERS];
-	size_t count = 0;
+	uint count = 0;
 	int8 player = -1;
 
 	/* 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;
--- a/src/rail_cmd.cpp	Sat Jun 21 13:35:29 2008 +0000
+++ b/src/rail_cmd.cpp	Sat Jun 21 13:40:17 2008 +0000
@@ -1846,13 +1846,13 @@
 
 		if (HasCatenaryDrawn(GetRailType(ti->tile))) DrawCatenary(ti);
 
-		/* End now if buildings are invisible */
-		if (IsInvisibilitySet(TO_BUILDINGS)) return;
-
 		foreach_draw_tile_seq(dtss, dts->seq) {
 			SpriteID image = dtss->image.sprite;
 			SpriteID pal;
 
+			/* Stop drawing sprite sequence once we meet a sprite that doesn't have to be opaque */
+			if (IsInvisibilitySet(TO_BUILDINGS) && !HasBit(image, SPRITE_MODIFIER_OPAQUE)) return;
+
 			/* Unlike stations, our default waypoint has no variation for
 			 * different railtype, so don't use the railtype offset if
 			 * no relocation is set */
--- a/src/roadveh_cmd.cpp	Sat Jun 21 13:35:29 2008 +0000
+++ b/src/roadveh_cmd.cpp	Sat Jun 21 13:40:17 2008 +0000
@@ -1737,7 +1737,7 @@
 				RoadStopType type = IsCargoInClass(v->cargo_type, CC_PASSENGERS) ? ROADSTOP_BUS : ROADSTOP_TRUCK;
 
 				/* Check if next inline bay is free */
-				if (IsDriveThroughStopTile(next_tile) && (GetRoadStopType(next_tile) == type)) {
+				if (IsDriveThroughStopTile(next_tile) && (GetRoadStopType(next_tile) == type) && GetStationIndex(v->tile) == GetStationIndex(next_tile)) {
 					RoadStop *rs_n = GetRoadStopByTile(next_tile, type);
 
 					if (rs_n->IsFreeBay(HasBit(v->u.road.state, RVS_USING_SECOND_BAY))) {
--- a/src/screenshot.cpp	Sat Jun 21 13:35:29 2008 +0000
+++ b/src/screenshot.cpp	Sat Jun 21 13:40:17 2008 +0000
@@ -247,12 +247,12 @@
 		sig_bit.gray  = 8;
 		png_set_sBIT(png_ptr, info_ptr, &sig_bit);
 
-#ifdef TTD_LITTLE_ENDIAN
+#if TTD_ENDIAN == TTD_LITTLE_ENDIAN
 		png_set_bgr(png_ptr);
 		png_set_filler(png_ptr, 0, PNG_FILLER_AFTER);
 #else
 		png_set_filler(png_ptr, 0, PNG_FILLER_BEFORE);
-#endif
+#endif /* TTD_ENDIAN == TTD_LITTLE_ENDIAN */
 	}
 
 	/* use by default 64k temp memory */
@@ -428,20 +428,15 @@
 		return false;
 	}
 
-	if (sizeof(*palette) == 3) {
-		success = fwrite(palette, 256 * sizeof(*palette), 1, f) == 1;
-	} else {
-		/* If the palette is word-aligned, copy it to a temporary byte array */
-		byte tmp[256 * 3];
-		uint i;
+	/* Palette is word-aligned, copy it to a temporary byte array */
+	byte tmp[256 * 3];
 
-		for (i = 0; i < 256; i++) {
-			tmp[i * 3 + 0] = palette[i].r;
-			tmp[i * 3 + 1] = palette[i].g;
-			tmp[i * 3 + 2] = palette[i].b;
-		}
-		success = fwrite(tmp, sizeof(tmp), 1, f) == 1;
+	for (uint i = 0; i < 256; i++) {
+		tmp[i * 3 + 0] = palette[i].r;
+		tmp[i * 3 + 1] = palette[i].g;
+		tmp[i * 3 + 2] = palette[i].b;
 	}
+	success = fwrite(tmp, sizeof(tmp), 1, f) == 1;
 
 	fclose(f);
 
--- a/src/settings.cpp	Sat Jun 21 13:35:29 2008 +0000
+++ b/src/settings.cpp	Sat Jun 21 13:40:17 2008 +0000
@@ -1496,7 +1496,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	Sat Jun 21 13:35:29 2008 +0000
+++ b/src/settings_gui.cpp	Sat Jun 21 13:40:17 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/signal.cpp	Sat Jun 21 13:35:29 2008 +0000
+++ b/src/signal.cpp	Sat Jun 21 13:40:17 2008 +0000
@@ -298,6 +298,7 @@
 				}
 
 				if (GetRailTileType(tile) == RAIL_TILE_WAYPOINT) {
+					if (GetWaypointAxis(tile) != DiagDirToAxis(enterdir)) continue;
 					if (!(flags & SF_TRAIN) && VehicleFromPos(tile, NULL, &TrainOnTileEnum)) flags |= SF_TRAIN;
 					tile += TileOffsByDiagDir(exitdir);
 					/* enterdir and exitdir stay the same */
--- a/src/sortlist_type.h	Sat Jun 21 13:35:29 2008 +0000
+++ b/src/sortlist_type.h	Sat Jun 21 13:40:17 2008 +0000
@@ -7,7 +7,9 @@
 
 #include "core/enum_type.hpp"
 #include "core/bitmath_func.hpp"
-#include "misc/smallvec.h"
+#include "core/mem_func.hpp"
+#include "core/sort_func.hpp"
+#include "core/smallvec_type.hpp"
 #include "date_type.h"
 
 enum SortListFlags {
@@ -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/sound.cpp	Sat Jun 21 13:35:29 2008 +0000
+++ b/src/sound.cpp	Sat Jun 21 13:40:17 2008 +0000
@@ -167,7 +167,7 @@
 
 
 static const byte _vol_factor_by_zoom[] = {255, 190, 134, 87};
-assert_compile(lengthof(_vol_factor_by_zoom) == ZOOM_LVL_END - ZOOM_LVL_BEGIN);
+assert_compile(lengthof(_vol_factor_by_zoom) == ZOOM_LVL_COUNT);
 
 static const byte _sound_base_vol[] = {
 	128,  90, 128, 128, 128, 128, 128, 128,
--- a/src/sound/cocoa_s.cpp	Sat Jun 21 13:35:29 2008 +0000
+++ b/src/sound/cocoa_s.cpp	Sat Jun 21 13:40:17 2008 +0000
@@ -24,7 +24,7 @@
 #include "../debug.h"
 #include "../driver.h"
 #include "../mixer.h"
-#include "../core/endian_func.hpp"
+#include "../core/endian_type.hpp"
 
 #include "cocoa_s.h"
 
@@ -61,9 +61,9 @@
 	requestedDesc.mBitsPerChannel = 16;
 	requestedDesc.mFormatFlags |= kLinearPCMFormatFlagIsSignedInteger;
 
-#ifdef TTD_BIG_ENDIAN
+#if TTD_ENDIAN == TTD_BIG_ENDIAN
 	requestedDesc.mFormatFlags |= kLinearPCMFormatFlagIsBigEndian;
-#endif
+#endif /* TTD_ENDIAN == TTD_BIG_ENDIAN */
 
 	requestedDesc.mFramesPerPacket = 1;
 	requestedDesc.mBytesPerFrame = requestedDesc.mBitsPerChannel * requestedDesc.mChannelsPerFrame / 8;
--- a/src/squirrel_helper.hpp	Sat Jun 21 13:35:29 2008 +0000
+++ b/src/squirrel_helper.hpp	Sat Jun 21 13:40:17 2008 +0000
@@ -7,8 +7,8 @@
 
 #include <squirrel.h>
 #include "core/math_func.hpp"
+#include "core/smallvec_type.hpp"
 #include "economy_type.h"
-#include "misc/smallvec.h"
 #include "squirrel_helper_type.hpp"
 
 /**
--- a/src/station_cmd.cpp	Sat Jun 21 13:35:29 2008 +0000
+++ b/src/station_cmd.cpp	Sat Jun 21 13:40:17 2008 +0000
@@ -2221,12 +2221,13 @@
 		DrawTramCatenary(ti, axis == AXIS_X ? ROAD_X : ROAD_Y);
 	}
 
-	/* End now if buildings are invisible */
-	if (IsInvisibilitySet(TO_BUILDINGS)) return;
-
 	const DrawTileSeqStruct *dtss;
 	foreach_draw_tile_seq(dtss, t->seq) {
 		SpriteID image = dtss->image.sprite;
+
+		/* Stop drawing sprite sequence once we meet a sprite that doesn't have to be opaque */
+		if (IsInvisibilitySet(TO_BUILDINGS) && !HasBit(image, SPRITE_MODIFIER_OPAQUE)) return;
+
 		if (relocation == 0 || HasBit(image, SPRITE_MODIFIER_USE_OFFSET)) {
 			image += total_offset;
 		} else {
--- a/src/strings.cpp	Sat Jun 21 13:35:29 2008 +0000
+++ b/src/strings.cpp	Sat Jun 21 13:40:17 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;
 	}
@@ -1251,11 +1251,11 @@
 		return false;
 	}
 
-#if defined(TTD_BIG_ENDIAN)
+#if TTD_ENDIAN == TTD_BIG_ENDIAN
 	for (i = 0; i != 32; i++) {
 		lang_pack->offsets[i] = ReadLE16Aligned(&lang_pack->offsets[i]);
 	}
-#endif
+#endif /* TTD_ENDIAN == TTD_BIG_ENDIAN */
 
 	tot_count = 0;
 	for (i = 0; i != 32; i++) {
--- a/src/table/palettes.h	Sat Jun 21 13:35:29 2008 +0000
+++ b/src/table/palettes.h	Sat Jun 21 13:40:17 2008 +0000
@@ -2,11 +2,18 @@
 
 /** @file palettes.h The colour translation of the GRF palettes. */
 
-#define M(r, g, b) { r, g, b }
+#include "../core/endian_type.hpp"
+
+#if TTD_ENDIAN == TTD_BIG_ENDIAN
+	#define M(r, g, b) { 0xff, r, g, b }
+#else
+	#define M(r, g, b) { b, g, r, 0xff }
+#endif /* TTD_ENDIAN == TTD_BIG_ENDIAN */
+
 static const Colour _palettes[][256] = {
 	/* palette 1 (TTD Windows) */
 	{
-		M(  0,   0,   0), M(212,   0, 212), M(212,   0, 212), M(212,   0, 212),
+		{  0, 0, 0, 0  }, M(212,   0, 212), M(212,   0, 212), M(212,   0, 212),
 		M(212,   0, 212), M(212,   0, 212), M(212,   0, 212), M(212,   0, 212),
 		M(212,   0, 212), M(212,   0, 212), M(168, 168, 168), M(184, 184, 184),
 		M(200, 200, 200), M(216, 216, 216), M(232, 232, 232), M(252, 252, 252),
@@ -74,7 +81,7 @@
 
 	/* palette 2 (mixed TTD DOS + TTD Windows palette */
 	{
-		M(  0,   0,   0), M( 16,  16,  16), M( 32,  32,  32), M( 48,  48,  48),
+		{  0, 0, 0, 0  }, M( 16,  16,  16), M( 32,  32,  32), M( 48,  48,  48),
 		M( 65,  64,  65), M( 82,  80,  82), M( 98, 101,  98), M(115, 117, 115),
 		M(131, 133, 131), M(148, 149, 148), M(168, 168, 168), M(184, 184, 184),
 		M(200, 200, 200), M(216, 216, 216), M(232, 232, 232), M(252, 252, 252),
--- a/src/terraform_gui.cpp	Sat Jun 21 13:35:29 2008 +0000
+++ b/src/terraform_gui.cpp	Sat Jun 21 13:40:17 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/toolbar_gui.cpp	Sat Jun 21 13:35:29 2008 +0000
+++ b/src/toolbar_gui.cpp	Sat Jun 21 13:40:17 2008 +0000
@@ -47,7 +47,7 @@
 #include "table/sprites.h"
 
 static void PopupMainToolbMenu(Window *parent, uint16 parent_button, StringID base_string, byte item_count, byte disabled_mask = 0, int sel_index = 0, int checked_items = 0);
-static void PopupMainPlayerToolbMenu(Window *parent, int main_button, int gray);
+static void PopupMainPlayerToolbMenu(Window *parent, int main_button, int gray = 0);
 static void SplitToolbar(Window *w);
 
 RailType _last_built_railtype;
@@ -59,6 +59,65 @@
 	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_SEPARATOR,
+	TBSE_DATEBACKWARD,
+	TBSE_DATEFORWARD,
+	TBSE_SMALLMAP,
+	TBSE_ZOOMIN,
+	TBSE_ZOOMOUT,
+	TBSE_LANDGENERATE,
+	TBSE_TOWNGENERATE,
+	TBSE_INDUSTRYGENERATE,
+	TBSE_BUILDROAD,
+	TBSE_PLANTTREES,
+	TBSE_PLACESIGNS,
+};
+
+/** The idea of this enum is to allow a separation between widget position
+ * and _menu_clicked_procs's entry.  By shifting, the "action" id is extracted and
+ * kept safe for usage when reuired.
+ * @see ToolbarMenuWindow::OnMouseLoop */
+enum ScenarioEditorMenuActions {
+	SEMA_MAP_CLICK = 17 << 8,
+};
+
 static ToolbarMode _toolbar_mode;
 
 static void SelectSignTool()
@@ -129,97 +188,141 @@
 
 /* --- Options button menu --- */
 
+enum OptionMenuEntries {
+	OME_GAMEOPTIONS    = 0,
+	OME_DIFFICULTIES,
+	OME_PATCHES,
+	OME_NEWGRFSETTINGS,
+	OME_TRANSPARENCIES,
+	OME_SHOW_TOWNNAMES = 6,
+	OME_SHOW_STATIONNAMES,
+	OME_SHOW_SIGNS,
+	OME_SHOW_WAYPOINTNAMES,
+	OME_FULL_ANIMATION,
+	OME_FULL_DETAILS,
+	OME_TRANSPARENTBUILDINGS,
+	OME_SHOW_STATIONSIGNS,
+	OME_MENUCOUNT,
+};
+
 static void ToolbarOptionsClick(Window *w)
 {
 	uint16 x = 0;
-	if (HasBit(_display_opt, DO_SHOW_TOWN_NAMES))    SetBit(x,  6);
-	if (HasBit(_display_opt, DO_SHOW_STATION_NAMES)) SetBit(x,  7);
-	if (HasBit(_display_opt, DO_SHOW_SIGNS))         SetBit(x,  8);
-	if (HasBit(_display_opt, DO_WAYPOINTS))          SetBit(x,  9);
-	if (HasBit(_display_opt, DO_FULL_ANIMATION))     SetBit(x, 10);
-	if (HasBit(_display_opt, DO_FULL_DETAIL))        SetBit(x, 11);
-	if (IsTransparencySet(TO_HOUSES))                SetBit(x, 12);
-	if (IsTransparencySet(TO_SIGNS))                 SetBit(x, 13);
+	if (HasBit(_display_opt, DO_SHOW_TOWN_NAMES))    SetBit(x, OME_SHOW_TOWNNAMES);
+	if (HasBit(_display_opt, DO_SHOW_STATION_NAMES)) SetBit(x, OME_SHOW_STATIONNAMES);
+	if (HasBit(_display_opt, DO_SHOW_SIGNS))         SetBit(x, OME_SHOW_SIGNS);
+	if (HasBit(_display_opt, DO_WAYPOINTS))          SetBit(x, OME_SHOW_WAYPOINTNAMES);
+	if (HasBit(_display_opt, DO_FULL_ANIMATION))     SetBit(x, OME_FULL_ANIMATION);
+	if (HasBit(_display_opt, DO_FULL_DETAIL))        SetBit(x, OME_FULL_DETAILS);
+	if (IsTransparencySet(TO_HOUSES))                SetBit(x, OME_TRANSPARENTBUILDINGS);
+	if (IsTransparencySet(TO_SIGNS))                 SetBit(x, OME_SHOW_STATIONSIGNS);
 
-	PopupMainToolbMenu(w, 2, STR_02C4_GAME_OPTIONS, 14, 0, 0, x);
+	PopupMainToolbMenu(w, TBN_SETTINGS, STR_02C4_GAME_OPTIONS, OME_MENUCOUNT, 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 OME_GAMEOPTIONS:          ShowGameOptions();                              return;
+		case OME_DIFFICULTIES:         ShowGameDifficulty();                           return;
+		case OME_PATCHES:              ShowPatchesSelection();                         return;
+		case OME_NEWGRFSETTINGS:       ShowNewGRFSettings(!_networking, true, true, &_grfconfig);   return;
+		case OME_TRANSPARENCIES:       ShowTransparencyToolbar();                      break;
 
-		case  6: ToggleBit(_display_opt, DO_SHOW_TOWN_NAMES);    break;
-		case  7: ToggleBit(_display_opt, DO_SHOW_STATION_NAMES); break;
-		case  8: ToggleBit(_display_opt, DO_SHOW_SIGNS);         break;
-		case  9: ToggleBit(_display_opt, DO_WAYPOINTS);          break;
-		case 10: ToggleBit(_display_opt, DO_FULL_ANIMATION);     break;
-		case 11: ToggleBit(_display_opt, DO_FULL_DETAIL);        break;
-		case 12: ToggleTransparency(TO_HOUSES);                  break;
-		case 13: ToggleTransparency(TO_SIGNS);                   break;
+		case OME_SHOW_TOWNNAMES:       ToggleBit(_display_opt, DO_SHOW_TOWN_NAMES);    break;
+		case OME_SHOW_STATIONNAMES:    ToggleBit(_display_opt, DO_SHOW_STATION_NAMES); break;
+		case OME_SHOW_SIGNS:           ToggleBit(_display_opt, DO_SHOW_SIGNS);         break;
+		case OME_SHOW_WAYPOINTNAMES:   ToggleBit(_display_opt, DO_WAYPOINTS);          break;
+		case OME_FULL_ANIMATION:       ToggleBit(_display_opt, DO_FULL_ANIMATION);     break;
+		case OME_FULL_DETAILS:         ToggleBit(_display_opt, DO_FULL_DETAIL);        break;
+		case OME_TRANSPARENTBUILDINGS: ToggleTransparency(TO_HOUSES);                  break;
+		case OME_SHOW_STATIONSIGNS:    ToggleTransparency(TO_SIGNS);                   break;
 	}
 	MarkWholeScreenDirty();
 }
 
 /* --- Saving/loading button menu --- */
 
+enum SaveLoadEditorMenuEntries {
+	SLEME_SAVE_SCENARIO   = 0,
+	SLEME_LOAD_SCENARIO,
+	SLEME_LOAD_HEIGHTMAP,
+	SLEME_EXIT_TOINTRO,
+	SLEME_EXIT_GAME       = 5,
+	SLEME_MENUCOUNT,
+};
+
+enum SaveLoadNormalMenuEntries {
+	SLNME_SAVE_GAME   = 0,
+	SLNME_LOAD_GAME,
+	SLNME_EXIT_TOINTRO,
+	SLNME_EXIT_GAME,
+	SLNME_MENUCOUNT,
+};
+
 static void ToolbarSaveClick(Window *w)
 {
-	PopupMainToolbMenu(w, 3, STR_015C_SAVE_GAME, 4);
+	PopupMainToolbMenu(w, TBN_SAVEGAME, STR_015C_SAVE_GAME, SLNME_MENUCOUNT);
 }
 
 static void ToolbarScenSaveOrLoad(Window *w)
 {
-	PopupMainToolbMenu(w, 3, STR_0292_SAVE_SCENARIO, 6);
+	PopupMainToolbMenu(w, TBSE_SAVESCENARIO, STR_0292_SAVE_SCENARIO, SLEME_MENUCOUNT);
 }
 
 static void MenuClickSaveLoad(int index)
 {
 	if (_game_mode == GM_EDITOR) {
 		switch (index) {
-			case 0: ShowSaveLoadDialog(SLD_SAVE_SCENARIO);  break;
-			case 1: ShowSaveLoadDialog(SLD_LOAD_SCENARIO);  break;
-			case 2: ShowSaveLoadDialog(SLD_LOAD_HEIGHTMAP); break;
-			case 3: AskExitToGameMenu();                    break;
-			case 5: HandleExitGameRequest();                break;
+			case SLEME_SAVE_SCENARIO:  ShowSaveLoadDialog(SLD_SAVE_SCENARIO);  break;
+			case SLEME_LOAD_SCENARIO:  ShowSaveLoadDialog(SLD_LOAD_SCENARIO);  break;
+			case SLEME_LOAD_HEIGHTMAP: ShowSaveLoadDialog(SLD_LOAD_HEIGHTMAP); break;
+			case SLEME_EXIT_TOINTRO:   AskExitToGameMenu();                    break;
+			case SLEME_EXIT_GAME:      HandleExitGameRequest();                break;
 		}
 	} else {
 		switch (index) {
-			case 0: ShowSaveLoadDialog(SLD_SAVE_GAME); break;
-			case 1: ShowSaveLoadDialog(SLD_LOAD_GAME); break;
-			case 2: AskExitToGameMenu();               break;
-			case 3: HandleExitGameRequest();           break;
+			case SLNME_SAVE_GAME:      ShowSaveLoadDialog(SLD_SAVE_GAME); break;
+			case SLNME_LOAD_GAME:      ShowSaveLoadDialog(SLD_LOAD_GAME); break;
+			case SLNME_EXIT_TOINTRO:   AskExitToGameMenu();               break;
+			case SLNME_EXIT_GAME:      HandleExitGameRequest();           break;
 		}
 	}
 }
 
 /* --- Map button menu --- */
 
+enum MapMenuEntries {
+	MME_SHOW_SMALLMAP        = 0,
+	MME_SHOW_EXTRAVIEWPORTS,
+	MME_SHOW_SIGNLISTS,
+	MME_SHOW_TOWNDIRECTORY,    ///< This entry is only used in Editor mode
+	MME_MENUCOUNT_NORMAL = 3,
+	MME_MENUCOUNT_EDITOR = 4,
+};
+
 static void ToolbarMapClick(Window *w)
 {
-	PopupMainToolbMenu(w, 4, STR_02DE_MAP_OF_WORLD, 3);
+	PopupMainToolbMenu(w, TBN_SMALLMAP, STR_02DE_MAP_OF_WORLD, MME_MENUCOUNT_NORMAL);
+}
+
+static void ToolbarScenMapTownDir(Window *w)
+{
+	/* Scenario editor button, Use different button to activate.
+	 * This scheme will allow to have an action (SEMA_MAP_CLICK, which is in fact
+	 * an entry in _menu_clicked_procs) while at the same time having a start button
+	 * who is not at the same index as its action
+	 * @see ToolbarMenuWindow::OnMouseLoop */
+	PopupMainToolbMenu(w, TBSE_SMALLMAP | SEMA_MAP_CLICK, STR_02DE_MAP_OF_WORLD, MME_MENUCOUNT_EDITOR);
 }
 
 static void MenuClickMap(int index)
 {
 	switch (index) {
-		case 0: ShowSmallMap();            break;
-		case 1: ShowExtraViewPortWindow(); break;
-		case 2: ShowSignList();            break;
-	}
-}
-
-static void MenuClickScenMap(int index)
-{
-	switch (index) {
-		case 0: ShowSmallMap();            break;
-		case 1: ShowExtraViewPortWindow(); break;
-		case 2: ShowSignList();            break;
-		case 3: ShowTownDirectory();       break;
+		case MME_SHOW_SMALLMAP:       ShowSmallMap();            break;
+		case MME_SHOW_EXTRAVIEWPORTS: ShowExtraViewPortWindow(); break;
+		case MME_SHOW_SIGNLISTS:      ShowSignList();            break;
+		case MME_SHOW_TOWNDIRECTORY:  if (_game_mode == GM_EDITOR) ShowTownDirectory(); break;
 	}
 }
 
@@ -227,7 +330,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)
@@ -239,7 +342,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)
@@ -251,7 +354,7 @@
 
 static void ToolbarStationsClick(Window *w)
 {
-	PopupMainPlayerToolbMenu(w, 7, 0);
+	PopupMainPlayerToolbMenu(w, TBN_STATIONS);
 }
 
 static void MenuClickStations(int index)
@@ -263,7 +366,7 @@
 
 static void ToolbarFinancesClick(Window *w)
 {
-	PopupMainPlayerToolbMenu(w, 8, 0);
+	PopupMainPlayerToolbMenu(w, TBN_FINANCES);
 }
 
 static void MenuClickFinances(int index)
@@ -275,7 +378,7 @@
 
 static void ToolbarPlayersClick(Window *w)
 {
-	PopupMainPlayerToolbMenu(w, 9, 0);
+	PopupMainPlayerToolbMenu(w, TBN_PLAYERS);
 }
 
 static void MenuClickCompany(int index)
@@ -292,7 +395,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)
@@ -314,7 +417,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)
@@ -330,7 +433,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)
@@ -351,7 +454,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);
 }
 
 
@@ -406,7 +509,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);
 	}
 }
@@ -416,7 +519,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);
 	}
 }
@@ -426,7 +529,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)
@@ -441,7 +544,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)
@@ -454,7 +557,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)
@@ -466,7 +569,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)
@@ -478,7 +581,7 @@
 
 static void ToolbarForestClick(Window *w)
 {
-	PopupMainToolbMenu(w, 23, STR_LANDSCAPING, 3);
+	PopupMainToolbMenu(w, TBN_LANDSCAPE, STR_LANDSCAPING, 3);
 }
 
 static void MenuClickForest(int index)
@@ -494,7 +597,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)
@@ -506,7 +609,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)
@@ -522,7 +625,7 @@
 
 static void ToolbarHelpClick(Window *w)
 {
-	PopupMainToolbMenu(w, 26, STR_02D5_LAND_BLOCK_INFO, 7);
+	PopupMainToolbMenu(w, TBN_HELP, STR_02D5_LAND_BLOCK_INFO, 6);
 }
 
 static void MenuClickSmallScreenshot()
@@ -558,7 +661,7 @@
 	}
 
 	SplitToolbar(w);
-	w->HandleButtonClick(27);
+	w->HandleButtonClick(TBN_SWITCHBAR);
 	SetWindowDirty(w);
 	SndPlayFx(SND_15_BEEP);
 }
@@ -569,7 +672,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);
@@ -582,7 +685,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);
@@ -591,16 +694,10 @@
 	_left_button_clicked = false;
 }
 
-static void ToolbarScenMapTownDir(Window *w)
-{
-	/* Scenario editor button, *hack*hack* use different button to activate */
-	PopupMainToolbMenu(w, 8 | (17 << 8), STR_02DE_MAP_OF_WORLD, 4);
-}
-
 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);
 	}
 }
@@ -608,14 +705,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();
@@ -624,35 +721,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();
 }
@@ -668,16 +765,19 @@
 	/* There are 27 buttons plus some spacings if the space allows it */
 	uint button_width;
 	uint spacing;
-	if (w->width >= 27 * 22) {
+	uint widgetcount = w->widget_count - 1;
+
+	if (w->width >= (int)widgetcount * 22) {
 		button_width = 22;
-		spacing = w->width - (27 * button_width);
+		spacing = w->width - (widgetcount * button_width);
 	} else {
-		button_width = w->width / 27;
+		button_width = w->width / widgetcount;
 		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 < widgetcount; i++) {
 		if (extra_spacing_at[j] == i) {
 			j++;
 			uint add = spacing / (lengthof(extra_spacing_at) - j);
@@ -687,11 +787,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) / (widgetcount - 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;
 }
 
@@ -732,7 +832,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 - 1; i++) {
 		w->widget[i].type = WWT_EMPTY;
 	}
 
@@ -784,8 +884,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);
 
@@ -803,12 +903,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();
 	}
@@ -868,22 +968,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);
 		}
 	}
 
@@ -898,7 +992,7 @@
 
 	virtual void OnTimeout()
 	{
-		for (uint i = 2; i < this->widget_count; i++) {
+		for (uint i = TBN_SETTINGS; i < this->widget_count - 1; i++) {
 			if (this->IsWidgetLowered(i)) {
 				this->RaiseWidget(i);
 				this->InvalidateWidget(i);
@@ -908,7 +1002,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);
 	}
 };
 
@@ -991,17 +1085,6 @@
 };
 
 struct ScenarioEditorToolbarWindow : Window {
-private:
-	enum ToolbarScenEditorWidgets {
-		TBSE_PAUSE        = 0,
-		TBSE_FASTFORWARD,
-		TBSE_SPACERPANEL  = 4,
-		TBSE_DATEBACKWARD = 6,
-		TBSE_DATEFORWARD,
-		TBSE_ZOOMIN       = 9,
-		TBSE_ZOOMOUT,
-	};
-
 public:
 	ScenarioEditorToolbarWindow(const WindowDesc *desc) : Window(desc)
 	{
@@ -1082,12 +1165,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.
@@ -1108,10 +1185,9 @@
 		}
 		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:
+				case TBSE_SPACERPANEL:
 					this->widget[i].left = x;
 					if (this->width < normal_min_width) {
 						this->widget[i].right = x;
@@ -1123,7 +1199,7 @@
 					this->widget[i].right = x - 1;
 					break;
 
-				case 5: {
+				case TBSE_SEPARATOR: {
 					int offset = x - this->widget[i].left;
 					this->widget[i + 1].left  += offset;
 					this->widget[i + 1].right += offset;
@@ -1240,7 +1316,7 @@
 	MenuClickShowRoad,    /* 14 */
 	MenuClickShowShips,   /* 15 */
 	MenuClickShowAir,     /* 16 */
-	MenuClickScenMap,     /* 17 */
+	MenuClickMap,         /* 17 */
 	NULL,                 /* 18 */
 	MenuClickBuildRail,   /* 19 */
 	MenuClickBuildRoad,   /* 20 */
@@ -1424,7 +1500,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 {
@@ -1448,7 +1524,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;
@@ -1472,7 +1548,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);
 			}
@@ -1511,7 +1587,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);
@@ -1526,7 +1602,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);
@@ -1554,6 +1630,11 @@
 { WIDGETS_END},
 };
 
+/** Shows the list of players appearing under the buttons that are linked to options for
+ * multiple players.
+ * @param parent Window who triggered that action.  It's the toolbar, in fact
+ * @param main_button widget which has been used
+ * @param gray bit-mapping of the items that will need to be grayed out once displayed */
 static void PopupMainPlayerToolbMenu(Window *parent, int main_button, int gray)
 {
 	parent->LowerWidget(main_button);
--- a/src/town_cmd.cpp	Sat Jun 21 13:35:29 2008 +0000
+++ b/src/town_cmd.cpp	Sat Jun 21 13:40:17 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);
 }
 
 
@@ -1965,7 +1966,6 @@
 
 		/* 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	Sat Jun 21 13:35:29 2008 +0000
+++ b/src/town_gui.cpp	Sat Jun 21 13:40:17 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/vehicle_gui.cpp	Sat Jun 21 13:35:29 2008 +0000
+++ b/src/vehicle_gui.cpp	Sat Jun 21 13:40:17 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,23 +44,20 @@
 #include "table/strings.h"
 
 Sorting _sorting;
-static bool   _internal_sort_order;     // descending/ascending
-
-typedef int CDECL VehicleSortListingTypeFunction(const void*, const void*);
 
-static VehicleSortListingTypeFunction VehicleNumberSorter;
-static VehicleSortListingTypeFunction VehicleNameSorter;
-static VehicleSortListingTypeFunction VehicleAgeSorter;
-static VehicleSortListingTypeFunction VehicleProfitThisYearSorter;
-static VehicleSortListingTypeFunction VehicleProfitLastYearSorter;
-static VehicleSortListingTypeFunction VehicleCargoSorter;
-static VehicleSortListingTypeFunction VehicleReliabilitySorter;
-static VehicleSortListingTypeFunction VehicleMaxSpeedSorter;
-static VehicleSortListingTypeFunction VehicleModelSorter;
-static VehicleSortListingTypeFunction VehicleValueSorter;
-static VehicleSortListingTypeFunction VehicleLengthSorter;
+static GUIVehicleList::SortFunction VehicleNumberSorter;
+static GUIVehicleList::SortFunction VehicleNameSorter;
+static GUIVehicleList::SortFunction VehicleAgeSorter;
+static GUIVehicleList::SortFunction VehicleProfitThisYearSorter;
+static GUIVehicleList::SortFunction VehicleProfitLastYearSorter;
+static GUIVehicleList::SortFunction VehicleCargoSorter;
+static GUIVehicleList::SortFunction VehicleReliabilitySorter;
+static GUIVehicleList::SortFunction VehicleMaxSpeedSorter;
+static GUIVehicleList::SortFunction VehicleModelSorter;
+static GUIVehicleList::SortFunction VehicleValueSorter;
+static GUIVehicleList::SortFunction VehicleLengthSorter;
 
-static VehicleSortListingTypeFunction* const _vehicle_sorter[] = {
+GUIVehicleList::SortFunction* const VehicleListBase::vehicle_sorter_funcs[] = {
 	&VehicleNumberSorter,
 	&VehicleNameSorter,
 	&VehicleAgeSorter,
@@ -72,7 +71,7 @@
 	&VehicleLengthSorter,
 };
 
-const StringID _vehicle_sort_listing[] = {
+const StringID VehicleListBase::vehicle_sorter_names[] = {
 	STR_SORT_BY_NUMBER,
 	STR_SORT_BY_DROPDOWN_NAME,
 	STR_SORT_BY_AGE,
@@ -89,40 +88,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()) 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(), &VehicleNumberSorter);
 }
 
 /** draw the vehicle profit button in the vehicle list window. */
@@ -507,183 +496,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;
+	memset(diff, 0, sizeof(diff));
+
+	/* 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 +857,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 +931,9 @@
 		this->DrawWidgets();
 
 		/* draw sorting criteria string */
-		DrawString(85, 15, _vehicle_sort_listing[this->vehicles.sort_type], TC_BLACK);
+		DrawString(85, 15, this->vehicle_sorter_names[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 +973,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, this->vehicle_sorter_names, 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 +1030,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 +1063,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 +1080,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/vehicle_gui.h	Sat Jun 21 13:35:29 2008 +0000
+++ b/src/vehicle_gui.h	Sat Jun 21 13:40:17 2008 +0000
@@ -15,10 +15,6 @@
 void DrawVehicleProfitButton(const Vehicle *v, int x, int y);
 void ShowVehicleRefitWindow(const Vehicle *v, VehicleOrderID order);
 
-#define PERIODIC_RESORT_DAYS 10
-
-extern const StringID _vehicle_sort_listing[];
-
 /** Constants of vehicle view widget indices */
 enum VehicleViewWindowWidgets {
 	VVW_WIDGET_CLOSEBOX = 0,
@@ -121,6 +117,14 @@
 	GUIVehicleList vehicles;  ///< The list of vehicles
 	Listing *sorting;         ///< Pointer to the vehicle type related sorting.
 	VehicleType vehicle_type; ///< The vehicle type that is sorted
+
+	static const StringID vehicle_sorter_names[];
+	static GUIVehicleList::SortFunction *const vehicle_sorter_funcs[];
+
+	VehicleListBase()
+	{
+		this->vehicles.SetSortFuncs(this->vehicle_sorter_funcs);
+	}
 };
 
 struct Sorting {
--- a/src/vehiclelist.h	Sat Jun 21 13:35:29 2008 +0000
+++ b/src/vehiclelist.h	Sat Jun 21 13:40:17 2008 +0000
@@ -5,7 +5,7 @@
 #ifndef VEHICLELIST_H
 #define VEHICLELIST_H
 
-#include "misc/smallvec.h"
+#include "core/smallvec_type.hpp"
 
 typedef SmallVector<const Vehicle *, 32> VehicleList;
 
--- a/src/video/cocoa/cocoa_v.mm	Sat Jun 21 13:35:29 2008 +0000
+++ b/src/video/cocoa/cocoa_v.mm	Sat Jun 21 13:40:17 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	Sat Jun 21 13:35:29 2008 +0000
+++ b/src/video/dedicated_v.cpp	Sat Jun 21 13:40:17 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	Sat Jun 21 13:35:29 2008 +0000
+++ b/src/video/null_v.cpp	Sat Jun 21 13:40:17 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	Sat Jun 21 13:35:29 2008 +0000
+++ b/src/video/sdl_v.cpp	Sat Jun 21 13:40:17 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	Sat Jun 21 13:35:29 2008 +0000
+++ b/src/video/video_driver.hpp	Sat Jun 21 13:40:17 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	Sat Jun 21 13:35:29 2008 +0000
+++ b/src/video/win32_v.cpp	Sat Jun 21 13:40:17 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	Sat Jun 21 13:35:29 2008 +0000
+++ b/src/viewport.cpp	Sat Jun 21 13:40:17 2008 +0000
@@ -44,7 +44,7 @@
 #include "settings_type.h"
 #include "station_func.h"
 #include "core/alloc_type.hpp"
-#include "misc/smallvec.h"
+#include "core/smallvec_type.hpp"
 #include "window_func.h"
 #include "tilehighlight_func.h"
 #include "window_gui.h"
@@ -80,7 +80,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 {
@@ -102,7 +102,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
 };
 
@@ -547,7 +546,7 @@
 	}
 
 	/* _vd.last_child == NULL if foundation sprite was clipped by the viewport bounds */
-	if (_vd.last_child != NULL) _vd.foundation[_vd.foundation_part] = _vd.parent_sprites_to_draw.items - 1;
+	if (_vd.last_child != NULL) _vd.foundation[_vd.foundation_part] = _vd.parent_sprites_to_draw.Length() - 1;
 
 	_vd.foundation_offset[_vd.foundation_part].x = x;
 	_vd.foundation_offset[_vd.foundation_part].y = y;
@@ -676,10 +675,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;
 }
@@ -717,17 +715,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.Length();
+
 	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 */
@@ -1350,8 +1353,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);
 		}
 	}
@@ -1473,7 +1478,7 @@
 	ViewportAddSigns(&_vd.dpi);
 	ViewportAddWaypoints(&_vd.dpi);
 
-	if (_vd.tile_sprites_to_draw.items != 0) ViewportDrawTileSprites(&_vd.tile_sprites_to_draw);
+	if (_vd.tile_sprites_to_draw.Length() != 0) ViewportDrawTileSprites(&_vd.tile_sprites_to_draw);
 
 	ParentSpriteToDraw *psd_end = _vd.parent_sprites_to_draw.End();
 	for (ParentSpriteToDraw *it = _vd.parent_sprites_to_draw.Begin(); it != psd_end; it++) {
@@ -1485,15 +1490,15 @@
 
 	if (_draw_bounding_boxes) ViewportDrawBoundingBoxes(&_vd.parent_sprites_to_sort);
 
-	if (_vd.string_sprites_to_draw.items != 0) ViewportDrawStrings(&_vd.dpi, &_vd.string_sprites_to_draw);
+	if (_vd.string_sprites_to_draw.Length() != 0) ViewportDrawStrings(&_vd.dpi, &_vd.string_sprites_to_draw);
 
 	_cur_dpi = old_dpi;
 
-	_vd.string_sprites_to_draw.items = 0;
-	_vd.tile_sprites_to_draw.items = 0;
-	_vd.parent_sprites_to_draw.items = 0;
-	_vd.parent_sprites_to_sort.items = 0;
-	_vd.child_screen_sprites_to_draw.items = 0;
+	_vd.string_sprites_to_draw.Clear();
+	_vd.tile_sprites_to_draw.Clear();
+	_vd.parent_sprites_to_draw.Clear();
+	_vd.parent_sprites_to_sort.Clear();
+	_vd.child_screen_sprites_to_draw.Clear();
 }
 
 /** Make sure we don't draw a too big area at a time.
--- a/src/water_cmd.cpp	Sat Jun 21 13:35:29 2008 +0000
+++ b/src/water_cmd.cpp	Sat Jun 21 13:40:17 2008 +0000
@@ -734,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	Sat Jun 21 13:35:29 2008 +0000
+++ b/src/win32.cpp	Sat Jun 21 13:40:17 2008 +0000
@@ -460,8 +460,8 @@
 static void GamelogPrintCrashLogProc(const char *s)
 {
 	DWORD num_written;
-	WriteFile(_file_crash_log, s, strlen(s), &num_written, NULL);
-	WriteFile(_file_crash_log, "\r\n", strlen("\r\n"), &num_written, NULL);
+	WriteFile(_file_crash_log, s, (DWORD)strlen(s), &num_written, NULL);
+	WriteFile(_file_crash_log, "\r\n", (DWORD)strlen("\r\n"), &num_written, NULL);
 }
 
 static LONG WINAPI ExceptionHandler(EXCEPTION_POINTERS *ep)
--- a/src/zoom_type.h	Sat Jun 21 13:35:29 2008 +0000
+++ b/src/zoom_type.h	Sat Jun 21 13:40:17 2008 +0000
@@ -16,6 +16,9 @@
 	ZOOM_LVL_OUT_8X,
 	ZOOM_LVL_END,
 
+	/* Number of zoom levels */
+	ZOOM_LVL_COUNT = ZOOM_LVL_END - ZOOM_LVL_BEGIN,
+
 	/* Here we define in which zoom viewports are */
 	ZOOM_LVL_VIEWPORT = ZOOM_LVL_NORMAL,
 	ZOOM_LVL_NEWS     = ZOOM_LVL_NORMAL,