(svn r13326) [NoAI] -Sync with trunk r13264:13325 noai
authorglx
Thu, 29 May 2008 15:56:32 +0000
branchnoai
changeset 10776 07203fc29812
parent 10774 2c882f0468f2
child 10779 df1c9ca74038
(svn r13326) [NoAI] -Sync with trunk r13264:13325
[NoAI] -Change [API CHANGE]: removed AISign.GetSignCount()
bin/ai/regression/regression.nut
bin/ai/regression/regression.txt
projects/openttd_vs80.vcproj
projects/openttd_vs90.vcproj
source.list
src/ai/ai.cpp
src/ai/api/ai_airport.cpp
src/ai/api/ai_bridge.cpp
src/ai/api/ai_engine.cpp
src/ai/api/ai_event_types.cpp
src/ai/api/ai_sign.cpp
src/ai/api/ai_sign.hpp
src/ai/api/ai_sign.hpp.sq
src/ai/api/ai_station.cpp
src/ai/api/ai_tile.cpp
src/ai/api/ai_tilelist.cpp
src/aircraft_cmd.cpp
src/airport.cpp
src/airport_gui.cpp
src/animated_tile.cpp
src/autoreplace_gui.cpp
src/autoslope.h
src/bridge_gui.cpp
src/build_vehicle_gui.cpp
src/cheat.cpp
src/cheat_gui.cpp
src/clear_cmd.cpp
src/console_cmds.cpp
src/core/bitmath_func.hpp
src/currency.cpp
src/currency.h
src/date.cpp
src/debug.cpp
src/depot_gui.cpp
src/disaster_cmd.cpp
src/dock_gui.cpp
src/economy.cpp
src/elrail_func.h
src/engine.cpp
src/engine_func.h
src/engine_gui.cpp
src/engine_gui.h
src/engine_type.h
src/fileio.cpp
src/fileio.h
src/fios.h
src/genworld.cpp
src/genworld.h
src/genworld_gui.cpp
src/gfx.cpp
src/gfxinit.cpp
src/group_gui.cpp
src/gui.h
src/heightmap.cpp
src/industry_cmd.cpp
src/industry_gui.cpp
src/landscape.cpp
src/lang/afrikaans.txt
src/lang/brazilian_portuguese.txt
src/lang/bulgarian.txt
src/lang/catalan.txt
src/lang/croatian.txt
src/lang/czech.txt
src/lang/danish.txt
src/lang/dutch.txt
src/lang/english.txt
src/lang/english_US.txt
src/lang/esperanto.txt
src/lang/estonian.txt
src/lang/finnish.txt
src/lang/french.txt
src/lang/galician.txt
src/lang/german.txt
src/lang/hungarian.txt
src/lang/icelandic.txt
src/lang/italian.txt
src/lang/japanese.txt
src/lang/korean.txt
src/lang/lithuanian.txt
src/lang/norwegian_bokmal.txt
src/lang/norwegian_nynorsk.txt
src/lang/piglatin.txt
src/lang/polish.txt
src/lang/portuguese.txt
src/lang/romanian.txt
src/lang/russian.txt
src/lang/simplified_chinese.txt
src/lang/slovak.txt
src/lang/slovenian.txt
src/lang/spanish.txt
src/lang/swedish.txt
src/lang/traditional_chinese.txt
src/lang/turkish.txt
src/lang/ukrainian.txt
src/lang/unfinished/greek.txt
src/lang/unfinished/latvian.txt
src/main_gui.cpp
src/minilzo.cpp
src/misc.cpp
src/misc_cmd.cpp
src/misc_gui.cpp
src/mixer.cpp
src/mixer.h
src/network/network.cpp
src/network/network_client.cpp
src/network/network_gui.cpp
src/network/network_server.cpp
src/network/network_udp.cpp
src/newgrf.cpp
src/newgrf.h
src/newgrf_commons.cpp
src/newgrf_engine.cpp
src/newgrf_town.cpp
src/news_gui.cpp
src/news_type.h
src/npf.cpp
src/oldloader.cpp
src/openttd.cpp
src/openttd.h
src/order_cmd.cpp
src/order_gui.cpp
src/osk_gui.cpp
src/pathfind.cpp
src/player_gui.cpp
src/players.cpp
src/rail.cpp
src/rail_cmd.cpp
src/rail_gui.cpp
src/road.cpp
src/road_cmd.cpp
src/road_gui.cpp
src/roadveh_cmd.cpp
src/saveload.cpp
src/saveload.h
src/settings.cpp
src/settings_func.h
src/settings_gui.cpp
src/settings_internal.h
src/settings_type.h
src/ship_cmd.cpp
src/signs.cpp
src/signs_base.h
src/smallmap_gui.cpp
src/sortlist_type.h
src/sound.cpp
src/sound_type.h
src/spritecache.cpp
src/spriteloader/grf.cpp
src/spriteloader/grf.hpp
src/spriteloader/png.cpp
src/spriteloader/png.hpp
src/spriteloader/spriteloader.hpp
src/station.cpp
src/station_cmd.cpp
src/station_gui.cpp
src/station_type.h
src/statusbar_gui.cpp
src/stdafx.h
src/string_func.h
src/strings.cpp
src/terraform_gui.cpp
src/texteff.cpp
src/tgp.cpp
src/timetable_cmd.cpp
src/timetable_gui.cpp
src/town.h
src/town_cmd.cpp
src/town_gui.cpp
src/train_cmd.cpp
src/train_gui.cpp
src/tree_cmd.cpp
src/tree_gui.cpp
src/tunnelbridge_cmd.cpp
src/unmovable_cmd.cpp
src/vehicle.cpp
src/vehicle_func.h
src/vehicle_gui.cpp
src/vehicle_type.h
src/vehiclelist.cpp
src/vehiclelist.h
src/video/cocoa/event.mm
src/viewport.cpp
src/water_cmd.cpp
src/waypoint.cpp
src/widgets/dropdown.cpp
src/win32.cpp
src/window.cpp
src/window_gui.h
src/yapf/yapf_base.hpp
src/yapf/yapf_rail.cpp
src/yapf/yapf_road.cpp
src/yapf/yapf_ship.cpp
--- a/bin/ai/regression/regression.nut	Thu May 29 12:52:24 2008 +0000
+++ b/bin/ai/regression/regression.nut	Thu May 29 15:56:32 2008 +0000
@@ -783,7 +783,6 @@
 	print("  RemoveSign(" + AISign_id + "):                       " + AISign.RemoveSign(AISign_id));
 	print("");
 	print("  GetMaxSignID():    " + AISign.GetMaxSignID());
-	print("  GetSignCount():    " + AISign.GetSignCount());
 	for (local i = -1; i < AISign.GetMaxSignID() + 1; i++) {
 		if (AISign.IsValidSign(i)) j++;
 		print("  Sign " + i);
@@ -792,7 +791,6 @@
 		print("    GetLocation():   " + AISign.GetLocation(i));
 	}
 	print("  Valid Signs:       " + j);
-	print("  GetSignCount():    " + AISign.GetSignCount());
 }
 
 function Regression::Station()
--- a/bin/ai/regression/regression.txt	Thu May 29 12:52:24 2008 +0000
+++ b/bin/ai/regression/regression.txt	Thu May 29 15:56:32 2008 +0000
@@ -864,7 +864,7 @@
   GetAutoRenewStatus();        true
   SetAutoRenewStatus(true);    false
   SetAutoRenewStatus(false);   true
-  GetAutoRenewMonths();        6
+  GetAutoRenewMonths();        -6
   SetAutoRenewMonths(-12);     true
   GetAutoRenewMonths();        -12
   SetAutoRenewMonths(-12);     false
@@ -5762,7 +5762,6 @@
   RemoveSign(1):                       true
 
   GetMaxSignID():    3
-  GetSignCount():    1
   Sign -1
     IsValidSign():   false
     GetText():       (null : 0x00000000)
@@ -5784,7 +5783,6 @@
     GetText():       (null : 0x00000000)
     GetLocation():   -1
   Valid Signs:       1
-  GetSignCount():    1
 
 --Station--
   IsValidStation(0):        true
--- a/projects/openttd_vs80.vcproj	Thu May 29 12:52:24 2008 +0000
+++ b/projects/openttd_vs80.vcproj	Thu May 29 15:56:32 2008 +0000
@@ -768,6 +768,10 @@
 				>
 			</File>
 			<File
+				RelativePath=".\..\src\vehiclelist.cpp"
+				>
+			</File>
+			<File
 				RelativePath=".\..\src\viewport.cpp"
 				>
 			</File>
@@ -1000,6 +1004,10 @@
 				>
 			</File>
 			<File
+				RelativePath=".\..\src\engine_gui.h"
+				>
+			</File>
+			<File
 				RelativePath=".\..\src\engine_type.h"
 				>
 			</File>
@@ -1604,6 +1612,10 @@
 				>
 			</File>
 			<File
+				RelativePath=".\..\src\vehiclelist.h"
+				>
+			</File>
+			<File
 				RelativePath=".\..\src\viewport_func.h"
 				>
 			</File>
--- a/projects/openttd_vs90.vcproj	Thu May 29 12:52:24 2008 +0000
+++ b/projects/openttd_vs90.vcproj	Thu May 29 15:56:32 2008 +0000
@@ -765,6 +765,10 @@
 				>
 			</File>
 			<File
+				RelativePath=".\..\src\vehiclelist.cpp"
+				>
+			</File>
+			<File
 				RelativePath=".\..\src\viewport.cpp"
 				>
 			</File>
@@ -997,6 +1001,10 @@
 				>
 			</File>
 			<File
+				RelativePath=".\..\src\engine_gui.h"
+				>
+			</File>
+			<File
 				RelativePath=".\..\src\engine_type.h"
 				>
 			</File>
@@ -1601,6 +1609,10 @@
 				>
 			</File>
 			<File
+				RelativePath=".\..\src\vehiclelist.h"
+				>
+			</File>
+			<File
 				RelativePath=".\..\src\viewport_func.h"
 				>
 			</File>
--- a/source.list	Thu May 29 12:52:24 2008 +0000
+++ b/source.list	Thu May 29 15:56:32 2008 +0000
@@ -114,6 +114,7 @@
 	#end
 #end
 vehicle.cpp
+vehiclelist.cpp
 viewport.cpp
 waypoint.cpp
 widget.cpp
@@ -175,6 +176,7 @@
 core/endian_func.hpp
 engine_base.h
 engine_func.h
+engine_gui.h
 engine_type.h
 core/enum_type.hpp
 fiber.hpp
@@ -326,6 +328,7 @@
 vehicle_func.h
 vehicle_gui.h
 vehicle_type.h
+vehiclelist.h
 viewport_func.h
 viewport_type.h
 waypoint.h
--- a/src/ai/ai.cpp	Thu May 29 12:52:24 2008 +0000
+++ b/src/ai/ai.cpp	Thu May 29 15:56:32 2008 +0000
@@ -45,14 +45,14 @@
 	if (!_ai_enabled) return;
 
 	/* Don't do anything if we are a network-client, or the AI has been disabled */
-	if (_networking && (!_network_server || !_settings.ai.ai_in_multiplayer)) return;
+	if (_networking && (!_network_server || !_settings_game.ai.ai_in_multiplayer)) return;
 
 	/* New tick */
 	_ai_frame_counter++;
 
 	/* Make sure the AI follows the difficulty rule.. */
-	assert(_settings.difficulty.competitor_speed <= 4);
-	if ((_ai_frame_counter & ((1 << (4 - _settings.difficulty.competitor_speed)) - 1)) != 0) return;
+	assert(_settings_game.difficulty.competitor_speed <= 4);
+	if ((_ai_frame_counter & ((1 << (4 - _settings_game.difficulty.competitor_speed)) - 1)) != 0) return;
 
 	/* Check for AI-client (so joining a network with an AI) */
 	if (!_networking || _network_server) {
@@ -210,7 +210,7 @@
 	/* If in network, and server, possible AI */
 	if (_networking && _network_server) {
 		/* Do we want AIs in multiplayer? */
-		if (!_settings.ai.ai_in_multiplayer) return false;
+		if (!_settings_game.ai.ai_in_multiplayer) return false;
 	}
 
 	return true;
--- a/src/ai/api/ai_airport.cpp	Thu May 29 12:52:24 2008 +0000
+++ b/src/ai/api/ai_airport.cpp	Thu May 29 15:56:32 2008 +0000
@@ -46,7 +46,7 @@
 /* static */ int32 AIAirport::GetAirportCoverageRadius(AirportType type)
 {
 	if (type > AT_HELISTATION) return -1;
-	return _settings.station.modified_catchment ? ::GetAirport(type)->catchment : (uint)CA_UNMODIFIED;
+	return _settings_game.station.modified_catchment ? ::GetAirport(type)->catchment : (uint)CA_UNMODIFIED;
 }
 
 /* static */ bool AIAirport::BuildAirport(TileIndex tile, AirportType type)
--- a/src/ai/api/ai_bridge.cpp	Thu May 29 12:52:24 2008 +0000
+++ b/src/ai/api/ai_bridge.cpp	Thu May 29 15:56:32 2008 +0000
@@ -77,7 +77,7 @@
 	if (!IsValidBridge(bridge_id)) return -1;
 
 	uint max = ::GetBridgeSpec(bridge_id)->max_length;
-	if (max >= 16 && _settings.construction.longbridges) max = 100;
+	if (max >= 16 && _settings_game.construction.longbridges) max = 100;
 	return max + 2;
 }
 
--- a/src/ai/api/ai_engine.cpp	Thu May 29 12:52:24 2008 +0000
+++ b/src/ai/api/ai_engine.cpp	Thu May 29 15:56:32 2008 +0000
@@ -134,7 +134,7 @@
 
 		case VEH_AIRCRAFT: {
 			const AircraftVehicleInfo *vi = ::AircraftVehInfo(engine_id);
-			return vi->max_speed / _settings.vehicle.plane_speed;
+			return vi->max_speed / _settings_game.vehicle.plane_speed;
 		} break;
 
 		default: NOT_REACHED();
--- a/src/ai/api/ai_event_types.cpp	Thu May 29 12:52:24 2008 +0000
+++ b/src/ai/api/ai_event_types.cpp	Thu May 29 15:56:32 2008 +0000
@@ -104,7 +104,7 @@
 
 		case VEH_AIRCRAFT: {
 			const AircraftVehicleInfo *vi = ::AircraftVehInfo(engine);
-			return vi->max_speed / _settings.vehicle.plane_speed;
+			return vi->max_speed / _settings_game.vehicle.plane_speed;
 		} break;
 
 		default: NOT_REACHED();
--- a/src/ai/api/ai_sign.cpp	Thu May 29 12:52:24 2008 +0000
+++ b/src/ai/api/ai_sign.cpp	Thu May 29 15:56:32 2008 +0000
@@ -17,11 +17,6 @@
 	return ::GetMaxSignIndex();
 }
 
-/* static */ int32 AISign::GetSignCount()
-{
-	return ::GetNumSigns();
-}
-
 /* static */ bool AISign::IsValidSign(SignID sign_id)
 {
 	return ::IsValidSignID(sign_id);
--- a/src/ai/api/ai_sign.hpp	Thu May 29 12:52:24 2008 +0000
+++ b/src/ai/api/ai_sign.hpp	Thu May 29 15:56:32 2008 +0000
@@ -35,14 +35,6 @@
 	static SignID GetMaxSignID();
 
 	/**
-	 * Gets the number of signs. This is different than GetMaxSignID()
-	 *   because of the way OpenTTD works internally.
-	 * @return The number of signs.
-	 * @post Return value is always non-negative.
-	 */
-	static int32 GetSignCount();
-
-	/**
 	 * Checks whether the given sign index is valid.
 	 * @param sign_id The index to check.
 	 * @return True if and only if the sign is valid.
--- a/src/ai/api/ai_sign.hpp.sq	Thu May 29 12:52:24 2008 +0000
+++ b/src/ai/api/ai_sign.hpp.sq	Thu May 29 15:56:32 2008 +0000
@@ -30,7 +30,6 @@
 
 	SQAISign.DefSQStaticMethod(engine, &AISign::GetClassName, "GetClassName", 1, "x");
 	SQAISign.DefSQStaticMethod(engine, &AISign::GetMaxSignID, "GetMaxSignID", 1, "x");
-	SQAISign.DefSQStaticMethod(engine, &AISign::GetSignCount, "GetSignCount", 1, "x");
 	SQAISign.DefSQStaticMethod(engine, &AISign::IsValidSign,  "IsValidSign",  2, "xi");
 	SQAISign.DefSQStaticMethod(engine, &AISign::GetText,      "GetText",      2, "xi");
 	SQAISign.DefSQStaticMethod(engine, &AISign::GetLocation,  "GetLocation",  2, "xi");
--- a/src/ai/api/ai_station.cpp	Thu May 29 12:52:24 2008 +0000
+++ b/src/ai/api/ai_station.cpp	Thu May 29 15:56:32 2008 +0000
@@ -79,7 +79,7 @@
 		DEBUG(ai, 0, "GetCoverageRadius(): coverage radius of airports needs to be requested via AIAirport::GetAirportCoverageRadius(), as it requires AirportType");
 		return -1;
 	}
-	if (!_settings.station.modified_catchment) return CA_UNMODIFIED;
+	if (!_settings_game.station.modified_catchment) return CA_UNMODIFIED;
 
 	switch (type) {
 		case STATION_TRAIN:      return CA_TRAIN;
--- a/src/ai/api/ai_tile.cpp	Thu May 29 12:52:24 2008 +0000
+++ b/src/ai/api/ai_tile.cpp	Thu May 29 15:56:32 2008 +0000
@@ -107,7 +107,7 @@
 	if (!::IsValidTile(tile)) return false;
 
 	AcceptedCargo accepts;
-	::GetAcceptanceAroundTiles(accepts, tile, width, height, _settings.station.modified_catchment ? radius : (uint)CA_UNMODIFIED);
+	::GetAcceptanceAroundTiles(accepts, tile, width, height, _settings_game.station.modified_catchment ? radius : (uint)CA_UNMODIFIED);
 	return accepts[cargo_type];
 }
 
@@ -116,7 +116,7 @@
 	if (!::IsValidTile(tile)) return false;
 
 	AcceptedCargo produced;
-	::GetProductionAroundTiles(produced, tile, width, height, _settings.station.modified_catchment ? radius : (uint)CA_UNMODIFIED);
+	::GetProductionAroundTiles(produced, tile, width, height, _settings_game.station.modified_catchment ? radius : (uint)CA_UNMODIFIED);
 	return produced[cargo_type];
 }
 
--- a/src/ai/api/ai_tilelist.cpp	Thu May 29 12:52:24 2008 +0000
+++ b/src/ai/api/ai_tilelist.cpp	Thu May 29 15:56:32 2008 +0000
@@ -87,7 +87,7 @@
 		if (!cargo_accepts) return;
 	}
 
-	if (!_settings.station.modified_catchment) radius = CA_UNMODIFIED;
+	if (!_settings_game.station.modified_catchment) radius = CA_UNMODIFIED;
 
 	BEGIN_TILE_LOOP(cur_tile, i->width + radius * 2, i->height + radius * 2, i->xy - ::TileDiffXY(radius, radius)) {
 		if (!::IsValidTile(cur_tile)) continue;
@@ -126,7 +126,7 @@
 		if (!cargo_produces) return;
 	}
 
-	if (!_settings.station.modified_catchment) radius = CA_UNMODIFIED;
+	if (!_settings_game.station.modified_catchment) radius = CA_UNMODIFIED;
 
 	BEGIN_TILE_LOOP(cur_tile, i->width + radius * 2, i->height + radius * 2, i->xy - ::TileDiffXY(radius, radius)) {
 		if (!::IsValidTile(cur_tile)) continue;
--- a/src/aircraft_cmd.cpp	Thu May 29 12:52:24 2008 +0000
+++ b/src/aircraft_cmd.cpp	Thu May 29 15:56:32 2008 +0000
@@ -288,7 +288,7 @@
 	}
 
 	UnitID unit_num = HasBit(p2, 0) ? 0 : GetFreeUnitNumber(VEH_AIRCRAFT);
-	if (unit_num > _settings.vehicle.max_aircraft)
+	if (unit_num > _settings_game.vehicle.max_aircraft)
 		return_cmd_error(STR_00E1_TOO_MANY_VEHICLES_IN_GAME);
 
 	if (flags & DC_EXEC) {
@@ -405,7 +405,7 @@
 		v->u.air.targetairport = GetStationIndex(tile);
 		v->SetNext(u);
 
-		v->service_interval = _settings.vehicle.servint_aircraft;
+		v->service_interval = _settings_game.vehicle.servint_aircraft;
 
 		v->date_of_last_service = _date;
 		v->build_year = u->build_year = _cur_year;
@@ -665,7 +665,7 @@
 
 static void CheckIfAircraftNeedsService(Vehicle *v)
 {
-	if (_settings.vehicle.servint_aircraft == 0 || !v->NeedsAutomaticServicing()) return;
+	if (_settings_game.vehicle.servint_aircraft == 0 || !v->NeedsAutomaticServicing()) return;
 	if (v->IsInDepot()) {
 		VehicleServiceInDepot(v);
 		return;
@@ -888,7 +888,7 @@
 
 	/* Adjust speed limits by plane speed factor to prevent taxiing
 	 * and take-off speeds being too low. */
-	speed_limit *= _settings.vehicle.plane_speed;
+	speed_limit *= _settings_game.vehicle.plane_speed;
 
 	if (v->u.air.cached_max_speed < speed_limit) {
 		if (v->cur_speed < speed_limit) hard_limit = false;
@@ -906,7 +906,7 @@
 	 * speeds to that aircraft do not get to taxi speed straight after
 	 * touchdown. */
 	if (!hard_limit && v->cur_speed > speed_limit) {
-		speed_limit = v->cur_speed - max(1, ((v->cur_speed * v->cur_speed) / 16384) / _settings.vehicle.plane_speed);
+		speed_limit = v->cur_speed - max(1, ((v->cur_speed * v->cur_speed) / 16384) / _settings_game.vehicle.plane_speed);
 	}
 
 	spd = min(v->cur_speed + (spd >> 8) + (v->subspeed < t), speed_limit);
@@ -917,12 +917,12 @@
 	/* updates statusbar only if speed have changed to save CPU time */
 	if (spd != v->cur_speed) {
 		v->cur_speed = spd;
-		if (_settings.gui.vehicle_speed)
+		if (_settings_client.gui.vehicle_speed)
 			InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
 	}
 
 	/* Adjust distance moved by plane speed setting */
-	if (_settings.vehicle.plane_speed > 1) spd /= _settings.vehicle.plane_speed;
+	if (_settings_game.vehicle.plane_speed > 1) spd /= _settings_game.vehicle.plane_speed;
 
 	if (!(v->direction & 1)) spd = spd * 3 / 4;
 
@@ -1605,7 +1605,7 @@
 		AircraftEventHandler_EnterTerminal(v, apc);
 		/* on an airport with helipads, a helicopter will always land there
 		 * and get serviced at the same time - patch setting */
-		if (_settings.order.serviceathelipad) {
+		if (_settings_game.order.serviceathelipad) {
 			if (v->subtype == AIR_HELICOPTER && apc->helipads != NULL) {
 				/* an exerpt of ServiceAircraft, without the invisibility stuff */
 				v->date_of_last_service = _date;
--- a/src/airport.cpp	Thu May 29 12:52:24 2008 +0000
+++ b/src/airport.cpp	Thu May 29 15:56:32 2008 +0000
@@ -477,7 +477,7 @@
 {
 	uint32 mask = 0;
 
-	if (_cur_year <  1960 || _settings.station.always_small_airport) SetBit(mask, 0);  // small airport
+	if (_cur_year <  1960 || _settings_game.station.always_small_airport) SetBit(mask, 0);  // small airport
 	if (_cur_year >= 1955) SetBit(mask, 1); // city airport
 	if (_cur_year >= 1963) SetBit(mask, 2); // heliport
 	if (_cur_year >= 1980) SetBit(mask, 3); // metropolitan airport
--- a/src/airport_gui.cpp	Thu May 29 12:52:24 2008 +0000
+++ b/src/airport_gui.cpp	Thu May 29 15:56:32 2008 +0000
@@ -70,12 +70,12 @@
 	BuildAirToolbarWindow(const WindowDesc *desc, WindowNumber window_number) : Window(desc, window_number)
 	{
 		this->FindWindowPlacementAndResize(desc);
-		if (_settings.gui.link_terraform_toolbar) ShowTerraformToolbar(this);
+		if (_settings_client.gui.link_terraform_toolbar) ShowTerraformToolbar(this);
 	}
 
 	~BuildAirToolbarWindow()
 	{
-		if (_settings.gui.link_terraform_toolbar) DeleteWindowById(WC_SCEN_LAND_GEN, 0);
+		if (_settings_client.gui.link_terraform_toolbar) DeleteWindowById(WC_SCEN_LAND_GEN, 0);
 	}
 
 	virtual void OnPaint()
@@ -178,7 +178,7 @@
 		this->SetWidgetLoweredState(BAW_BTN_DOHILIGHT, _station_show_coverage);
 		this->LowerWidget(_selected_airport_type + BAW_SMALL_AIRPORT);
 
-		if (_settings.economy.station_noise_level) {
+		if (_settings_game.economy.station_noise_level) {
 			ResizeWindowForWidget(this, BAW_BOTTOMPANEL, 0, 10);
 		}
 
@@ -211,14 +211,14 @@
 		airport = GetAirport(_selected_airport_type);
 		SetTileSelectSize(airport->size_x, airport->size_y);
 
-		int rad = _settings.station.modified_catchment ? airport->catchment : (uint)CA_UNMODIFIED;
+		int rad = _settings_game.station.modified_catchment ? airport->catchment : (uint)CA_UNMODIFIED;
 
 		if (_station_show_coverage) SetTileSelectBigSize(-rad, -rad, 2 * rad, 2 * rad);
 
 		this->DrawWidgets();
 
 		/* only show the station (airport) noise, if the noise option is activated */
-		if (_settings.economy.station_noise_level) {
+		if (_settings_game.economy.station_noise_level) {
 			/* show the noise of the selected airport */
 			SetDParam(0, airport->noise_level);
 			DrawString(2, 206, STR_STATION_NOISE, 0);
--- a/src/animated_tile.cpp	Thu May 29 12:52:24 2008 +0000
+++ b/src/animated_tile.cpp	Thu May 29 15:56:32 2008 +0000
@@ -116,7 +116,7 @@
 		return;
 	}
 
-	_animated_tile_count = SlGetFieldLength() / sizeof(*_animated_tile_list);
+	_animated_tile_count = (uint)SlGetFieldLength() / sizeof(*_animated_tile_list);
 
 	/* Determine a nice rounded size for the amount of allocated tiles */
 	_animated_tile_allocated = 256;
--- a/src/autoreplace_gui.cpp	Thu May 29 12:52:24 2008 +0000
+++ b/src/autoreplace_gui.cpp	Thu May 29 15:56:32 2008 +0000
@@ -22,11 +22,12 @@
 #include "engine_func.h"
 #include "engine_base.h"
 #include "window_gui.h"
+#include "engine_gui.h"
 
 #include "table/sprites.h"
 #include "table/strings.h"
 
-void DrawEngineList(VehicleType type, int x, int y, const EngineList eng_list, uint16 min, uint16 max, EngineID selected_id, int count_location, GroupID selected_group);
+void DrawEngineList(VehicleType type, int x, int y, const GUIEngineList *eng_list, uint16 min, uint16 max, EngineID selected_id, int count_location, GroupID selected_group);
 
 static const StringID _rail_types_list[] = {
 	STR_RAIL_VEHICLES,
@@ -142,7 +143,7 @@
 	EngineID sel_engine[2];
 	uint16 count[2];
 	bool wagon_btnstate; ///< true means engine is selected
-	EngineList list[2];
+	GUIEngineList list[2];
 	bool update_left;
 	bool update_right;
 	bool init_lists;
@@ -184,8 +185,8 @@
 		VehicleType type = (VehicleType)this->window_number;
 		byte i = draw_left ? 0 : 1;
 
-		EngineList *list = &this->list[i];
-		list->clear();
+		GUIEngineList *list = &this->list[i];
+		list->Clear();
 
 		const Engine *e;
 		FOR_ALL_ENGINES_OF_TYPE(e, type) {
@@ -208,7 +209,7 @@
 				if (eid == this->sel_engine[0]) continue; // we can't replace an engine into itself (that would be autorenew)
 			}
 
-			list->push_back(eid);
+			*list->Append() = eid;
 			if (eid == this->sel_engine[i]) selected_engine = eid; // The selected engine is still in the list
 		}
 		this->sel_engine[i] = selected_engine; // update which engine we selected (the same or none, if it's not in the list anymore)
@@ -223,8 +224,8 @@
 		if (this->update_left == true) {
 			/* We need to rebuild the left list */
 			GenerateReplaceVehList(this, true);
-			SetVScrollCount(this, this->list[0].size());
-			if (this->init_lists && this->sel_engine[0] == INVALID_ENGINE && this->list[0].size() != 0) {
+			SetVScrollCount(this, this->list[0].Length());
+			if (this->init_lists && this->sel_engine[0] == INVALID_ENGINE && this->list[0].Length() != 0) {
 				this->sel_engine[0] = this->list[0][0];
 			}
 		}
@@ -233,12 +234,12 @@
 			/* Either we got a request to rebuild the right list or the left list selected a different engine */
 			if (this->sel_engine[0] == INVALID_ENGINE) {
 				/* Always empty the right list when nothing is selected in the left list */
-				this->list[1].clear();
+				this->list[1].Clear();
 				this->sel_engine[1] = INVALID_ENGINE;
 			} else {
 				GenerateReplaceVehList(this, false);
-				SetVScroll2Count(this, this->list[1].size());
-				if (this->init_lists && this->sel_engine[1] == INVALID_ENGINE && this->list[1].size() != 0) {
+				SetVScroll2Count(this, this->list[1].Length());
+				if (this->init_lists && this->sel_engine[1] == INVALID_ENGINE && this->list[1].Length() != 0) {
 					this->sel_engine[1] = this->list[1][0];
 				}
 			}
@@ -253,8 +254,6 @@
 	ReplaceVehicleWindow(const WindowDesc *desc, VehicleType vehicletype, GroupID id_g) : Window(desc, vehicletype)
 	{
 		this->wagon_btnstate = true; // start with locomotives (all other vehicles will not read this bool)
-		new (&this->list[0]) EngineList();
-		new (&this->list[1]) EngineList();
 		this->update_left   = true;
 		this->update_right  = true;
 		this->init_lists    = true;
@@ -380,9 +379,9 @@
 		/* Draw the lists */
 		for (byte i = 0; i < 2; i++) {
 			uint widget     = (i == 0) ? RVW_WIDGET_LEFT_MATRIX : RVW_WIDGET_RIGHT_MATRIX;
-			EngineList list = this->list[i]; // which list to draw
+			GUIEngineList *list = &this->list[i]; // which list to draw
 			EngineID start  = i == 0 ? this->vscroll.pos : this->vscroll2.pos; // what is the offset for the start (scrolling)
-			EngineID end    = min((i == 0 ? this->vscroll.cap : this->vscroll2.cap) + start, list.size());
+			EngineID end    = min((i == 0 ? this->vscroll.cap : this->vscroll2.cap) + start, list->Length());
 
 			/* Do the actual drawing */
 			DrawEngineList((VehicleType)this->window_number, this->widget[widget].left + 2, this->widget[widget].top + 1, list, start, end, this->sel_engine[i], i == 0 ? this->widget[RVW_WIDGET_LEFT_MATRIX].right - 2 : 0, selected_group);
@@ -436,7 +435,7 @@
 				uint16 click_scroll_pos = widget == RVW_WIDGET_LEFT_MATRIX ? this->vscroll.pos : this->vscroll2.pos;
 				uint16 click_scroll_cap = widget == RVW_WIDGET_LEFT_MATRIX ? this->vscroll.cap : this->vscroll2.cap;
 				byte click_side         = widget == RVW_WIDGET_LEFT_MATRIX ? 0 : 1;
-				size_t engine_count     = this->list[click_side].size();
+				size_t engine_count     = this->list[click_side].Length();
 
 				if (i < click_scroll_cap) {
 					i += click_scroll_pos;
--- a/src/autoslope.h	Thu May 29 12:52:24 2008 +0000
+++ b/src/autoslope.h	Thu May 29 15:56:32 2008 +0000
@@ -38,7 +38,7 @@
  */
 static inline bool AutoslopeEnabled()
 {
-	return (_settings.construction.autoslope &&
+	return (_settings_game.construction.autoslope &&
 	        (IsValidPlayer(_current_player) ||
 	         (_current_player == OWNER_NONE && _game_mode == GM_EDITOR)));
 }
--- a/src/bridge_gui.cpp	Thu May 29 12:52:24 2008 +0000
+++ b/src/bridge_gui.cpp	Thu May 29 15:56:32 2008 +0000
@@ -22,9 +22,6 @@
 
 #include "table/strings.h"
 
-/* Save the sorting during runtime */
-static Listing _bridge_sorting = {false, 0};
-
 /**
  * Carriage for the data we need if we want to build a bridge
  */
@@ -36,53 +33,6 @@
 
 typedef GUIList<BuildBridgeData> GUIBridgeList;
 
-/** Sort the bridges by their index */
-static int CDECL BridgeIndexSorter(const void *a, const void *b)
-{
-	const BuildBridgeData* ba = (BuildBridgeData*)a;
-	const BuildBridgeData* bb = (BuildBridgeData*)b;
-	int r = ba->index - bb->index;
-
-	return (_bridge_sorting.order) ? -r : r;
-}
-
-/** Sort the bridges by their price */
-static int CDECL BridgePriceSorter(const void *a, const void *b)
-{
-	const BuildBridgeData* ba = (BuildBridgeData*)a;
-	const BuildBridgeData* bb = (BuildBridgeData*)b;
-	int r = ba->cost - bb->cost;
-
-	return (_bridge_sorting.order) ? -r : r;
-}
-
-/** Sort the bridges by their maximum speed */
-static int CDECL BridgeSpeedSorter(const void *a, const void *b)
-{
-	const BuildBridgeData* ba = (BuildBridgeData*)a;
-	const BuildBridgeData* bb = (BuildBridgeData*)b;
-	int r = ba->spec->speed - bb->spec->speed;
-
-	return (_bridge_sorting.order) ? -r : r;
-}
-
-typedef int CDECL BridgeSortListingTypeFunction(const void*, const void*);
-
-/* Availible bridge sorting functions */
-static BridgeSortListingTypeFunction* const _bridge_sorter[] = {
-	&BridgeIndexSorter,
-	&BridgePriceSorter,
-	&BridgeSpeedSorter
-};
-
-/* Names of the sorting functions */
-static const StringID _bridge_sort_listing[] = {
-	STR_SORT_BY_NUMBER,
-	STR_ENGINE_SORT_COST,
-	STR_SORT_BY_MAX_SPEED,
-	INVALID_STRING_ID
-};
-
 /**
  * Callback executed after a build Bridge CMD has been called
  *
@@ -109,33 +59,51 @@
 
 class BuildBridgeWindow : public Window {
 private:
-	/* The last size of the build bridge window
-	 * is saved during runtime */
+	/* Runtime saved values */
 	static uint last_size;
+	static Listing last_sorting;
 
+	/* Constants for sorting the bridges */
+	static const StringID sorter_names[];
+	static GUIBridgeList::SortFunction *const sorter_funcs[];
+
+	/* Internal variables */
 	TileIndex start_tile;
 	TileIndex end_tile;
 	uint32 type;
 	GUIBridgeList *bridges;
 
+	/** Sort the bridges by their index */
+	static int CDECL BridgeIndexSorter(const BuildBridgeData *a, const BuildBridgeData *b)
+	{
+		return a->index - b->index;
+	}
+
+	/** Sort the bridges by their price */
+	static int CDECL BridgePriceSorter(const BuildBridgeData *a, const BuildBridgeData *b)
+	{
+		return a->cost - b->cost;
+	}
+
+	/** Sort the bridges by their maximum speed */
+	static int CDECL BridgeSpeedSorter(const BuildBridgeData *a, const BuildBridgeData *b)
+	{
+		return a->spec->speed - b->spec->speed;
+	}
+
 	void BuildBridge(uint8 i)
 	{
-		DoCommandP(this->end_tile, this->start_tile, this->type | this->bridges->sort_list[i].index,
+		DoCommandP(this->end_tile, this->start_tile, this->type | this->bridges->Get(i)->index,
 				CcBuildBridge, CMD_BUILD_BRIDGE | CMD_MSG(STR_5015_CAN_T_BUILD_BRIDGE_HERE));
 	}
 
 	/** Sort the builable bridges */
 	void SortBridgeList()
 	{
-		/* Skip sorting if resort bit is not set */
-		if (!(bridges->flags & VL_RESORT)) return;
-
-		qsort(this->bridges->sort_list, this->bridges->list_length, sizeof(this->bridges->sort_list[0]), _bridge_sorter[_bridge_sorting.criteria]);
+		this->bridges->Sort();
 
 		/* Display the current sort variant */
-		this->widget[BBSW_DROPDOWN_CRITERIA].data = _bridge_sort_listing[this->bridges->sort_type];
-
-		bridges->flags &= ~VL_RESORT;
+		this->widget[BBSW_DROPDOWN_CRITERIA].data = this->sorter_names[this->bridges->SortType()];
 
 		/* Set the modified widgets dirty */
 		this->InvalidateWidget(BBSW_DROPDOWN_CRITERIA);
@@ -149,13 +117,15 @@
 		type(br_type),
 		bridges(bl)
 	{
+		this->bridges->SetListing(this->last_sorting);
+		this->bridges->SetSortFuncs(this->sorter_funcs);
 		this->SortBridgeList();
 
 		/* Change the data, or the caption of the gui. Set it to road or rail, accordingly */
 		this->widget[BBSW_CAPTION].data = (GB(this->type, 15, 2) == TRANSPORT_ROAD) ? STR_1803_SELECT_ROAD_BRIDGE : STR_100D_SELECT_RAIL_BRIDGE;
 
 		this->resize.step_height = 22;
-		this->vscroll.count = bl->list_length;
+		this->vscroll.count = bl->Length();
 
 		if (this->last_size <= 4) {
 			this->vscroll.cap = 4;
@@ -171,7 +141,8 @@
 
 	~BuildBridgeWindow()
 	{
-		free(this->bridges->sort_list);
+		this->last_sorting = this->bridges->GetListing();
+
 		delete bridges;
 	}
 
@@ -183,10 +154,10 @@
 
 		uint y = this->widget[BBSW_BRIDGE_LIST].top + 2;
 
-		for (int i = this->vscroll.pos; (i < (this->vscroll.cap + this->vscroll.pos)) && (i < this->bridges->list_length); i++) {
-			const BridgeSpec *b = this->bridges->sort_list[i].spec;
+		for (int i = this->vscroll.pos; (i < (this->vscroll.cap + this->vscroll.pos)) && (i < (int)this->bridges->Length()); i++) {
+			const BridgeSpec *b = this->bridges->Get(i)->spec;
 
-			SetDParam(2, this->bridges->sort_list[i].cost);
+			SetDParam(2, this->bridges->Get(i)->cost);
 			SetDParam(1, b->speed * 10 / 16);
 			SetDParam(0, b->material);
 
@@ -200,7 +171,7 @@
 	virtual EventState OnKeyPress(uint16 key, uint16 keycode)
 	{
 		const uint8 i = keycode - '1';
-		if (i < 9 && i < this->bridges->list_length) {
+		if (i < 9 && i < this->bridges->Length()) {
 			/* Build the requested bridge */
 			this->BuildBridge(i);
 			delete this;
@@ -217,7 +188,7 @@
 				uint i = ((int)pt.y - this->widget[BBSW_BRIDGE_LIST].top) / this->resize.step_height;
 				if (i < this->vscroll.cap) {
 					i += this->vscroll.pos;
-					if (i < this->bridges->list_length) {
+					if (i < this->bridges->Length()) {
 						this->BuildBridge(i);
 						delete this;
 					}
@@ -225,27 +196,21 @@
 			} break;
 
 			case BBSW_DROPDOWN_ORDER:
-				/* Revers the sort order */
-				this->bridges->flags ^= VL_DESC;
-				_bridge_sorting.order = !_bridge_sorting.order;
-
-				this->bridges->flags |= VL_RESORT;
-				this->SortBridgeList();
+				this->bridges->ToggleSortOrder();
+				this->SetDirty();
 				break;
 
 			case BBSW_DROPDOWN_CRITERIA:
-				ShowDropDownMenu(this, _bridge_sort_listing, bridges->sort_type, BBSW_DROPDOWN_CRITERIA, 0, 0);
+				ShowDropDownMenu(this, this->sorter_names, this->bridges->SortType(), BBSW_DROPDOWN_CRITERIA, 0, 0);
 				break;
 		}
 	}
 
 	virtual void OnDropdownSelect(int widget, int index)
 	{
-		if (widget == BBSW_DROPDOWN_CRITERIA && this->bridges->sort_type != index) {
-			this->bridges->sort_type = index;
-			_bridge_sorting.criteria = index;
+		if (widget == BBSW_DROPDOWN_CRITERIA && this->bridges->SortType() != index) {
+			this->bridges->SetSortType(index);
 
-			this->bridges->flags |= VL_RESORT;
 			this->SortBridgeList();
 		}
 	}
@@ -254,7 +219,7 @@
 	{
 		this->vscroll.cap += delta.y / (int)this->resize.step_height;
 		this->widget[BBSW_BRIDGE_LIST].data = (this->vscroll.cap << 8) + 1;
-		SetVScrollCount(this, this->bridges->list_length);
+		SetVScrollCount(this, this->bridges->Length());
 
 		this->last_size = this->vscroll.cap;
 	}
@@ -262,6 +227,23 @@
 
 /* Set the default size of the Build Bridge Window */
 uint BuildBridgeWindow::last_size = 4;
+/* Set the default sorting for the bridges */
+Listing BuildBridgeWindow::last_sorting = {false, 0};
+
+/* Availible bridge sorting functions */
+GUIBridgeList::SortFunction* const BuildBridgeWindow::sorter_funcs[] = {
+	&BridgeIndexSorter,
+	&BridgePriceSorter,
+	&BridgeSpeedSorter
+};
+
+/* Names of the sorting functions */
+const StringID BuildBridgeWindow::sorter_names[] = {
+	STR_SORT_BY_NUMBER,
+	STR_ENGINE_SORT_COST,
+	STR_SORT_BY_MAX_SPEED,
+	INVALID_STRING_ID
+};
 
 /* Widget definition for the rail bridge selection window */
 static const Widget _build_bridge_widgets[] = {
@@ -286,35 +268,6 @@
 };
 
 /**
- * Add a buildable bridge to the list.
- *  If the list is empty a new one is created.
- *
- * @param bl The list which we want to manage
- * @param item The item to add
- * @return The pointer to the list
- */
-static GUIBridgeList *PushBridgeList(GUIBridgeList *bl, BuildBridgeData item)
-{
-	if (bl == NULL) {
-		/* Create the list if needed */
-		bl = new GUIBridgeList();
-		bl->flags |= VL_RESORT;
-		if (_bridge_sorting.order) bl->flags |= VL_DESC;
-		bl->list_length = 1;
-		bl->sort_type = _bridge_sorting.criteria;
-	} else {
-		/* Resize the list */
-		bl->list_length++;
-	}
-
-	bl->sort_list = ReallocT(bl->sort_list, bl->list_length);
-
-	bl->sort_list[bl->list_length - 1] = item;
-
-	return bl;
-}
-
-/**
  * Prepare the data for the build a bridge window.
  *  If we can't build a bridge under the given conditions
  *  show an error message.
@@ -350,24 +303,26 @@
 		/* total length of bridge */
 		const uint tot_bridgedata_len = CalcBridgeLenCostFactor(bridge_len + 2);
 
+		bl = new GUIBridgeList();
+
 		/* loop for all bridgetypes */
 		for (BridgeType brd_type = 0; brd_type != MAX_BRIDGES; brd_type++) {
 			if (CheckBridge_Stuff(brd_type, bridge_len)) {
 				/* bridge is accepted, add to list */
-				BuildBridgeData item;
-				item.index = brd_type;
-				item.spec = GetBridgeSpec(brd_type);
+				BuildBridgeData *item = bl->Append();
+				item->index = brd_type;
+				item->spec = GetBridgeSpec(brd_type);
 				/* Add to terraforming & bulldozing costs the cost of the
 				 * bridge itself (not computed with DC_QUERY_COST) */
-				item.cost = ret.GetCost() + (((int64)tot_bridgedata_len * _price.build_bridge * item.spec->price) >> 8);
-				bl = PushBridgeList(bl, item);
+				item->cost = ret.GetCost() + (((int64)tot_bridgedata_len * _price.build_bridge * item->spec->price) >> 8);
 			}
 		}
 	}
 
-	if (bl != NULL) {
+	if (bl != NULL && bl->Length() != 0) {
 		new BuildBridgeWindow(&_build_bridge_desc, start, end, type, bl);
 	} else {
+		if (bl != NULL) delete bl;
 		ShowErrorMessage(errmsg, STR_5015_CAN_T_BUILD_BRIDGE_HERE, TileX(end) * TILE_SIZE, TileY(end) * TILE_SIZE);
 	}
 }
--- a/src/build_vehicle_gui.cpp	Thu May 29 12:52:24 2008 +0000
+++ b/src/build_vehicle_gui.cpp	Thu May 29 15:56:32 2008 +0000
@@ -29,6 +29,7 @@
 #include "widgets/dropdown_func.h"
 #include "string_func.h"
 #include "window_gui.h"
+#include "engine_gui.h"
 
 #include "table/sprites.h"
 #include "table/strings.h"
@@ -506,7 +507,7 @@
 	y += 10;
 
 	/* Wagon speed limit, displayed if above zero */
-	if (_settings.vehicle.wagon_speed_limits) {
+	if (_settings_game.vehicle.wagon_speed_limits) {
 		uint max_speed = GetEngineProperty(engine_number, 0x09, rvi->max_speed);
 		if (max_speed > 0) {
 			SetDParam(0, max_speed * 10 / 16);
@@ -544,7 +545,7 @@
 	y += 10;
 
 	/* Max tractive effort - not applicable if old acceleration or maglev */
-	if (_settings.vehicle.realistic_acceleration && rvi->railtype != RAILTYPE_MAGLEV) {
+	if (_settings_game.vehicle.realistic_acceleration && rvi->railtype != RAILTYPE_MAGLEV) {
 		SetDParam(0, ((weight << multihead) * 10 * GetEngineProperty(engine_number, 0x1F, rvi->tractive_effort)) / 256);
 		DrawString(x, y, STR_PURCHASE_INFO_MAX_TE, TC_FROMSTRING);
 		y += 10;
@@ -744,13 +745,13 @@
  * @param selected_id what engine to highlight as selected, if any
  * @param count_location Offset to print the engine count (used by autoreplace). 0 means it's off
  */
-void DrawEngineList(VehicleType type, int x, int y, const EngineList eng_list, uint16 min, uint16 max, EngineID selected_id, int count_location, GroupID selected_group)
+void DrawEngineList(VehicleType type, int x, int y, const GUIEngineList *eng_list, uint16 min, uint16 max, EngineID selected_id, int count_location, GroupID selected_group)
 {
 	byte step_size = GetVehicleListHeight(type);
 	byte x_offset = 0;
 	byte y_offset = 0;
 
-	assert(max <= eng_list.size());
+	assert(max <= eng_list->Length());
 
 	switch (type) {
 		case VEH_TRAIN:
@@ -778,7 +779,7 @@
 	}
 
 	for (; min < max; min++, y += step_size) {
-		const EngineID engine = eng_list[min];
+		const EngineID engine = (*eng_list)[min];
 		/* Note: num_engines is only used in the autoreplace GUI, so it is correct to use _local_player here. */
 		const uint num_engines = GetGroupNumEngines(_local_player, selected_group, engine);
 
@@ -805,7 +806,7 @@
 	bool regenerate_list;
 	EngineID sel_engine;
 	EngineID rename_engine;
-	EngineList eng_list;
+	GUIEngineList eng_list;
 
 	BuildVehicleWindow(const WindowDesc *desc, TileIndex tile, VehicleType type) : Window(desc, tile == 0 ? (int)type : tile)
 	{
@@ -847,7 +848,7 @@
 
 		this->GenerateBuildList(); // generate the list, since we need it in the next line
 		/* Select the first engine in the list as default when opening the window */
-		if (this->eng_list.size() > 0) this->sel_engine = this->eng_list[0];
+		if (this->eng_list.Length() > 0) this->sel_engine = this->eng_list[0];
 
 		this->FindWindowPlacementAndResize(desc);
 	}
@@ -905,7 +906,7 @@
 
 		this->filter.railtype = (this->window_number <= VEH_END) ? RAILTYPE_END : GetRailType(this->window_number);
 
-		this->eng_list.clear();
+		this->eng_list.Clear();
 
 		/* Make list of all available train engines and wagons.
 		* Also check to see if the previously selected engine is still available,
@@ -919,7 +920,8 @@
 			if (this->filter.railtype != RAILTYPE_END && !HasPowerOnRail(rvi->railtype, this->filter.railtype)) continue;
 			if (!IsEngineBuildable(eid, VEH_TRAIN, _local_player)) continue;
 
-			this->eng_list.push_back(eid);
+			*this->eng_list.Append() = eid;
+
 			if (rvi->railveh_type != RAILVEH_WAGON) {
 				num_engines++;
 			} else {
@@ -948,14 +950,14 @@
 	{
 		EngineID sel_id = INVALID_ENGINE;
 
-		this->eng_list.clear();
+		this->eng_list.Clear();
 
 		const Engine *e;
 		FOR_ALL_ENGINES_OF_TYPE(e, VEH_ROAD) {
 			EngineID eid = e->index;
 			if (!IsEngineBuildable(eid, VEH_ROAD, _local_player)) continue;
 			if (!HasBit(this->filter.roadtypes, HasBit(EngInfo(eid)->misc_flags, EF_ROAD_TRAM) ? ROADTYPE_TRAM : ROADTYPE_ROAD)) continue;
-			this->eng_list.push_back(eid);
+			*this->eng_list.Append() = eid;
 
 			if (eid == this->sel_engine) sel_id = eid;
 		}
@@ -966,13 +968,13 @@
 	void GenerateBuildShipList()
 	{
 		EngineID sel_id = INVALID_ENGINE;
-		this->eng_list.clear();
+		this->eng_list.Clear();
 
 		const Engine *e;
 		FOR_ALL_ENGINES_OF_TYPE(e, VEH_SHIP) {
 			EngineID eid = e->index;
 			if (!IsEngineBuildable(eid, VEH_SHIP, _local_player)) continue;
-			this->eng_list.push_back(eid);
+			*this->eng_list.Append() = eid;
 
 			if (eid == this->sel_engine) sel_id = eid;
 		}
@@ -984,7 +986,7 @@
 	{
 		EngineID sel_id = INVALID_ENGINE;
 
-		this->eng_list.clear();
+		this->eng_list.Clear();
 
 		/* Make list of all available planes.
 		* Also check to see if the previously selected plane is still available,
@@ -997,7 +999,7 @@
 			/* First VEH_END window_numbers are fake to allow a window open for all different types at once */
 			if (this->window_number > VEH_END && !CanAircraftUseStation(eid, this->window_number)) continue;
 
-			this->eng_list.push_back(eid);
+			*this->eng_list.Append() = eid;
 			if (eid == this->sel_engine) sel_id = eid;
 		}
 
@@ -1038,7 +1040,7 @@
 
 			case BUILD_VEHICLE_WIDGET_LIST: {
 				uint i = (pt.y - this->widget[BUILD_VEHICLE_WIDGET_LIST].top) / GetVehicleListHeight(this->vehicle_type) + this->vscroll.pos;
-				size_t num_items = this->eng_list.size();
+				size_t num_items = this->eng_list.Length();
 				this->sel_engine = (i < num_items) ? this->eng_list[i] : INVALID_ENGINE;
 				this->SetDirty();
 				break;
@@ -1104,11 +1106,11 @@
 			this->GenerateBuildList();
 		}
 
-		uint max = min(this->vscroll.pos + this->vscroll.cap, this->eng_list.size());
+		uint max = min(this->vscroll.pos + this->vscroll.cap, this->eng_list.Length());
 
 		this->SetWidgetDisabledState(BUILD_VEHICLE_WIDGET_BUILD, this->window_number <= VEH_END);
 
-		SetVScrollCount(this, this->eng_list.size());
+		SetVScrollCount(this, this->eng_list.Length());
 		SetDParam(0, this->filter.railtype + STR_881C_NEW_RAIL_VEHICLES); // This should only affect rail vehicles
 
 		/* Set text of sort by dropdown */
@@ -1116,7 +1118,7 @@
 
 		this->DrawWidgets();
 
-		DrawEngineList(this->vehicle_type, this->widget[BUILD_VEHICLE_WIDGET_LIST].left + 2, this->widget[BUILD_VEHICLE_WIDGET_LIST].top + 1, this->eng_list, this->vscroll.pos, max, this->sel_engine, 0, DEFAULT_GROUP);
+		DrawEngineList(this->vehicle_type, this->widget[BUILD_VEHICLE_WIDGET_LIST].left + 2, this->widget[BUILD_VEHICLE_WIDGET_LIST].top + 1, &this->eng_list, this->vscroll.pos, max, this->sel_engine, 0, DEFAULT_GROUP);
 
 		if (this->sel_engine != INVALID_ENGINE) {
 			const Widget *wi = &this->widget[BUILD_VEHICLE_WIDGET_PANEL];
--- a/src/cheat.cpp	Thu May 29 12:52:24 2008 +0000
+++ b/src/cheat.cpp	Thu May 29 15:56:32 2008 +0000
@@ -30,7 +30,7 @@
 static void Load_CHTS()
 {
 	Cheat *cht = (Cheat*)&_cheats;
-	uint count = SlGetFieldLength() / 2;
+	size_t count = SlGetFieldLength() / 2;
 
 	for (uint i = 0; i < count; i++) {
 		cht[i].been_used = (SlReadByte() != 0);
--- a/src/cheat_gui.cpp	Thu May 29 12:52:24 2008 +0000
+++ b/src/cheat_gui.cpp	Thu May 29 15:56:32 2008 +0000
@@ -64,9 +64,9 @@
 {
 	if (p1 == -1) p1 = 3;
 	if (p1 ==  4) p1 = 0;
-	_settings.game_creation.landscape = p1;
+	_settings_game.game_creation.landscape = p1;
 	ReloadNewGRFData();
-	return _settings.game_creation.landscape;
+	return _settings_game.game_creation.landscape;
 }
 
 extern void EnginesMonthlyLoop();
@@ -107,7 +107,7 @@
 	{SLE_BOOL,  STR_CHEAT_BUILD_IN_PAUSE,  &_cheats.build_in_pause.value,      &_cheats.build_in_pause.been_used,   NULL                    },
 	{SLE_BOOL,  STR_CHEAT_NO_JETCRASH,     &_cheats.no_jetcrash.value,         &_cheats.no_jetcrash.been_used,      NULL                    },
 	{SLE_BOOL,  STR_CHEAT_SETUP_PROD,      &_cheats.setup_prod.value,          &_cheats.setup_prod.been_used,       NULL                    },
-	{SLE_UINT8, STR_CHEAT_SWITCH_CLIMATE,  &_settings.game_creation.landscape, &_cheats.switch_climate.been_used,   &ClickChangeClimateCheat},
+	{SLE_UINT8, STR_CHEAT_SWITCH_CLIMATE,  &_settings_game.game_creation.landscape, &_cheats.switch_climate.been_used,   &ClickChangeClimateCheat},
 	{SLE_INT32, STR_CHEAT_CHANGE_DATE,     &_cur_year,                         &_cheats.change_date.been_used,      &ClickChangeDateCheat   },
 };
 
--- a/src/clear_cmd.cpp	Thu May 29 12:52:24 2008 +0000
+++ b/src/clear_cmd.cpp	Thu May 29 15:56:32 2008 +0000
@@ -218,7 +218,7 @@
 {
 	TileLoopClearHelper(tile);
 
-	switch (_settings.game_creation.landscape) {
+	switch (_settings_game.game_creation.landscape) {
 		case LT_TROPIC: TileLoopClearDesert(tile); break;
 		case LT_ARCTIC: TileLoopClearAlps(tile);   break;
 	}
@@ -346,7 +346,7 @@
 
 void InitializeClearLand()
 {
-	_settings.game_creation.snow_line = _settings.game_creation.snow_line_height * TILE_HEIGHT;
+	_settings_game.game_creation.snow_line = _settings_game.game_creation.snow_line_height * TILE_HEIGHT;
 }
 
 static CommandCost TerraformTile_Clear(TileIndex tile, uint32 flags, uint z_new, Slope tileh_new)
--- a/src/console_cmds.cpp	Thu May 29 12:52:24 2008 +0000
+++ b/src/console_cmds.cpp	Thu May 29 15:56:32 2008 +0000
@@ -927,8 +927,8 @@
 	}
 
 	/* Don't copy the _newgame pointers to the real pointers, so call SwitchMode directly */
-	_settings.game_creation.map_x = MapLogX();
-	_settings.game_creation.map_y = FindFirstBit(MapSizeY());
+	_settings_game.game_creation.map_x = MapLogX();
+	_settings_game.game_creation.map_y = FindFirstBit(MapSizeY());
 	SwitchMode(SM_NEWGAME);
 	return true;
 }
@@ -990,7 +990,7 @@
 		return true;
 	}
 
-	IConsolePrintF(CC_DEFAULT, "Generation Seed: %u", _settings.game_creation.generation_seed);
+	IConsolePrintF(CC_DEFAULT, "Generation Seed: %u", _settings_game.game_creation.generation_seed);
 	return true;
 }
 
@@ -1133,7 +1133,7 @@
 		return true;
 	}
 
-	if (_game_mode == GM_NORMAL && _settings.gui.autosave_on_exit) DoExitSave();
+	if (_game_mode == GM_NORMAL && _settings_client.gui.autosave_on_exit) DoExitSave();
 
 	_exit_game = true;
 	return true;
--- a/src/core/bitmath_func.hpp	Thu May 29 12:52:24 2008 +0000
+++ b/src/core/bitmath_func.hpp	Thu May 29 15:56:32 2008 +0000
@@ -97,7 +97,7 @@
  * @param y The second value
  * @return True if at least one bit is set in both values, false else.
  */
-#define HASBITS(x, y) ((x) & (y))
+#define HASBITS(x, y) (((x) & (y)) != 0)
 
 /**
  * Set a bit in a variable.
--- a/src/currency.cpp	Thu May 29 12:52:24 2008 +0000
+++ b/src/currency.cpp	Thu May 29 15:56:32 2008 +0000
@@ -150,10 +150,10 @@
  **/
 void CheckSwitchToEuro()
 {
-	if (_currency_specs[_settings.gui.currency].to_euro != CF_NOEURO &&
-			_currency_specs[_settings.gui.currency].to_euro != CF_ISEURO &&
-			_cur_year >= _currency_specs[_settings.gui.currency].to_euro) {
-		_settings.gui.currency = 2; // this is the index of euro above.
+	if (_currency_specs[_settings_client.gui.currency].to_euro != CF_NOEURO &&
+			_currency_specs[_settings_client.gui.currency].to_euro != CF_ISEURO &&
+			_cur_year >= _currency_specs[_settings_client.gui.currency].to_euro) {
+		_settings_client.gui.currency = 2; // this is the index of euro above.
 		AddNewsItem(STR_EURO_INTRODUCE, NS_ECONOMY, 0, 0);
 	}
 }
--- a/src/currency.h	Thu May 29 12:52:24 2008 +0000
+++ b/src/currency.h	Thu May 29 15:56:32 2008 +0000
@@ -39,7 +39,7 @@
 
 // XXX small hack, but makes the rest of the code a bit nicer to read
 #define _custom_currency (_currency_specs[CUSTOM_CURRENCY_ID])
-#define _currency ((const CurrencySpec*)&_currency_specs[(_game_mode == GM_MENU) ? _settings_newgame.gui.currency : _settings.gui.currency])
+#define _currency ((const CurrencySpec*)&_currency_specs[_settings_client.gui.currency])
 
 uint GetMaskOfAllowedCurrencies();
 void CheckSwitchToEuro();
--- a/src/date.cpp	Thu May 29 12:52:24 2008 +0000
+++ b/src/date.cpp	Thu May 29 15:56:32 2008 +0000
@@ -257,7 +257,7 @@
 		SaveOrLoad(name, SL_SAVE, AUTOSAVE_DIR);
 		DebugDumpCommands("ddc:save:%s\n", name);
 #endif /* DUMP_COMMANDS */
-		if (_settings.gui.autosave != 0 && (_cur_month % _autosave_months[_settings.gui.autosave]) == 0) {
+		if (_settings_client.gui.autosave != 0 && (_cur_month % _autosave_months[_settings_client.gui.autosave]) == 0) {
 			_do_autosave = true;
 			RedrawAutosave();
 		}
@@ -283,10 +283,10 @@
 	ShipsYearlyLoop();
 	if (_network_server) NetworkServerYearlyLoop();
 
-	if (_cur_year == _settings.gui.semaphore_build_before) ResetSignalVariant();
+	if (_cur_year == _settings_client.gui.semaphore_build_before) ResetSignalVariant();
 
 	/* check if we reached end of the game */
-	if (_cur_year == _settings.gui.ending_year) {
+	if (_cur_year == _settings_client.gui.ending_year) {
 			ShowEndGameChart();
 	/* check if we reached the maximum year, decrement dates by a year */
 	} else if (_cur_year == MAX_YEAR + 1) {
@@ -303,5 +303,5 @@
 		InitChatMessage();
 	}
 
-	if (_settings.gui.auto_euro) CheckSwitchToEuro();
+	if (_settings_client.gui.auto_euro) CheckSwitchToEuro();
 }
--- a/src/debug.cpp	Thu May 29 12:52:24 2008 +0000
+++ b/src/debug.cpp	Thu May 29 15:56:32 2008 +0000
@@ -74,7 +74,7 @@
 		char buf2[lengthof(buf) + 32];
 
 		snprintf(buf2, lengthof(buf2), "dbg: [%s] %s\n", dbg, buf);
-		send(_debug_socket, buf2, strlen(buf2), 0);
+		send(_debug_socket, buf2, (int)strlen(buf2), 0);
 	} else
 #endif /* ENABLE_NETWORK */
 	{
--- a/src/depot_gui.cpp	Thu May 29 12:52:24 2008 +0000
+++ b/src/depot_gui.cpp	Thu May 29 15:56:32 2008 +0000
@@ -26,6 +26,7 @@
 #include "depot_base.h"
 #include "tilehighlight_func.h"
 #include "window_gui.h"
+#include "vehiclelist.h"
 
 #include "table/strings.h"
 #include "table/sprites.h"
--- a/src/disaster_cmd.cpp	Thu May 29 12:52:24 2008 +0000
+++ b/src/disaster_cmd.cpp	Thu May 29 15:56:32 2008 +0000
@@ -1050,7 +1050,7 @@
 
 	ResetDisasterDelay();
 
-	if (_settings.difficulty.disasters != 0) DoDisaster();
+	if (_settings_game.difficulty.disasters != 0) DoDisaster();
 }
 
 void StartupDisasters()
--- a/src/dock_gui.cpp	Thu May 29 12:52:24 2008 +0000
+++ b/src/dock_gui.cpp	Thu May 29 15:56:32 2008 +0000
@@ -136,12 +136,12 @@
 	BuildDocksToolbarWindow(const WindowDesc *desc, WindowNumber window_number) : Window(desc, window_number)
 	{
 		this->FindWindowPlacementAndResize(desc);
-		if (_settings.gui.link_terraform_toolbar) ShowTerraformToolbar(this);
+		if (_settings_client.gui.link_terraform_toolbar) ShowTerraformToolbar(this);
 	}
 
 	~BuildDocksToolbarWindow()
 	{
-		if (_settings.gui.link_terraform_toolbar) DeleteWindowById(WC_SCEN_LAND_GEN, 0);
+		if (_settings_client.gui.link_terraform_toolbar) DeleteWindowById(WC_SCEN_LAND_GEN, 0);
 	}
 
 	virtual void OnPaint()
@@ -263,7 +263,7 @@
 
 	virtual void OnPaint()
 	{
-		int rad = (_settings.station.modified_catchment) ? CA_DOCK : CA_UNMODIFIED;
+		int rad = (_settings_game.station.modified_catchment) ? CA_DOCK : CA_UNMODIFIED;
 
 		this->DrawWidgets();
 
--- a/src/economy.cpp	Thu May 29 12:52:24 2008 +0000
+++ b/src/economy.cpp	Thu May 29 15:56:32 2008 +0000
@@ -663,7 +663,7 @@
 	 * inflation doesn't add anything after that either; it even makes playing
 	 * it impossible due to the diverging cost and income rates.
 	 */
-	if ((_cur_year - _settings.game_creation.starting_year) >= (ORIGINAL_MAX_YEAR - ORIGINAL_BASE_YEAR)) return;
+	if ((_cur_year - _settings_game.game_creation.starting_year) >= (ORIGINAL_MAX_YEAR - ORIGINAL_BASE_YEAR)) return;
 
 	/* Approximation for (100 + infl_amount)% ** (1 / 12) - 100%
 	 * scaled by 65536
@@ -713,7 +713,7 @@
 
 static void HandleEconomyFluctuations()
 {
-	if (_settings.difficulty.economy == 0) return;
+	if (_settings_game.difficulty.economy == 0) return;
 
 	if (--_economy.fluct == 0) {
 		_economy.fluct = -(int)GB(Random(), 0, 2);
@@ -822,7 +822,7 @@
 	for (i = 0; i != NUM_PRICES; i++) {
 		Money price = _price_base[i];
 		if (_price_category[i] != 0) {
-			uint mod = _price_category[i] == 1 ? _settings.difficulty.vehicle_costs : _settings.difficulty.construction_cost;
+			uint mod = _price_category[i] == 1 ? _settings_game.difficulty.vehicle_costs : _settings_game.difficulty.construction_cost;
 			if (mod < 1) {
 				price = price * 3 >> 2;
 			} else if (mod > 1) {
@@ -838,10 +838,10 @@
 		_price_frac[i] = 0;
 	}
 
-	_economy.interest_rate = _settings.difficulty.initial_interest;
-	_economy.infl_amount = _settings.difficulty.initial_interest;
-	_economy.infl_amount_pr = max(0, _settings.difficulty.initial_interest - 1);
-	_economy.max_loan_unround = _economy.max_loan = _settings.difficulty.max_loan;
+	_economy.interest_rate = _settings_game.difficulty.initial_interest;
+	_economy.infl_amount = _settings_game.difficulty.initial_interest;
+	_economy.infl_amount_pr = max(0, _settings_game.difficulty.initial_interest - 1);
+	_economy.max_loan_unround = _economy.max_loan = _settings_game.difficulty.max_loan;
 	_economy.fluct = GB(Random(), 0, 8) + 168;
 }
 
@@ -1180,7 +1180,7 @@
 	}
 
 	/* zero the distance (thus income) if it's the bank and very short transport. */
-	if (_settings.game_creation.landscape == LT_TEMPERATE && cs->label == 'VALU' && dist < 10) return 0;
+	if (_settings_game.game_creation.landscape == LT_TEMPERATE && cs->label == 'VALU' && dist < 10) return 0;
 
 
 	static const int MIN_TIME_FACTOR = 31;
@@ -1226,7 +1226,7 @@
 	 * XXX - Think of something better to
 	 *       1) Only deliver to industries which are withing the catchment radius
 	 *       2) Distribute between industries if more then one is present */
-	best_dist = (_settings.station.station_spread + 8) * 2;
+	best_dist = (_settings_game.station.station_spread + 8) * 2;
 	FOR_ALL_INDUSTRIES(ind) {
 		indspec = GetIndustrySpec(ind->type);
 		uint i;
@@ -1331,7 +1331,7 @@
 
 			SetDParam(0, _current_player);
 			AddNewsItem(
-				STR_2031_SERVICE_SUBSIDY_AWARDED + _settings.difficulty.subsidy_multiplier,
+				STR_2031_SERVICE_SUBSIDY_AWARDED + _settings_game.difficulty.subsidy_multiplier,
 				NS_SUBSIDIES,
 				pair.a, pair.b
 			);
@@ -1381,7 +1381,7 @@
 
 	/* Modify profit if a subsidy is in effect */
 	if (subsidised) {
-		switch (_settings.difficulty.subsidy_multiplier) {
+		switch (_settings_game.difficulty.subsidy_multiplier) {
 			case 0:  profit += profit >> 1; break;
 			case 1:  profit *= 2; break;
 			case 2:  profit *= 3; break;
@@ -1502,7 +1502,7 @@
 
 	/* We have not waited enough time till the next round of loading/unloading */
 	if (--v->load_unload_time_rem != 0) {
-		if (_settings.order.improved_load && (v->current_order.GetLoadType() & OLFB_FULL_LOAD)) {
+		if (_settings_game.order.improved_load && (v->current_order.GetLoadType() & OLFB_FULL_LOAD)) {
 			/* 'Reserve' this cargo for this vehicle, because we were first. */
 			for (; v != NULL; v = v->Next()) {
 				if (v->cargo_cap != 0) cargo_left[v->cargo_type] -= v->cargo_cap - v->cargo.Count();
@@ -1538,7 +1538,7 @@
 		if (v->cargo_cap == 0) continue;
 
 		byte load_amount = EngInfo(v->engine_type)->load_amount;
-		if (_settings.order.gradual_loading && HasBit(EngInfo(v->engine_type)->callbackmask, CBM_VEHICLE_LOAD_AMOUNT)) {
+		if (_settings_game.order.gradual_loading && HasBit(EngInfo(v->engine_type)->callbackmask, CBM_VEHICLE_LOAD_AMOUNT)) {
 			uint16 cb_load_amount = GetVehicleCallback(CBID_VEHICLE_LOAD_AMOUNT, 0, 0, v->engine_type, v);
 			if (cb_load_amount != CALLBACK_FAILED && GB(cb_load_amount, 0, 8) != 0) load_amount = GB(cb_load_amount, 0, 8);
 		}
@@ -1547,7 +1547,7 @@
 
 		if (HasBit(v->vehicle_flags, VF_CARGO_UNLOADING) && (u->current_order.GetUnloadType() & OUFB_NO_UNLOAD) == 0) {
 			uint cargo_count = v->cargo.Count();
-			uint amount_unloaded = _settings.order.gradual_loading ? min(cargo_count, load_amount) : cargo_count;
+			uint amount_unloaded = _settings_game.order.gradual_loading ? min(cargo_count, load_amount) : cargo_count;
 			bool remaining; // Are there cargo entities in this vehicle that can still be unloaded here?
 
 			if (HasBit(ge->acceptance_pickup, GoodsEntry::ACCEPTANCE) && !(u->current_order.GetUnloadType() & OUFB_TRANSFER)) {
@@ -1573,7 +1573,7 @@
 			unloading_time += amount_unloaded;
 
 			anything_unloaded = true;
-			if (_settings.order.gradual_loading && remaining) {
+			if (_settings_game.order.gradual_loading && remaining) {
 				completely_emptied = false;
 			} else {
 				/* We have finished unloading (cargo count == 0) */
@@ -1607,14 +1607,14 @@
 
 			/* Skip loading this vehicle if another train/vehicle is already handling
 			 * the same cargo type at this station */
-			if (_settings.order.improved_load && cargo_left[v->cargo_type] <= 0) {
+			if (_settings_game.order.improved_load && cargo_left[v->cargo_type] <= 0) {
 				SetBit(cargo_not_full, v->cargo_type);
 				continue;
 			}
 
 			if (cap > count) cap = count;
-			if (_settings.order.gradual_loading) cap = min(cap, load_amount);
-			if (_settings.order.improved_load) {
+			if (_settings_game.order.gradual_loading) cap = min(cap, load_amount);
+			if (_settings_game.order.improved_load) {
 				/* Don't load stuff that is already 'reserved' for other vehicles */
 				cap = min((uint)cargo_left[v->cargo_type], cap);
 				cargo_left[v->cargo_type] -= cap;
@@ -1658,7 +1658,7 @@
 	 * all wagons at the same time instead of using the same 'improved'
 	 * loading algorithm for the wagons (only fill wagon when there is
 	 * enough to fill the previous wagons) */
-	if (_settings.order.improved_load && (u->current_order.GetLoadType() & OLFB_FULL_LOAD)) {
+	if (_settings_game.order.improved_load && (u->current_order.GetLoadType() & OLFB_FULL_LOAD)) {
 		/* Update left cargo */
 		for (v = u; v != NULL; v = v->Next()) {
 			if (v->cargo_cap != 0) cargo_left[v->cargo_type] -= v->cargo_cap - v->cargo.Count();
@@ -1668,7 +1668,7 @@
 	v = u;
 
 	if (anything_loaded || anything_unloaded) {
-		if (_settings.order.gradual_loading) {
+		if (_settings_game.order.gradual_loading) {
 			/* The time it takes to load one 'slice' of cargo or passengers depends
 			* on the vehicle type - the values here are those found in TTDPatch */
 			const uint gradual_loading_wait_time[] = { 40, 20, 10, 20 };
@@ -1705,11 +1705,11 @@
 
 	/* Calculate the loading indicator fill percent and display
 	 * In the Game Menu do not display indicators
-	 * If _settings.gui.loading_indicators == 2, show indicators (bool can be promoted to int as 0 or 1 - results in 2 > 0,1 )
-	 * if _settings.gui.loading_indicators == 1, _local_player must be the owner or must be a spectator to show ind., so 1 > 0
-	 * if _settings.gui.loading_indicators == 0, do not display indicators ... 0 is never greater than anything
+	 * If _settings_client.gui.loading_indicators == 2, show indicators (bool can be promoted to int as 0 or 1 - results in 2 > 0,1 )
+	 * if _settings_client.gui.loading_indicators == 1, _local_player must be the owner or must be a spectator to show ind., so 1 > 0
+	 * if _settings_client.gui.loading_indicators == 0, do not display indicators ... 0 is never greater than anything
 	 */
-	if (_game_mode != GM_MENU && (_settings.gui.loading_indicators > (uint)(v->owner != _local_player && _local_player != PLAYER_SPECTATOR))) {
+	if (_game_mode != GM_MENU && (_settings_client.gui.loading_indicators > (uint)(v->owner != _local_player && _local_player != PLAYER_SPECTATOR))) {
 		StringID percent_up_down = STR_NULL;
 		int percent = CalcPercentVehicleFilled(v, &percent_up_down);
 		if (v->fill_percent_te_id == INVALID_TE_ID) {
@@ -1757,7 +1757,7 @@
 void PlayersMonthlyLoop()
 {
 	PlayersGenStatistics();
-	if (_settings.economy.inflation && _cur_year < MAX_YEAR)
+	if (_settings_game.economy.inflation && _cur_year < MAX_YEAR)
 		AddInflation();
 	PlayersPayInterest();
 	/* Reset the _current_player flag */
@@ -1827,7 +1827,7 @@
 
 	/* Check if buying shares is allowed (protection against modified clients) */
 	/* Cannot buy own shares */
-	if (!IsValidPlayer((PlayerID)p1) || !_settings.economy.allow_shares || _current_player == (PlayerID)p1) return CMD_ERROR;
+	if (!IsValidPlayer((PlayerID)p1) || !_settings_game.economy.allow_shares || _current_player == (PlayerID)p1) return CMD_ERROR;
 
 	p = GetPlayer((PlayerID)p1);
 
@@ -1876,7 +1876,7 @@
 
 	/* Check if selling shares is allowed (protection against modified clients) */
 	/* Cannot sell own shares */
-	if (!IsValidPlayer((PlayerID)p1) || !_settings.economy.allow_shares || _current_player == (PlayerID)p1) return CMD_ERROR;
+	if (!IsValidPlayer((PlayerID)p1) || !_settings_game.economy.allow_shares || _current_player == (PlayerID)p1) return CMD_ERROR;
 
 	p = GetPlayer((PlayerID)p1);
 
--- a/src/elrail_func.h	Thu May 29 12:52:24 2008 +0000
+++ b/src/elrail_func.h	Thu May 29 15:56:32 2008 +0000
@@ -25,7 +25,7 @@
  */
 static inline bool HasCatenaryDrawn(RailType rt)
 {
-	return HasCatenary(rt) && !IsInvisibilitySet(TO_CATENARY) && !_settings.vehicle.disable_elrails;
+	return HasCatenary(rt) && !IsInvisibilitySet(TO_CATENARY) && !_settings_game.vehicle.disable_elrails;
 }
 
 /**
@@ -37,6 +37,6 @@
 void DrawCatenaryOnTunnel(const TileInfo *ti);
 void DrawCatenaryOnBridge(const TileInfo *ti);
 
-int32 SettingsDisableElrail(int32 p1); ///< _settings.disable_elrail callback
+int32 SettingsDisableElrail(int32 p1); ///< _settings_game.disable_elrail callback
 
 #endif /* ELRAIL_FUNC_H */
--- a/src/engine.cpp	Thu May 29 12:52:24 2008 +0000
+++ b/src/engine.cpp	Thu May 29 15:56:32 2008 +0000
@@ -116,34 +116,6 @@
 	free(this->name);
 }
 
-/** Sort all items using qsort() and given 'CompareItems' function
- * @param el list to be sorted
- * @param compare function for evaluation of the quicksort
- */
-void EngList_Sort(EngineList *el, EngList_SortTypeFunction compare)
-{
-	size_t size = el->size();
-	/* out-of-bounds access at the next line for size == 0 (even with operator[] at some systems)
-	 * generally, do not sort if there are less than 2 items */
-	if (size < 2) return;
-	qsort(&((*el)[0]), size, sizeof(EngineID), compare); // MorphOS doesn't know vector::at(int) ...
-}
-
-/** Sort selected range of items (on indices @ <begin, begin+num_items-1>)
- * @param el list to be sorted
- * @param compare function for evaluation of the quicksort
- * @param begin start of sorting
- * @param num_items count of items to be sorted
- */
-void EngList_SortPartial(EngineList *el, EngList_SortTypeFunction compare, uint begin, uint num_items)
-{
-	assert(begin <= (uint)el->size());
-	assert(begin + num_items <= (uint)el->size());
-	if (num_items < 2) return;
-	qsort(&((*el)[begin]), num_items, sizeof(EngineID), compare);
-}
-
-
 /** Sets cached values in Player::num_vehicles and Group::num_vehicles
  */
 void SetCachedEngineCounts()
@@ -218,7 +190,7 @@
 	uint age = e->age;
 
 	/* Check for early retirement */
-	if (e->player_avail != 0 && !_settings.vehicle.never_expire_vehicles) {
+	if (e->player_avail != 0 && !_settings_game.vehicle.never_expire_vehicles) {
 		int retire_early = e->info.retire_early;
 		uint retire_early_max_age = max(0, e->duration_phase_1 + e->duration_phase_2 - retire_early * 12);
 		if (retire_early != 0 && age >= retire_early_max_age) {
@@ -231,7 +203,7 @@
 	if (age < e->duration_phase_1) {
 		uint start = e->reliability_start;
 		e->reliability = age * (e->reliability_max - start) / e->duration_phase_1 + start;
-	} else if ((age -= e->duration_phase_1) < e->duration_phase_2 || _settings.vehicle.never_expire_vehicles) {
+	} else if ((age -= e->duration_phase_1) < e->duration_phase_2 || _settings_game.vehicle.never_expire_vehicles) {
 		/* We are at the peak of this engines life. It will have max reliability.
 		 * This is also true if the engines never expire. They will not go bad over time */
 		e->reliability = e->reliability_max;
@@ -294,10 +266,10 @@
 			CalcEngineReliability(e);
 		}
 
-		e->lifelength = ei->lifelength + _settings.vehicle.extend_vehicle_life;
+		e->lifelength = ei->lifelength + _settings_game.vehicle.extend_vehicle_life;
 
 		/* prevent certain engines from ever appearing. */
-		if (!HasBit(ei->climates, _settings.game_creation.landscape)) {
+		if (!HasBit(ei->climates, _settings_game.game_creation.landscape)) {
 			e->flags |= ENGINE_AVAILABLE;
 			e->player_avail = 0;
 		}
--- a/src/engine_func.h	Thu May 29 12:52:24 2008 +0000
+++ b/src/engine_func.h	Thu May 29 15:56:32 2008 +0000
@@ -29,8 +29,4 @@
 CargoID GetEngineCargoType(EngineID engine);
 void SetCachedEngineCounts();
 
-typedef int CDECL EngList_SortTypeFunction(const void*, const void*); ///< argument type for EngList_Sort()
-void EngList_Sort(EngineList *el, EngList_SortTypeFunction compare);  ///< qsort of the engine list
-void EngList_SortPartial(EngineList *el, EngList_SortTypeFunction compare, uint begin, uint num_items); ///< qsort of specified portion of the engine list
-
 #endif /* ENGINE_H */
--- a/src/engine_gui.cpp	Thu May 29 12:52:24 2008 +0000
+++ b/src/engine_gui.cpp	Thu May 29 15:56:32 2008 +0000
@@ -15,6 +15,7 @@
 #include "variables.h"
 #include "newgrf_engine.h"
 #include "strings_func.h"
+#include "engine_gui.h"
 
 #include "table/strings.h"
 #include "table/sprites.h"
@@ -190,3 +191,32 @@
 	GfxFillRect(25, 56, w->width - 56, 112, PALETTE_TO_STRUCT_GREY | (1 << USE_COLORTABLE));
 	dei->info_proc(engine, w->width >> 1, 129, w->width - 52);
 }
+
+
+/** Sort all items using qsort() and given 'CompareItems' function
+ * @param el list to be sorted
+ * @param compare function for evaluation of the quicksort
+ */
+void EngList_Sort(GUIEngineList *el, EngList_SortTypeFunction compare)
+{
+	uint size = el->Length();
+	/* out-of-bounds access at the next line for size == 0 (even with operator[] at some systems)
+	 * generally, do not sort if there are less than 2 items */
+	if (size < 2) return;
+	qsort(el->Begin(), size, sizeof(*el->Begin()), compare); // MorphOS doesn't know vector::at(int) ...
+}
+
+/** Sort selected range of items (on indices @ <begin, begin+num_items-1>)
+ * @param el list to be sorted
+ * @param compare function for evaluation of the quicksort
+ * @param begin start of sorting
+ * @param num_items count of items to be sorted
+ */
+void EngList_SortPartial(GUIEngineList *el, EngList_SortTypeFunction compare, uint begin, uint num_items)
+{
+	if (num_items < 2) return;
+	assert(begin < el->Length());
+	assert(begin + num_items <= el->Length());
+	qsort(el->Get(begin), num_items, sizeof(*el->Begin()), compare);
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/engine_gui.h	Thu May 29 15:56:32 2008 +0000
@@ -0,0 +1,16 @@
+/* $Id$ */
+
+/** @file engine_gui.h Engine GUI functions, used by build_vehicle_gui and autoreplace_gui */
+
+#ifndef ENGINE_GUI_H
+#define ENGINE_GUI_H
+
+#include "sortlist_type.h"
+
+typedef GUIList<EngineID> GUIEngineList;
+
+typedef int CDECL EngList_SortTypeFunction(const void*, const void*); ///< argument type for EngList_Sort()
+void EngList_Sort(GUIEngineList *el, EngList_SortTypeFunction compare);  ///< qsort of the engine list
+void EngList_SortPartial(GUIEngineList *el, EngList_SortTypeFunction compare, uint begin, uint num_items); ///< qsort of specified portion of the engine list
+
+#endif /* ENGINE_GUI_H */
--- a/src/engine_type.h	Thu May 29 12:52:24 2008 +0000
+++ b/src/engine_type.h	Thu May 29 15:56:32 2008 +0000
@@ -14,11 +14,8 @@
 #include "player_type.h"
 #include "strings_type.h"
 
-#include <vector>
-
 typedef uint16 EngineID;
 typedef uint16 EngineRenewID;
-typedef std::vector<EngineID> EngineList; ///< engine list type
 
 struct Engine;
 
--- a/src/fileio.cpp	Thu May 29 12:52:24 2008 +0000
+++ b/src/fileio.cpp	Thu May 29 15:56:32 2008 +0000
@@ -43,7 +43,7 @@
 static Fio _fio;
 
 /* Get current position in file */
-uint32 FioGetPos()
+size_t FioGetPos()
 {
 	return _fio.pos + (_fio.buffer - _fio.buffer_end);
 }
@@ -53,7 +53,7 @@
 	return _fio.shortnames[slot];
 }
 
-void FioSeekTo(uint32 pos, int mode)
+void FioSeekTo(size_t pos, int mode)
 {
 	if (mode == SEEK_CUR) pos += FioGetPos();
 	_fio.buffer = _fio.buffer_end = _fio.buffer_start + FIO_BUFFER_SIZE;
@@ -74,7 +74,7 @@
 #endif /* LIMITED_FDS */
 
 /* Seek to a file and a position */
-void FioSeekToFile(uint8 slot, uint32 pos)
+void FioSeekToFile(uint8 slot, size_t pos)
 {
 	FILE *f;
 #if defined(LIMITED_FDS)
--- a/src/fileio.h	Thu May 29 12:52:24 2008 +0000
+++ b/src/fileio.h	Thu May 29 15:56:32 2008 +0000
@@ -9,9 +9,9 @@
 #include <string>
 #include "core/enum_type.hpp"
 
-void FioSeekTo(uint32 pos, int mode);
-void FioSeekToFile(uint8 slot, uint32 pos);
-uint32 FioGetPos();
+void FioSeekTo(size_t pos, int mode);
+void FioSeekToFile(uint8 slot, size_t pos);
+size_t FioGetPos();
 const char *FioGetFilename(uint8 slot);
 byte FioReadByte();
 uint16 FioReadWord();
--- a/src/fios.h	Thu May 29 12:52:24 2008 +0000
+++ b/src/fios.h	Thu May 29 15:56:32 2008 +0000
@@ -72,11 +72,19 @@
 	char title[255];      ///< internal name of the game
 };
 
+enum {
+	SORT_ASCENDING  = 0,
+	SORT_DESCENDING = 1,
+	SORT_BY_DATE    = 0,
+	SORT_BY_NAME    = 2
+};
+
 /* Variables to display file lists */
 extern FiosItem *_fios_list; ///< defined in misc_gui.cpp
 extern int _fios_num;        ///< defined in fios.cpp, read_only version of _fios_count
 extern SmallFiosItem _file_to_saveload;
 extern SaveLoadDialogMode _saveload_mode;   ///< defined in misc_gui.cpp
+extern byte _savegame_sort_order;
 
 /* Launch save/load dialog */
 void ShowSaveLoadDialog(SaveLoadDialogMode mode);
--- a/src/genworld.cpp	Thu May 29 12:52:24 2008 +0000
+++ b/src/genworld.cpp	Thu May 29 15:56:32 2008 +0000
@@ -39,7 +39,7 @@
 void StartupPlayers();
 void StartupDisasters();
 
-void InitializeGame(int mode, uint size_x, uint size_y);
+void InitializeGame(uint size_x, uint size_y, bool reset_date);
 
 /* Please only use this variable in genworld.h and genworld.c and
  *  nowhere else. For speed improvements we need it to be global, but
@@ -91,8 +91,8 @@
 		_generating_world = true;
 		if (_network_dedicated) DEBUG(net, 0, "Generating map, please wait...");
 		/* Set the Random() seed to generation_seed so we produce the same map with the same seed */
-		if (_settings.game_creation.generation_seed == GENERATE_NEW_SEED) _settings.game_creation.generation_seed = _settings_newgame.game_creation.generation_seed = InteractiveRandom();
-		_random.SetSeed(_settings.game_creation.generation_seed);
+		if (_settings_game.game_creation.generation_seed == GENERATE_NEW_SEED) _settings_game.game_creation.generation_seed = _settings_newgame.game_creation.generation_seed = InteractiveRandom();
+		_random.SetSeed(_settings_game.game_creation.generation_seed);
 		SetGeneratingWorldProgress(GWP_MAP_INIT, 2);
 		SetObjectToPlace(SPR_CURSOR_ZZZ, PAL_NONE, VHM_NONE, WC_MAIN_WINDOW, 0);
 
@@ -105,7 +105,7 @@
 			SetGeneratingWorldProgress(GWP_UNMOVABLE, 1);
 
 			/* Make the map the height of the patch setting */
-			if (_game_mode != GM_MENU) FlatEmptyWorld(_settings.game_creation.se_flat_world_height);
+			if (_game_mode != GM_MENU) FlatEmptyWorld(_settings_game.game_creation.se_flat_world_height);
 
 			ConvertGroundTilesIntoWaterTiles();
 			IncreaseGeneratingWorldProgress(GWP_UNMOVABLE);
@@ -165,7 +165,7 @@
 
 		if (_network_dedicated) DEBUG(net, 0, "Map generated, starting game");
 
-		if (_settings.gui.pause_on_newgame && _game_mode == GM_NORMAL) DoCommandP(0, 1, 0, NULL, CMD_PAUSE);
+		if (_settings_client.gui.pause_on_newgame && _game_mode == GM_NORMAL) DoCommandP(0, 1, 0, NULL, CMD_PAUSE);
 	} catch (...) {
 		_generating_world = false;
 		throw;
@@ -253,7 +253,7 @@
  * @param size_x The X-size of the map.
  * @param size_y The Y-size of the map.
  */
-void GenerateWorld(int mode, uint size_x, uint size_y)
+void GenerateWorld(GenerateWorldMode mode, uint size_x, uint size_y)
 {
 	if (_gw.active) return;
 	_gw.mode   = mode;
@@ -273,13 +273,13 @@
 	_current_player = OWNER_NONE;
 
 	/* Set the date before loading sprites as some newgrfs check it */
-	SetDate(ConvertYMDToDate(_settings.game_creation.starting_year, 0, 1));
+	SetDate(ConvertYMDToDate(_settings_game.game_creation.starting_year, 0, 1));
 
 	/* Load the right landscape stuff */
 	GfxLoadSprites();
 	LoadStringWidthTable();
 
-	InitializeGame(IG_NONE, _gw.size_x, _gw.size_y);
+	InitializeGame(_gw.size_x, _gw.size_y, false);
 	PrepareGenerateWorldProgress();
 
 	/* Re-init the windowing system */
--- a/src/genworld.h	Thu May 29 12:52:24 2008 +0000
+++ b/src/genworld.h	Thu May 29 15:56:32 2008 +0000
@@ -18,6 +18,14 @@
 	GENERATE_NEW_SEED = (uint)-1, ///< Create a new random seed
 };
 
+/* Modes for GenerateWorld */
+enum GenerateWorldMode {
+	GW_NEWGAME   = 0,    /* Generate a map for a new game */
+	GW_EMPTY     = 1,    /* Generate an empty map (sea-level) */
+	GW_RANDOM    = 2,    /* Generate a random map for SE */
+	GW_HEIGHTMAP = 3,    /* Generate a newgame from a heightmap */
+};
+
 typedef void gw_done_proc();
 typedef void gw_abort_proc();
 
@@ -27,7 +35,7 @@
 	bool wait_for_draw;    ///< Are we waiting on a draw event
 	bool quit_thread;      ///< Do we want to quit the active thread
 	bool threaded;         ///< Whether we run _GenerateWorld threaded
-	int mode;              ///< What mode are we making a world in
+	GenerateWorldMode mode;///< What mode are we making a world in
 	PlayerID lp;           ///< The local_player before generating
 	uint size_x;           ///< X-size of the map
 	uint size_y;           ///< Y-size of the map
@@ -67,7 +75,7 @@
 void GenerateWorldSetCallback(gw_done_proc *proc);
 void GenerateWorldSetAbortCallback(gw_abort_proc *proc);
 void WaitTillGeneratedWorld();
-void GenerateWorld(int mode, uint size_x, uint size_y);
+void GenerateWorld(GenerateWorldMode mode, uint size_x, uint size_y);
 void AbortGeneratingWorld();
 bool IsGeneratingWorldAborted();
 void HandleGeneratingWorldAbortion();
--- a/src/genworld_gui.cpp	Thu May 29 12:52:24 2008 +0000
+++ b/src/genworld_gui.cpp	Thu May 29 15:56:32 2008 +0000
@@ -205,7 +205,7 @@
 	DeleteAllNonVitalWindows();
 
 	/* Copy all XXX_newgame to XXX when coming from outside the editor */
-	UpdatePatches();
+	_settings_game = _settings_newgame;
 	ResetGRFConfig(true);
 
 	SndPlayFx(SND_15_BEEP);
@@ -377,9 +377,9 @@
 				break;
 
 			case GLAND_GENERATE_BUTTON: // Generate
-				UpdatePatches();
+				_settings_game = _settings_newgame;
 
-				if (_settings.economy.town_layout == TL_NO_ROADS) {
+				if (_settings_game.economy.town_layout == TL_NO_ROADS) {
 					ShowQuery(
 						STR_TOWN_LAYOUT_WARNING_CAPTION,
 						STR_TOWN_LAYOUT_WARNING_MESSAGE,
--- a/src/gfx.cpp	Thu May 29 12:52:24 2008 +0000
+++ b/src/gfx.cpp	Thu May 29 15:56:32 2008 +0000
@@ -807,7 +807,7 @@
 	memcpy(old_val, d, c * sizeof(*old_val));
 
 	/* Dark blue water */
-	s = (_settings.game_creation.landscape == LT_TOYLAND) ? ev->ac : ev->a;
+	s = (_settings_game.game_creation.landscape == LT_TOYLAND) ? ev->ac : ev->a;
 	j = EXTR(320, 5);
 	for (i = 0; i != 5; i++) {
 		*d++ = s[j];
@@ -816,7 +816,7 @@
 	}
 
 	/* Glittery water */
-	s = (_settings.game_creation.landscape == LT_TOYLAND) ? ev->bc : ev->b;
+	s = (_settings_game.game_creation.landscape == LT_TOYLAND) ? ev->bc : ev->b;
 	j = EXTR(128, 15);
 	for (i = 0; i != 5; i++) {
 		*d++ = s[j];
@@ -876,7 +876,7 @@
 	/* Animate water for old DOS graphics */
 	if (_use_dos_palette) {
 		/* Dark blue water DOS */
-		s = (_settings.game_creation.landscape == LT_TOYLAND) ? ev->ac : ev->a;
+		s = (_settings_game.game_creation.landscape == LT_TOYLAND) ? ev->ac : ev->a;
 		j = EXTR(320, 5);
 		for (i = 0; i != 5; i++) {
 			*d++ = s[j];
@@ -885,7 +885,7 @@
 		}
 
 		/* Glittery water DOS */
-		s = (_settings.game_creation.landscape == LT_TOYLAND) ? ev->bc : ev->b;
+		s = (_settings_game.game_creation.landscape == LT_TOYLAND) ? ev->bc : ev->b;
 		j = EXTR(128, 15);
 		for (i = 0; i != 5; i++) {
 			*d++ = s[j];
--- a/src/gfxinit.cpp	Thu May 29 12:52:24 2008 +0000
+++ b/src/gfxinit.cpp	Thu May 29 15:56:32 2008 +0000
@@ -214,10 +214,10 @@
 	 * This overwrites some of the temperate sprites, such as foundations
 	 * and the ground sprites.
 	 */
-	if (_settings.game_creation.landscape != LT_TEMPERATE) {
+	if (_settings_game.game_creation.landscape != LT_TEMPERATE) {
 		LoadGrfIndexed(
-			files->landscape[_settings.game_creation.landscape - 1].filename,
-			_landscape_spriteindexes[_settings.game_creation.landscape - 1],
+			files->landscape[_settings_game.game_creation.landscape - 1].filename,
+			_landscape_spriteindexes[_settings_game.game_creation.landscape - 1],
 			i++
 		);
 	}
@@ -248,7 +248,7 @@
 
 void GfxLoadSprites()
 {
-	DEBUG(sprite, 2, "Loading sprite set %d", _settings.game_creation.landscape);
+	DEBUG(sprite, 2, "Loading sprite set %d", _settings_game.game_creation.landscape);
 
 	GfxInitSpriteMem();
 	LoadSpriteTables();
--- a/src/group_gui.cpp	Thu May 29 12:52:24 2008 +0000
+++ b/src/group_gui.cpp	Thu May 29 15:56:32 2008 +0000
@@ -30,70 +30,6 @@
 
 typedef GUIList<const Group*> GUIGroupList;
 
-static void BuildGroupList(GUIGroupList *gl, PlayerID owner, VehicleType vehicle_type)
-{
-	uint n = 0;
-
-	if (!(gl->flags & VL_REBUILD)) return;
-
-	const Group **list = MallocT<const Group*>(GetGroupArraySize());
-
-	const Group *g;
-	FOR_ALL_GROUPS(g) {
-		if (g->owner == owner && g->vehicle_type == vehicle_type) list[n++] = g;
-	}
-
-	gl->sort_list = ReallocT(gl->sort_list, n);
-	gl->list_length = n;
-
-	for (uint i = 0; i < n; ++i) gl->sort_list[i] = list[i];
-	free(list);
-
-	gl->flags &= ~VL_REBUILD;
-	gl->flags |= VL_RESORT;
-}
-
-
-static int CDECL GroupNameSorter(const void *a, const void *b)
-{
-	static const Group *last_group[2] = { NULL, NULL };
-	static char         last_name[2][64] = { "", "" };
-
-	const Group *ga = *(const Group**)a;
-	const Group *gb = *(const Group**)b;
-	int r;
-
-	if (ga != last_group[0]) {
-		last_group[0] = ga;
-		SetDParam(0, ga->index);
-		GetString(last_name[0], STR_GROUP_NAME, lastof(last_name[0]));
-	}
-
-	if (gb != last_group[1]) {
-		last_group[1] = gb;
-		SetDParam(0, gb->index);
-		GetString(last_name[1], STR_GROUP_NAME, lastof(last_name[1]));
-	}
-
-	r = strcmp(last_name[0], last_name[1]); // sort by name
-
-	if (r == 0) return ga->index - gb->index;
-
-	return r;
-}
-
-
-static void SortGroupList(GUIGroupList *gl)
-{
-	if (!(gl->flags & VL_RESORT)) return;
-
-	qsort((void*)gl->sort_list, gl->list_length, sizeof(gl->sort_list[0]), GroupNameSorter);
-
-	gl->resort_timer = DAY_TICKS * PERIODIC_RESORT_DAYS;
-	gl->flags &= ~VL_RESORT;
-}
-
-
 enum GroupListWidgets {
 	GRP_WIDGET_CLOSEBOX = 0,
 	GRP_WIDGET_CAPTION,
@@ -182,18 +118,64 @@
 };
 
 
-struct VehicleGroupWindow : public Window, public VehicleListBase {
+class VehicleGroupWindow : public Window, public VehicleListBase {
+private:
 	GroupID group_sel;
 	VehicleID vehicle_sel;
 	GUIGroupList groups;
 
+	/**
+	 * (Re)Build the group list.
+	 *
+	 * @param owner The owner of the window
+	 */
+	void BuildGroupList(PlayerID owner)
+	{
+		if (!this->groups.NeedRebuild()) return;
+
+		this->groups.Clear();
+
+		const Group *g;
+		FOR_ALL_GROUPS(g) {
+			if (g->owner == owner && g->vehicle_type == this->vehicle_type) {
+				*this->groups.Append() = g;
+			}
+		}
+
+		this->groups.Compact();
+		this->groups.RebuildDone();
+	}
+
+	/** Sort the groups by their name */
+	static int CDECL GroupNameSorter(const Group* const *a, const Group* const *b)
+	{
+		static const Group *last_group[2] = { NULL, NULL };
+		static char         last_name[2][64] = { "", "" };
+
+		if (*a != last_group[0]) {
+			last_group[0] = *a;
+			SetDParam(0, (*a)->index);
+			GetString(last_name[0], STR_GROUP_NAME, lastof(last_name[0]));
+		}
+
+		if (*b != last_group[1]) {
+			last_group[1] = *b;
+			SetDParam(0, (*b)->index);
+			GetString(last_name[1], STR_GROUP_NAME, lastof(last_name[1]));
+		}
+
+		int r = strcmp(last_name[0], last_name[1]); // sort by name
+		if (r == 0) return (*a)->index - (*b)->index;
+		return r;
+	}
+
+public:
 	VehicleGroupWindow(const WindowDesc *desc, WindowNumber window_number) : Window(desc, window_number)
 	{
 		const PlayerID owner = (PlayerID)GB(this->window_number, 0, 8);
 		this->vehicle_type = (VehicleType)GB(this->window_number, 11, 5);
 
 		this->caption_color = owner;
-		this->hscroll.cap = 224;
 		this->resize.step_width = 1;
 
 		switch (this->vehicle_type) {
@@ -223,14 +205,12 @@
 			case VEH_AIRCRAFT: this->sorting = &_sorting.aircraft; break;
 		}
 
-		this->vehicles.sort_list = NULL;
 		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->groups.sort_list = NULL;
-		this->groups.flags = VL_REBUILD | VL_NONE;
-		this->groups.resort_timer = DAY_TICKS * PERIODIC_RESORT_DAYS; // Set up resort timer
+		this->groups.ForceRebuild();
+		this->groups.NeedResort();
 
 		this->group_sel = ALL_GROUP;
 		this->vehicle_sel = INVALID_VEHICLE;
@@ -280,14 +260,18 @@
 
 	~VehicleGroupWindow()
 	{
-		free((void*)this->vehicles.sort_list);
-		free((void*)this->groups.sort_list);
 	}
 
 	virtual void OnInvalidateData(int data)
 	{
 		this->vehicles.flags |= (data == 0 ? VL_REBUILD : VL_RESORT);
-		this->groups.flags |= (data == 0 ? VL_REBUILD : VL_RESORT);
+
+		if (data == 0) {
+			this->groups.ForceRebuild();
+		} else {
+			this->groups.ForceResort();
+		}
+
 		if (!(IsAllGroupID(this->group_sel) || IsDefaultGroupID(this->group_sel) || IsValidGroupID(this->group_sel))) {
 			this->group_sel = ALL_GROUP;
 			HideDropDownMenu(this);
@@ -298,7 +282,7 @@
 	virtual void OnPaint()
 	{
 		const PlayerID owner = (PlayerID)GB(this->window_number, 0, 8);
-		int x = 203;
+		int x = this->widget[GRP_WIDGET_LIST_VEHICLE].left + 2;
 		int y2 = PLY_WND_PRC__OFFSET_TOP_WIDGET;
 		int y1 = PLY_WND_PRC__OFFSET_TOP_WIDGET + 2;
 		int max;
@@ -309,21 +293,20 @@
 		BuildVehicleList(this, owner, this->group_sel, IsAllGroupID(this->group_sel) ? VLW_STANDARD : VLW_GROUP_LIST);
 		SortVehicleList(this);
 
+		this->BuildGroupList(owner);
+		this->groups.Sort(&GroupNameSorter);
 
-		BuildGroupList(&this->groups, owner, this->vehicle_type);
-		SortGroupList(&this->groups);
-
-		SetVScrollCount(this, this->groups.list_length);
-		SetVScroll2Count(this, this->vehicles.list_length);
+		SetVScrollCount(this, this->groups.Length());
+		SetVScroll2Count(this, this->vehicles.Length());
 
 		/* The drop down menu is out, *but* it may not be used, retract it. */
-		if (this->vehicles.list_length == 0 && this->IsWidgetLowered(GRP_WIDGET_MANAGE_VEHICLES_DROPDOWN)) {
+		if (this->vehicles.Length() == 0 && this->IsWidgetLowered(GRP_WIDGET_MANAGE_VEHICLES_DROPDOWN)) {
 			this->RaiseWidget(GRP_WIDGET_MANAGE_VEHICLES_DROPDOWN);
 			HideDropDownMenu(this);
 		}
 
 		/* Disable all lists management button when the list is empty */
-		this->SetWidgetsDisabledState(this->vehicles.list_length == 0 || _local_player != owner,
+		this->SetWidgetsDisabledState(this->vehicles.Length() == 0 || _local_player != owner,
 				GRP_WIDGET_STOP_ALL,
 				GRP_WIDGET_START_ALL,
 				GRP_WIDGET_MANAGE_VEHICLES_DROPDOWN,
@@ -352,7 +335,7 @@
 				We list all vehicles or ungrouped vehicles */
 		if (IsDefaultGroupID(this->group_sel) || IsAllGroupID(this->group_sel)) {
 			SetDParam(0, owner);
-			SetDParam(1, this->vehicles.list_length);
+			SetDParam(1, this->vehicles.Length());
 
 			switch (this->vehicle_type) {
 				case VEH_TRAIN:
@@ -434,9 +417,9 @@
 
 		DrawString(10, y1, str_no_group_veh, IsDefaultGroupID(this->group_sel) ? TC_WHITE : TC_BLACK);
 
-		max = min(this->vscroll.pos + this->vscroll.cap, this->groups.list_length);
+		max = min(this->vscroll.pos + this->vscroll.cap, this->groups.Length());
 		for (i = this->vscroll.pos ; i < max ; ++i) {
-			const Group *g = this->groups.sort_list[i];
+			const Group *g = this->groups[i];
 
 			assert(g->owner == owner);
 
@@ -453,14 +436,16 @@
 
 		this->DrawSortButtonState(GRP_WIDGET_SORT_BY_ORDER, this->vehicles.flags & VL_DESC ? SBS_DOWN : SBS_UP);
 
+		int list_width = this->widget[GRP_WIDGET_LIST_VEHICLE].right - this->widget[GRP_WIDGET_LIST_VEHICLE].left - 20;
+
 		/* Draw Matrix Vehicle according to the vehicle list built before */
-		max = min(this->vscroll2.pos + this->vscroll2.cap, this->vehicles.list_length);
+		max = min(this->vscroll2.pos + this->vscroll2.cap, this->vehicles.Length());
 		for (i = this->vscroll2.pos ; i < max ; ++i) {
-			const Vehicle* v = this->vehicles.sort_list[i];
+			const Vehicle* v = this->vehicles[i];
 
 			assert(v->type == this->vehicle_type && v->owner == owner);
 
-			DrawVehicleImage(v, x + 19, y2 + 6, this->vehicle_sel, this->hscroll.cap, 0);
+			DrawVehicleImage(v, x + 19, y2 + 6, this->vehicle_sel, list_width, 0);
 			DrawVehicleProfitButton(v, x, y2 + 13);
 
 			SetDParam(0, v->unitnumber);
@@ -521,9 +506,9 @@
 
 				id_g += this->vscroll.pos;
 
-				if (id_g >= this->groups.list_length) return;
+				if (id_g >= this->groups.Length()) return;
 
-				this->group_sel = this->groups.sort_list[id_g]->index;;
+				this->group_sel = this->groups[id_g]->index;;
 
 				this->vehicles.flags |= VL_REBUILD;
 				this->SetDirty();
@@ -538,9 +523,9 @@
 
 				id_v += this->vscroll2.pos;
 
-				if (id_v >= this->vehicles.list_length) return; // click out of list bound
+				if (id_v >= this->vehicles.Length()) return; // click out of list bound
 
-				v = this->vehicles.sort_list[id_v];
+				v = this->vehicles[id_v];
 
 				this->vehicle_sel = v->index;
 
@@ -628,9 +613,9 @@
 
 				id_g += this->vscroll.pos;
 
-				if (id_g >= this->groups.list_length) return;
+				if (id_g >= this->groups.Length()) return;
 
-				DoCommandP(0, this->groups.sort_list[id_g]->index, vindex, NULL, CMD_ADD_VEHICLE_GROUP | CMD_MSG(STR_GROUP_CAN_T_ADD_VEHICLE));
+				DoCommandP(0, this->groups[id_g]->index, vindex, NULL, CMD_ADD_VEHICLE_GROUP | CMD_MSG(STR_GROUP_CAN_T_ADD_VEHICLE));
 
 				break;
 			}
@@ -648,9 +633,9 @@
 
 				id_v += this->vscroll2.pos;
 
-				if (id_v >= this->vehicles.list_length) return; // click out of list bound
+				if (id_v >= this->vehicles.Length()) return; // click out of list bound
 
-				v = this->vehicles.sort_list[id_v];
+				v = this->vehicles[id_v];
 
 				if (vindex == v->index) {
 					ShowVehicleViewWindow(v);
@@ -673,7 +658,6 @@
 
 	virtual void OnResize(Point new_size, Point delta)
 	{
-		this->hscroll.cap += delta.x;
 		this->vscroll.cap += delta.y / PLY_WND_PRC__SIZE_OF_ROW_TINY;
 		this->vscroll2.cap += delta.y / (int)this->resize.step_height;
 
@@ -693,7 +677,7 @@
 				break;
 
 			case GRP_WIDGET_MANAGE_VEHICLES_DROPDOWN:
-				assert(this->vehicles.list_length != 0);
+				assert(this->vehicles.Length() != 0);
 
 				switch (index) {
 					case GALF_REPLACE: // Replace window
@@ -736,9 +720,7 @@
 			this->vehicles.flags |= VL_RESORT;
 			this->SetDirty();
 		}
-		if (--this->groups.resort_timer == 0) {
-			this->groups.resort_timer = DAY_TICKS * PERIODIC_RESORT_DAYS;
-			this->groups.flags |= VL_RESORT;
+		if (this->groups.NeedResort()) {
 			this->SetDirty();
 		}
 	}
--- a/src/gui.h	Thu May 29 12:52:24 2008 +0000
+++ b/src/gui.h	Thu May 29 15:56:32 2008 +0000
@@ -61,9 +61,6 @@
 
 void ShowSmallMap();
 void ShowExtraViewPortWindow(TileIndex tile = INVALID_TILE);
-void SetVScrollCount(Window *w, int num);
-void SetVScroll2Count(Window *w, int num);
-void SetHScrollCount(Window *w, int num);
 
 void BuildFileList();
 void SetFiosType(const byte fiostype);
--- a/src/heightmap.cpp	Thu May 29 12:52:24 2008 +0000
+++ b/src/heightmap.cpp	Thu May 29 15:56:32 2008 +0000
@@ -297,7 +297,7 @@
 	TileIndex tile;
 
 	/* Get map size and calculate scale and padding values */
-	switch (_settings.game_creation.heightmap_rotation) {
+	switch (_settings_game.game_creation.heightmap_rotation) {
 		default: NOT_REACHED();
 		case HM_COUNTER_CLOCKWISE:
 			width   = MapSizeX();
@@ -322,7 +322,7 @@
 	/* Form the landscape */
 	for (row = 0; row < height - 1; row++) {
 		for (col = 0; col < width - 1; col++) {
-			switch (_settings.game_creation.heightmap_rotation) {
+			switch (_settings_game.game_creation.heightmap_rotation) {
 				default: NOT_REACHED();
 				case HM_COUNTER_CLOCKWISE: tile = TileXY(col, row); break;
 				case HM_CLOCKWISE:         tile = TileXY(row, col); break;
@@ -337,7 +337,7 @@
 				/* Use nearest neighbor resizing to scale map data.
 				 *  We rotate the map 45 degrees (counter)clockwise */
 				img_row = (((row - row_pad) * num_div) / img_scale);
-				switch (_settings.game_creation.heightmap_rotation) {
+				switch (_settings_game.game_creation.heightmap_rotation) {
 					default: NOT_REACHED();
 					case HM_COUNTER_CLOCKWISE:
 						img_col = (((width - 1 - col - col_pad) * num_div) / img_scale);
--- a/src/industry_cmd.cpp	Thu May 29 12:52:24 2008 +0000
+++ b/src/industry_cmd.cpp	Thu May 29 15:56:32 2008 +0000
@@ -70,7 +70,7 @@
 	/* once performed, enable only the current climate industries */
 	for (IndustryType i = 0; i < NUM_INDUSTRYTYPES; i++) {
 		_industry_specs[i].enabled = i < NEW_INDUSTRYOFFSET &&
-				HasBit(_origin_industry_specs[i].climate_availability, _settings.game_creation.landscape);
+				HasBit(_origin_industry_specs[i].climate_availability, _settings_game.game_creation.landscape);
 	}
 
 	memset(&_industry_tile_specs, 0, sizeof(_industry_tile_specs));
@@ -84,7 +84,7 @@
 void ResetIndustryCreationProbility(IndustryType type)
 {
 	assert(type < INVALID_INDUSTRYTYPE);
-	_industry_specs[type].appear_creation[_settings.game_creation.landscape] = 0;
+	_industry_specs[type].appear_creation[_settings_game.game_creation.landscape] = 0;
 }
 
 DEFINE_OLD_POOL_GENERIC(Industry, Industry)
@@ -888,14 +888,14 @@
 	uint field_type;
 	int type;
 
-	if (_settings.game_creation.landscape == LT_ARCTIC) {
+	if (_settings_game.game_creation.landscape == LT_ARCTIC) {
 		if (GetTileZ(tile) + TILE_HEIGHT * 2 >= GetSnowLine())
 			return;
 	}
 
 	/* determine field size */
 	r = (Random() & 0x303) + 0x404;
-	if (_settings.game_creation.landscape == LT_ARCTIC) r += 0x404;
+	if (_settings_game.game_creation.landscape == LT_ARCTIC) r += 0x404;
 	size_x = GB(r, 0, 8);
 	size_y = GB(r, 8, 8);
 
@@ -926,7 +926,7 @@
 	END_TILE_LOOP(cur_tile, size_x, size_y, tile)
 
 	type = 3;
-	if (_settings.game_creation.landscape != LT_ARCTIC && _settings.game_creation.landscape != LT_TROPIC) {
+	if (_settings_game.game_creation.landscape != LT_ARCTIC && _settings_game.game_creation.landscape != LT_TROPIC) {
 		type = _plantfarmfield_type[Random() & 0xF];
 	}
 
@@ -1063,7 +1063,7 @@
 
 static bool CheckNewIndustry_Forest(TileIndex tile)
 {
-	if (_settings.game_creation.landscape == LT_ARCTIC) {
+	if (_settings_game.game_creation.landscape == LT_ARCTIC) {
 		if (GetTileZ(tile) < HighestSnowLine() + TILE_HEIGHT * 2U) {
 			_error_message = STR_4831_FOREST_CAN_ONLY_BE_PLANTED;
 			return false;
@@ -1075,7 +1075,7 @@
 static bool CheckNewIndustry_OilRefinery(TileIndex tile)
 {
 	if (_game_mode == GM_EDITOR) return true;
-	if (DistanceFromEdge(TILE_ADDXY(tile, 1, 1)) < _settings.game_creation.oil_refinery_limit) return true;
+	if (DistanceFromEdge(TILE_ADDXY(tile, 1, 1)) < _settings_game.game_creation.oil_refinery_limit) return true;
 
 	_error_message = STR_483B_CAN_ONLY_BE_POSITIONED;
 	return false;
@@ -1087,7 +1087,7 @@
 {
 	if (_game_mode == GM_EDITOR && _ignore_restrictions) return true;
 	if (TileHeight(tile) == 0 &&
-			DistanceFromEdge(TILE_ADDXY(tile, 1, 1)) < _settings.game_creation.oil_refinery_limit) return true;
+			DistanceFromEdge(TILE_ADDXY(tile, 1, 1)) < _settings_game.game_creation.oil_refinery_limit) return true;
 
 	_error_message = STR_483B_CAN_ONLY_BE_POSITIONED;
 	return false;
@@ -1095,7 +1095,7 @@
 
 static bool CheckNewIndustry_Farm(TileIndex tile)
 {
-	if (_settings.game_creation.landscape == LT_ARCTIC) {
+	if (_settings_game.game_creation.landscape == LT_ARCTIC) {
 		if (GetTileZ(tile) + TILE_HEIGHT * 2 >= HighestSnowLine()) {
 			_error_message = STR_0239_SITE_UNSUITABLE;
 			return false;
@@ -1171,7 +1171,7 @@
 
 	t = ClosestTownFromTile(tile, (uint)-1);
 
-	if (_settings.economy.multiple_industry_per_town) return t;
+	if (_settings_game.economy.multiple_industry_per_town) return t;
 
 	FOR_ALL_INDUSTRIES(i) {
 		if (i->type == (byte)type &&
@@ -1257,7 +1257,7 @@
 	/* It is almost impossible to have a fully flat land in TG, so what we
 	 *  do is that we check if we can make the land flat later on. See
 	 *  CheckIfCanLevelIndustryPlatform(). */
-	return !refused_slope || (_settings.game_creation.land_generator == LG_TERRAGENESIS && _generating_world && !custom_shape && !_ignore_restrictions);
+	return !refused_slope || (_settings_game.game_creation.land_generator == LG_TERRAGENESIS && _generating_world && !custom_shape && !_ignore_restrictions);
 }
 
 static bool CheckIfIndustryIsAllowed(TileIndex tile, int type, const Town *t)
@@ -1387,7 +1387,7 @@
 	const IndustrySpec *indspec = GetIndustrySpec(type);
 	const Industry *i;
 
-	if (_settings.economy.same_industry_close && indspec->IsRawIndustry())
+	if (_settings_game.economy.same_industry_close && indspec->IsRawIndustry())
 		/* Allow primary industries to be placed close to any other industry */
 		return true;
 
@@ -1401,8 +1401,8 @@
 				indspec->accepts_cargo[0] == i->accepts_cargo[0] && (
 				/* at least one of those options must be true */
 				_game_mode != GM_EDITOR || // editor must not be stopped
-				!_settings.economy.same_industry_close ||
-				!_settings.economy.multiple_industry_per_town)) {
+				!_settings_game.economy.same_industry_close ||
+				!_settings_game.economy.multiple_industry_per_town)) {
 			_error_message = STR_INDUSTRY_TOO_CLOSE;
 			return false;
 		}
@@ -1449,7 +1449,7 @@
 	i->production_rate[1] = indspec->production_rate[1];
 
 	/* don't use smooth economy for industries using production related callbacks */
-	if (_settings.economy.smooth_economy &&
+	if (_settings_game.economy.smooth_economy &&
 	    !(HasBit(indspec->callback_flags, CBM_IND_PRODUCTION_256_TICKS) || HasBit(indspec->callback_flags, CBM_IND_PRODUCTION_CARGO_ARRIVAL)) && // production callbacks
 	    !(HasBit(indspec->callback_flags, CBM_IND_MONTHLYPROD_CHANGE) || HasBit(indspec->callback_flags, CBM_IND_PRODUCTION_CHANGE))             // production change callbacks
 	) {
@@ -1577,7 +1577,7 @@
 		if (!_check_new_industry_procs[indspec->check_proc](tile)) return NULL;
 	}
 
-	if (!custom_shape_check && _settings.game_creation.land_generator == LG_TERRAGENESIS && _generating_world && !_ignore_restrictions && !CheckIfCanLevelIndustryPlatform(tile, 0, it, type)) return NULL;
+	if (!custom_shape_check && _settings_game.game_creation.land_generator == LG_TERRAGENESIS && _generating_world && !_ignore_restrictions && !CheckIfCanLevelIndustryPlatform(tile, 0, it, type)) return NULL;
 	if (!CheckIfFarEnoughFromIndustry(tile, type)) return NULL;
 
 	const Town *t = CheckMultipleIndustryInTown(tile, type);
@@ -1621,11 +1621,11 @@
 
 	/* If the patch for raw-material industries is not on, you cannot build raw-material industries.
 	 * Raw material industries are industries that do not accept cargo (at least for now) */
-	if (_game_mode != GM_EDITOR && _settings.construction.raw_industry_construction == 0 && indspec->IsRawIndustry()) {
+	if (_game_mode != GM_EDITOR && _settings_game.construction.raw_industry_construction == 0 && indspec->IsRawIndustry()) {
 		return CMD_ERROR;
 	}
 
-	if (_game_mode != GM_EDITOR && _settings.construction.raw_industry_construction == 2 && indspec->IsRawIndustry()) {
+	if (_game_mode != GM_EDITOR && _settings_game.construction.raw_industry_construction == 2 && indspec->IsRawIndustry()) {
 		if (flags & DC_EXEC) {
 			/* Prospecting has a chance to fail, however we cannot guarantee that something can
 			 * be built on the map, so the chance gets lower when the map is fuller, but there
@@ -1700,13 +1700,13 @@
 {
 	/* We need to bypass the amount given in parameter if it exceeds the maximum dimension of the
 	 * _numof_industry_table.  newgrf can specify a big amount */
-	int num = (amount > NB_NUMOFINDUSTRY) ? amount : _numof_industry_table[_settings.difficulty.number_industries][amount];
+	int num = (amount > NB_NUMOFINDUSTRY) ? amount : _numof_industry_table[_settings_game.difficulty.number_industries][amount];
 	const IndustrySpec *ind_spc = GetIndustrySpec(type);
 
 	/* These are always placed next to the coastline, so we scale by the perimeter instead. */
 	num = (ind_spc->check_proc == CHECK_REFINERY || ind_spc->check_proc == CHECK_OIL_RIG) ? ScaleByMapSize1D(num) : ScaleByMapSize(num);
 
-	if (_settings.difficulty.number_industries != 0) {
+	if (_settings_game.difficulty.number_industries != 0) {
 		PlayerID old_player = _current_player;
 		_current_player = OWNER_NONE;
 		assert(num > 0);
@@ -1735,7 +1735,7 @@
 	const IndustrySpec *ind_spc;
 
 	/* Find the total amount of industries */
-	if (_settings.difficulty.number_industries > 0) {
+	if (_settings_game.difficulty.number_industries > 0) {
 		for (it = 0; it < NUM_INDUSTRYTYPES; it++) {
 
 			ind_spc = GetIndustrySpec(it);
@@ -1744,12 +1744,12 @@
 				ResetIndustryCreationProbility(it);
 			}
 
-			chance = ind_spc->appear_creation[_settings.game_creation.landscape];
+			chance = ind_spc->appear_creation[_settings_game.game_creation.landscape];
 			if (ind_spc->enabled && chance > 0) {
 				/* once the chance of appearance is determind, it have to be scaled by
 				 * the difficulty level. The "chance" in question is more an index into
 				 * the _numof_industry_table,in fact */
-				int num = (chance > NB_NUMOFINDUSTRY) ? chance : _numof_industry_table[_settings.difficulty.number_industries][chance];
+				int num = (chance > NB_NUMOFINDUSTRY) ? chance : _numof_industry_table[_settings_game.difficulty.number_industries][chance];
 
 				/* These are always placed next to the coastline, so we scale by the perimeter instead. */
 				num = (ind_spc->check_proc == CHECK_REFINERY || ind_spc->check_proc == CHECK_OIL_RIG) ? ScaleByMapSize1D(num) : ScaleByMapSize(num);
@@ -1760,7 +1760,7 @@
 
 	SetGeneratingWorldProgress(GWP_INDUSTRY, i);
 
-	if (_settings.difficulty.number_industries > 0) {
+	if (_settings_game.difficulty.number_industries > 0) {
 		for (it = 0; it < NUM_INDUSTRYTYPES; it++) {
 			/* Once the number of industries has been determined, let's really create them.
 			 * The test for chance allows us to try create industries that are available only
@@ -1769,7 +1769,7 @@
 			 *          processed that scaling above? No, don't think so.  Will find a way. */
 			ind_spc = GetIndustrySpec(it);
 			if (ind_spc->enabled) {
-				chance = ind_spc->appear_creation[_settings.game_creation.landscape];
+				chance = ind_spc->appear_creation[_settings_game.game_creation.landscape];
 				if (chance > 0) PlaceInitialIndustry(it, chance);
 			}
 		}
@@ -1823,7 +1823,7 @@
 	/* Generate a list of all possible industries that can be built. */
 	for (j = 0; j < NUM_INDUSTRYTYPES; j++) {
 		ind_spc = GetIndustrySpec(j);
-		byte chance = ind_spc->appear_ingame[_settings.game_creation.landscape];
+		byte chance = ind_spc->appear_ingame[_settings_game.game_creation.landscape];
 
 		if (!ind_spc->enabled || chance == 0) continue;
 
@@ -1881,7 +1881,7 @@
 	const IndustrySpec *indspec = GetIndustrySpec(type);
 
 	/* oil wells (or the industries with that flag set) are always allowed to closedown */
-	if (indspec->behaviour & INDUSTRYBEH_DONT_INCR_PROD && _settings.game_creation.landscape == LT_TEMPERATE) return false;
+	if (indspec->behaviour & INDUSTRYBEH_DONT_INCR_PROD && _settings_game.game_creation.landscape == LT_TEMPERATE) return false;
 	return (indspec->behaviour & INDUSTRYBEH_CANCLOSE_LASTINSTANCE) == 0 && GetIndustryTypeCount(type) <= 1;
 }
 
@@ -2031,7 +2031,7 @@
 	bool standard = true;
 	bool suppress_message = false;
 	/* don't use smooth economy for industries using production related callbacks */
-	bool smooth_economy = _settings.economy.smooth_economy &&
+	bool smooth_economy = _settings_game.economy.smooth_economy &&
 	                      !(HasBit(indspec->callback_flags, CBM_IND_PRODUCTION_256_TICKS) || HasBit(indspec->callback_flags, CBM_IND_PRODUCTION_CARGO_ARRIVAL)) && // production callbacks
 	                      !(HasBit(indspec->callback_flags, CBM_IND_MONTHLYPROD_CHANGE) || HasBit(indspec->callback_flags, CBM_IND_PRODUCTION_CHANGE));            // production change callbacks
 	byte div = 0;
@@ -2072,7 +2072,7 @@
 
 	if (standard && (indspec->life_type & (INDUSTRYLIFE_ORGANIC | INDUSTRYLIFE_EXTRACTIVE)) != 0) {
 		/* decrease or increase */
-		bool only_decrease = (indspec->behaviour & INDUSTRYBEH_DONT_INCR_PROD) && _settings.game_creation.landscape == LT_TEMPERATE;
+		bool only_decrease = (indspec->behaviour & INDUSTRYBEH_DONT_INCR_PROD) && _settings_game.game_creation.landscape == LT_TEMPERATE;
 
 		if (smooth_economy) {
 			closeit = true;
@@ -2257,7 +2257,7 @@
 Money IndustrySpec::GetConstructionCost() const
 {
 	return (_price.build_industry *
-			(_settings.construction.raw_industry_construction == 1 && this->IsRawIndustry() ?
+			(_settings_game.construction.raw_industry_construction == 1 && this->IsRawIndustry() ?
 					this->raw_industry_cost_multiplier :
 					this->cost_multiplier
 			)) >> 8;
--- a/src/industry_gui.cpp	Thu May 29 12:52:24 2008 +0000
+++ b/src/industry_gui.cpp	Thu May 29 15:56:32 2008 +0000
@@ -27,6 +27,7 @@
 #include "tilehighlight_func.h"
 #include "string_func.h"
 #include "sortlist_type.h"
+#include "widgets/dropdown_func.h"
 
 #include "table/strings.h"
 #include "table/sprites.h"
@@ -131,7 +132,7 @@
 				/* Rule is that editor mode loads all industries.
 				 * In game mode, all non raw industries are loaded too
 				 * and raw ones are loaded only when setting allows it */
-				if (_game_mode != GM_EDITOR && indsp->IsRawIndustry() && _settings.construction.raw_industry_construction == 0) {
+				if (_game_mode != GM_EDITOR && indsp->IsRawIndustry() && _settings_game.construction.raw_industry_construction == 0) {
 					/* Unselect if the industry is no longer in the list */
 					if (this->selected_type == ind) this->selected_index = -1;
 					continue;
@@ -195,10 +196,10 @@
 		 * In Editor, you just build, while ingame, or you fund or you prospect */
 		if (_game_mode == GM_EDITOR) {
 			/* We've chosen many random industries but no industries have been specified */
-			if (indsp == NULL) this->enabled[this->selected_index] = _settings.difficulty.number_industries != 0;
+			if (indsp == NULL) this->enabled[this->selected_index] = _settings_game.difficulty.number_industries != 0;
 			this->widget[DPIW_FUND_WIDGET].data = STR_BUILD_NEW_INDUSTRY;
 		} else {
-			this->widget[DPIW_FUND_WIDGET].data = (_settings.construction.raw_industry_construction == 2 && indsp->IsRawIndustry()) ? STR_PROSPECT_NEW_INDUSTRY : STR_FUND_NEW_INDUSTRY;
+			this->widget[DPIW_FUND_WIDGET].data = (_settings_game.construction.raw_industry_construction == 2 && indsp->IsRawIndustry()) ? STR_PROSPECT_NEW_INDUSTRY : STR_FUND_NEW_INDUSTRY;
 		}
 		this->SetWidgetDisabledState(DPIW_FUND_WIDGET, !this->enabled[this->selected_index]);
 
@@ -304,7 +305,7 @@
 
 					this->SetDirty();
 
-					if ((_game_mode != GM_EDITOR && _settings.construction.raw_industry_construction == 2 && indsp != NULL && indsp->IsRawIndustry()) ||
+					if ((_game_mode != GM_EDITOR && _settings_game.construction.raw_industry_construction == 2 && indsp != NULL && indsp->IsRawIndustry()) ||
 							this->selected_type == INVALID_INDUSTRYTYPE) {
 						/* Reset the button state if going to prospecting or "build many industries" */
 						this->RaiseButtons();
@@ -325,7 +326,7 @@
 						GenerateIndustries();
 						_generating_world = false;
 					}
-				} else if (_game_mode != GM_EDITOR && _settings.construction.raw_industry_construction == 2 && GetIndustrySpec(this->selected_type)->IsRawIndustry()) {
+				} else if (_game_mode != GM_EDITOR && _settings_game.construction.raw_industry_construction == 2 && GetIndustrySpec(this->selected_type)->IsRawIndustry()) {
 					DoCommandP(0, this->selected_type, InteractiveRandom(), NULL, CMD_BUILD_INDUSTRY | CMD_MSG(STR_4830_CAN_T_CONSTRUCT_THIS_INDUSTRY));
 					this->HandleButtonClick(DPIW_FUND_WIDGET);
 				} else {
@@ -691,10 +692,8 @@
 	IDW_CLOSEBOX = 0,
 	IDW_CAPTION,
 	IDW_STICKY,
-	IDW_SORTBYNAME,
-	IDW_SORTBYTYPE,
-	IDW_SORTBYPROD,
-	IDW_SORTBYTRANSPORT,
+	IDW_DROPDOWN_ORDER,
+	IDW_DROPDOWN_CRITERIA,
 	IDW_SPACER,
 	IDW_INDUSTRY_LIST,
 	IDW_SCROLLBAR,
@@ -704,160 +703,149 @@
 /** Widget definition of the industy directory gui */
 static const Widget _industry_directory_widgets[] = {
 {   WWT_CLOSEBOX,   RESIZE_NONE,    13,     0,    10,     0,    13, STR_00C5,                STR_018B_CLOSE_WINDOW},             // IDW_CLOSEBOX
-{    WWT_CAPTION,  RESIZE_RIGHT,    13,    11,   495,     0,    13, STR_INDUSTRYDIR_CAPTION, STR_018C_WINDOW_TITLE_DRAG_THIS},   // IDW_CAPTION
-{  WWT_STICKYBOX,     RESIZE_LR,    13,   496,   507,     0,    13, 0x0,                     STR_STICKY_BUTTON},                 // IDW_STICKY
-{ WWT_PUSHTXTBTN,   RESIZE_NONE,    13,     0,   100,    14,    25, STR_SORT_BY_NAME,        STR_SORT_ORDER_TIP},                // IDW_SORTBYNAME
-{ WWT_PUSHTXTBTN,   RESIZE_NONE,    13,   101,   200,    14,    25, STR_SORT_BY_TYPE,        STR_SORT_ORDER_TIP},                // IDW_SORTBYTYPE
-{ WWT_PUSHTXTBTN,   RESIZE_NONE,    13,   201,   300,    14,    25, STR_SORT_BY_PRODUCTION,  STR_SORT_ORDER_TIP},                // IDW_SORTBYPROD
-{ WWT_PUSHTXTBTN,   RESIZE_NONE,    13,   301,   400,    14,    25, STR_SORT_BY_TRANSPORTED, STR_SORT_ORDER_TIP},                // IDW_SORTBYTRANSPORT
-{      WWT_PANEL,  RESIZE_RIGHT,    13,   401,   495,    14,    25, 0x0,                     STR_NULL},                          // IDW_SPACER
-{      WWT_PANEL,     RESIZE_RB,    13,     0,   495,    26,   189, 0x0,                     STR_200A_TOWN_NAMES_CLICK_ON_NAME}, // IDW_INDUSRTY_LIST
-{  WWT_SCROLLBAR,    RESIZE_LRB,    13,   496,   507,    14,   177, 0x0,                     STR_0190_SCROLL_BAR_SCROLLS_LIST},  // IDW_SCROLLBAR
-{  WWT_RESIZEBOX,   RESIZE_LRTB,    13,   496,   507,   178,   189, 0x0,                     STR_RESIZE_BUTTON},                 // IDW_RESIZE
+{    WWT_CAPTION,  RESIZE_RIGHT,    13,    11,   415,     0,    13, STR_INDUSTRYDIR_CAPTION, STR_018C_WINDOW_TITLE_DRAG_THIS},   // IDW_CAPTION
+{  WWT_STICKYBOX,     RESIZE_LR,    13,   416,   427,     0,    13, 0x0,                     STR_STICKY_BUTTON},                 // IDW_STICKY
+
+{    WWT_TEXTBTN,   RESIZE_NONE,    13,     0,    80,    14,    25, STR_SORT_BY,             STR_SORT_ORDER_TIP},                // IDW_DROPDOWN_ORDER
+{   WWT_DROPDOWN,   RESIZE_NONE,    13,    81,   243,    14,    25, 0x0,                     STR_SORT_CRITERIA_TIP},             // IDW_DROPDOWN_CRITERIA
+{      WWT_PANEL,  RESIZE_RIGHT,    13,   244,   415,    14,    25, 0x0,                     STR_NULL},                          // IDW_SPACER
+
+{      WWT_PANEL,     RESIZE_RB,    13,     0,   415,    26,   189, 0x0,                     STR_200A_TOWN_NAMES_CLICK_ON_NAME}, // IDW_INDUSRTY_LIST
+{  WWT_SCROLLBAR,    RESIZE_LRB,    13,   416,   427,    14,   177, 0x0,                     STR_0190_SCROLL_BAR_SCROLLS_LIST},  // IDW_SCROLLBAR
+{  WWT_RESIZEBOX,   RESIZE_LRTB,    13,   416,   427,   178,   189, 0x0,                     STR_RESIZE_BUTTON},                 // IDW_RESIZE
 {   WIDGETS_END},
 };
 
-static char _bufcache[96];
-static const Industry* _last_industry;
-static int _internal_sort_order;
-
-/** Returns percents of cargo transported if industry produces this cargo, else -1
- * @param i industry to check
- * @param id cargo slot
- * @return percents of cargo transported, or -1 if industry doesn't use this cargo slot
- */
-static inline int GetCargoTransportedPercentsIfValid(const Industry *i, uint id)
-{
-	assert(id < lengthof(i->produced_cargo));
-
-	if (i->produced_cargo[id] == CT_INVALID) return 101;
-	return i->last_month_pct_transported[id] * 100 >> 8;
-}
-
-/** Returns value representing industry's transported cargo
- * percentage for industry sorting
- * @param i industry to check
- * @return value used for sorting
- */
-static int GetCargoTransportedSortValue(const Industry *i)
-{
-	int p1 = GetCargoTransportedPercentsIfValid(i, 0);
-	int p2 = GetCargoTransportedPercentsIfValid(i, 1);
-
-	if (p1 > p2) Swap(p1, p2); // lower value has higher priority
-
-	return (p1 << 8) + p2;
-}
-
-static int CDECL GeneralIndustrySorter(const void *a, const void *b)
-{
-	const Industry* i = *(const Industry**)a;
-	const Industry* j = *(const Industry**)b;
-	int r;
-
-	switch (_internal_sort_order >> 1) {
-		default: NOT_REACHED();
-		case 0: /* Sort by Name (handled later) */
-			r = 0;
-			break;
-
-		case 1: /* Sort by Type */
-			r = i->type - j->type;
-			break;
-
-		case 2: /* Sort by Production */
-			if (i->produced_cargo[0] == CT_INVALID) {
-				r = (j->produced_cargo[0] == CT_INVALID ? 0 : -1);
-			} else {
-				if (j->produced_cargo[0] == CT_INVALID) {
-					r = 1;
-				} else {
-					r =
-						(i->last_month_production[0] + i->last_month_production[1]) -
-						(j->last_month_production[0] + j->last_month_production[1]);
-				}
-			}
-			break;
-
-		case 3: /* Sort by transported fraction */
-			r = GetCargoTransportedSortValue(i) - GetCargoTransportedSortValue(j);
-			break;
-	}
-
-	/* default to string sorting if they are otherwise equal */
-	if (r == 0) {
-		char buf1[96];
-
-		SetDParam(0, i->town->index);
-		GetString(buf1, STR_TOWN, lastof(buf1));
-
-		if (j != _last_industry) {
-			_last_industry = j;
-			SetDParam(0, j->town->index);
-			GetString(_bufcache, STR_TOWN, lastof(_bufcache));
-		}
-		r = strcmp(buf1, _bufcache);
-	}
-
-	if (_internal_sort_order & 1) r = -r;
-	return r;
-}
-
 typedef GUIList<const Industry*> GUIIndustryList;
 
-/**
- * Rebuild industries list if the VL_REBUILD flag is set
- *
- * @param sl pointer to industry list
- */
-static void BuildIndustriesList(GUIIndustryList *sl)
-{
-	uint n = 0;
-	const Industry *i;
-
-	if (!(sl->flags & VL_REBUILD)) return;
-
-	/* Create array for sorting */
-	const Industry **industry_sort = MallocT<const Industry*>(GetMaxIndustryIndex() + 1);
-
-	DEBUG(misc, 3, "Building industry list");
-
-	FOR_ALL_INDUSTRIES(i) industry_sort[n++] = i;
-
-	free((void*)sl->sort_list);
-	sl->sort_list = MallocT<const Industry*>(n);
-	sl->list_length = n;
-
-	for (uint i = 0; i < n; ++i) sl->sort_list[i] = industry_sort[i];
-
-	sl->flags &= ~VL_REBUILD;
-	sl->flags |= VL_RESORT;
-	free((void*)industry_sort);
-}
-
-
-/**
- * Sort industry list if the VL_RESORT flag is set
- *
- * @param sl pointer to industry list
- */
-static void SortIndustriesList(GUIIndustryList *sl)
-{
-	if (!(sl->flags & VL_RESORT)) return;
-
-	_internal_sort_order = (sl->sort_type << 1) | (sl->flags & VL_DESC);
-	_last_industry = NULL; // used for "cache" in namesorting
-	qsort((void*)sl->sort_list, sl->list_length, sizeof(sl->sort_list[0]), &GeneralIndustrySorter);
-
-	sl->flags &= ~VL_RESORT;
-}
 
 /**
  * The list of industries.
  */
-struct IndustryDirectoryWindow : public Window, public GUIIndustryList {
-	static Listing industry_sort;
+class IndustryDirectoryWindow : public Window {
+protected:
+	/* Runtime saved values */
+	static Listing last_sorting;
+	static const Industry *last_industry;
 
+	/* Constants for sorting stations */
+	static const StringID sorter_names[];
+	static GUIIndustryList::SortFunction *const sorter_funcs[];
+
+	GUIIndustryList industries;
+
+	/** (Re)Build industries list */
+	void BuildIndustriesList()
+	{
+		if (!this->industries.NeedRebuild()) return;
+
+		this->industries.Clear();
+
+		DEBUG(misc, 3, "Building industry list");
+
+		const Industry *i;
+		FOR_ALL_INDUSTRIES(i) {
+			*this->industries.Append() = i;
+		}
+
+		this->industries.Compact();
+		this->industries.RebuildDone();
+	}
+
+	/**
+	 * Returns percents of cargo transported if industry produces this cargo, else -1
+	 *
+	 * @param i industry to check
+	 * @param id cargo slot
+	 * @return percents of cargo transported, or -1 if industry doesn't use this cargo slot
+	 */
+	static inline int GetCargoTransportedPercentsIfValid(const Industry *i, uint id)
+	{
+		assert(id < lengthof(i->produced_cargo));
+
+		if (i->produced_cargo[id] == CT_INVALID) return 101;
+		return i->last_month_pct_transported[id] * 100 >> 8;
+	}
+
+	/**
+	 * Returns value representing industry's transported cargo
+	 *  percentage for industry sorting
+	 *
+	 * @param i industry to check
+	 * @return value used for sorting
+	 */
+	static int GetCargoTransportedSortValue(const Industry *i)
+	{
+		int p1 = GetCargoTransportedPercentsIfValid(i, 0);
+		int p2 = GetCargoTransportedPercentsIfValid(i, 1);
+
+		if (p1 > p2) Swap(p1, p2); // lower value has higher priority
+
+		return (p1 << 8) + p2;
+	}
+
+	/** Sort industries by name */
+	static int CDECL IndustryNameSorter(const Industry* const *a, const Industry* const *b)
+	{
+		static char buf_cache[96];
+		static char buf[96];
+
+		SetDParam(0, (*a)->town->index);
+		GetString(buf, STR_TOWN, lastof(buf));
+
+		if (*b != last_industry) {
+			last_industry = *b;
+			SetDParam(0, (*b)->town->index);
+			GetString(buf_cache, STR_TOWN, lastof(buf_cache));
+		}
+
+		return strcmp(buf, buf_cache);
+	}
+
+	/** Sort industries by type and name */
+	static int CDECL IndustryTypeSorter(const Industry* const *a, const Industry* const *b)
+	{
+		int r = (*a)->type - (*b)->type;
+		return (r = 0) ? IndustryNameSorter(a, b) : r;
+	}
+
+	/** Sort industries by production and name */
+	static int CDECL IndustryProductionSorter(const Industry* const *a, const Industry* const *b)
+	{
+		int r;
+
+		if ((*a)->produced_cargo[0] == CT_INVALID) {
+			if ((*b)->produced_cargo[0] != CT_INVALID) return -1;
+		} else {
+			if ((*b)->produced_cargo[0] == CT_INVALID) return 1;
+
+			r = ((*a)->last_month_production[0] + (*a)->last_month_production[1]) -
+			    ((*b)->last_month_production[0] + (*b)->last_month_production[1]);
+		}
+
+		return (r = 0) ? IndustryNameSorter(a, b) : r;
+	}
+
+	/** Sort industries by transported cargo and name */
+	static int CDECL IndustryTransportedCargoSorter(const Industry* const *a, const Industry* const *b)
+	{
+		int r = GetCargoTransportedSortValue(*a) - GetCargoTransportedSortValue(*b);
+		return (r = 0) ? IndustryNameSorter(a, b) : r;
+	}
+
+	/** Sort the industries list */
+	void SortIndustriesList()
+	{
+		if (!this->industries.Sort()) return;
+
+		/* Reset name sorter sort cache */
+		this->last_industry = NULL;
+
+		/* Set the modified widget dirty */
+		this->InvalidateWidget(IDW_INDUSTRY_LIST);
+	}
+
+public:
 	IndustryDirectoryWindow(const WindowDesc *desc, WindowNumber number) : Window(desc, number)
 	{
 		this->vscroll.cap = 16;
@@ -865,27 +853,35 @@
 		this->resize.step_height = 10;
 		this->FindWindowPlacementAndResize(desc);
 
-		this->sort_list = NULL;
-		this->flags = VL_REBUILD;
-		this->sort_type = industry_sort.criteria;
-		if (industry_sort.order) this->flags |= VL_DESC;
+		this->industries.SetListing(this->last_sorting);
+		this->industries.SetSortFuncs(this->sorter_funcs);
+		this->industries.ForceRebuild();
+		this->industries.NeedResort();
+		this->SortIndustriesList();
+
+		this->widget[IDW_DROPDOWN_CRITERIA].data = this->sorter_names[this->industries.SortType()];
+	}
+
+	~IndustryDirectoryWindow()
+	{
+		this->last_sorting = this->industries.GetListing();
 	}
 
 	virtual void OnPaint()
 	{
-		BuildIndustriesList(this);
-		SortIndustriesList(this);
+		BuildIndustriesList();
+		SortIndustriesList();
 
-		SetVScrollCount(this, this->list_length);
+		SetVScrollCount(this, this->industries.Length());
 
 		this->DrawWidgets();
-		this->DrawSortButtonState(IDW_SORTBYNAME + this->sort_type, this->flags & VL_DESC ? SBS_DOWN : SBS_UP);
+		this->DrawSortButtonState(IDW_DROPDOWN_ORDER, this->industries.IsDescSortOrder() ? SBS_DOWN : SBS_UP);
 
-		int max = min(this->vscroll.pos + this->vscroll.cap, this->list_length);
+		int max = min(this->vscroll.pos + this->vscroll.cap, this->industries.Length());
 		int y = 28; // start of the list-widget
 
 		for (int n = this->vscroll.pos; n < max; ++n) {
-			const Industry* i = this->sort_list[n];
+			const Industry* i = this->industries[n];
 			const IndustrySpec *indsp = GetIndustrySpec(i->type);
 			byte p = 0;
 
@@ -918,39 +914,41 @@
 	virtual void OnClick(Point pt, int widget)
 	{
 		switch (widget) {
-			case IDW_SORTBYNAME:
-			case IDW_SORTBYTYPE:
-			case IDW_SORTBYPROD:
-			case IDW_SORTBYTRANSPORT:
-				if (this->sort_type == (widget - IDW_SORTBYNAME)) {
-					this->flags ^= VL_DESC;
-				} else {
-					this->sort_type = widget - IDW_SORTBYNAME;
-					this->flags &= ~VL_DESC;
-				}
-				industry_sort.criteria = this->sort_type;
-				industry_sort.order = HasBit(this->flags, 0);
-				this->flags |= VL_RESORT;
+			case IDW_DROPDOWN_ORDER:
+				this->industries.ToggleSortOrder();
 				this->SetDirty();
 				break;
 
+			case IDW_DROPDOWN_CRITERIA:
+				ShowDropDownMenu(this, this->sorter_names, this->industries.SortType(), IDW_DROPDOWN_CRITERIA, 0, 0);
+				break;
+
 			case IDW_INDUSTRY_LIST: {
 				int y = (pt.y - 28) / 10;
 				uint16 p;
 
 				if (!IsInsideMM(y, 0, this->vscroll.cap)) return;
 				p = y + this->vscroll.pos;
-				if (p < this->list_length) {
+				if (p < this->industries.Length()) {
 					if (_ctrl_pressed) {
-						ShowExtraViewPortWindow(this->sort_list[p]->xy);
+						ShowExtraViewPortWindow(this->industries[p]->xy);
 					} else {
-						ScrollMainWindowToTile(this->sort_list[p]->xy);
+						ScrollMainWindowToTile(this->industries[p]->xy);
 					}
 				}
 			} break;
 		}
 	}
 
+	virtual void OnDropdownSelect(int widget, int index)
+	{
+		if (this->industries.SortType() != index) {
+			this->industries.SetSortType(index);
+			this->widget[IDW_DROPDOWN_CRITERIA].data = this->sorter_names[this->industries.SortType()];
+			this->SetDirty();
+		}
+	}
+
 	virtual void OnResize(Point new_size, Point delta)
 	{
 		this->vscroll.cap += delta.y / 10;
@@ -958,16 +956,39 @@
 
 	virtual void OnInvalidateData(int data)
 	{
-		this->flags |= (data == 0 ? VL_REBUILD : VL_RESORT);
+		if (data == 0) {
+			this->industries.ForceRebuild();
+		} else {
+			this->industries.ForceResort();
+		}
 		this->InvalidateWidget(IDW_INDUSTRY_LIST);
 	}
 };
 
-Listing IndustryDirectoryWindow::industry_sort = {0, 0};
+Listing IndustryDirectoryWindow::last_sorting = {false, 0};
+const Industry *IndustryDirectoryWindow::last_industry = NULL;
+
+/* Availible station sorting functions */
+GUIIndustryList::SortFunction* const IndustryDirectoryWindow::sorter_funcs[] = {
+	&IndustryNameSorter,
+	&IndustryTypeSorter,
+	&IndustryProductionSorter,
+	&IndustryTransportedCargoSorter
+};
+
+/* Names of the sorting functions */
+const StringID IndustryDirectoryWindow::sorter_names[] = {
+	STR_SORT_BY_DROPDOWN_NAME,
+	STR_SORT_BY_TYPE,
+	STR_SORT_BY_PRODUCTION,
+	STR_SORT_BY_TRANSPORTED,
+	INVALID_STRING_ID
+};
+
 
 /** Window definition of the industy directory gui */
 static const WindowDesc _industry_directory_desc = {
-	WDP_AUTO, WDP_AUTO, 508, 190, 508, 190,
+	WDP_AUTO, WDP_AUTO, 428, 190, 428, 190,
 	WC_INDUSTRY_DIRECTORY, WC_NONE,
 	WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS | WDF_STICKY_BUTTON | WDF_RESIZABLE,
 	_industry_directory_widgets,
--- a/src/landscape.cpp	Thu May 29 12:52:24 2008 +0000
+++ b/src/landscape.cpp	Thu May 29 15:56:32 2008 +0000
@@ -526,7 +526,7 @@
  */
 byte GetSnowLine(void)
 {
-	if (_snow_line == NULL) return _settings.game_creation.snow_line;
+	if (_snow_line == NULL) return _settings_game.game_creation.snow_line;
 
 	YearMonthDay ymd;
 	ConvertDateToYMD(_date, &ymd);
@@ -539,7 +539,7 @@
  */
 byte HighestSnowLine(void)
 {
-	return _snow_line == NULL ? _settings.game_creation.snow_line : _snow_line->highest_value;
+	return _snow_line == NULL ? _settings_game.game_creation.snow_line : _snow_line->highest_value;
 }
 
 /**
@@ -818,14 +818,14 @@
 	static const int gwp_desert_amount = 4 + 8;
 
 	if (mode == GW_HEIGHTMAP) {
-		SetGeneratingWorldProgress(GWP_LANDSCAPE, (_settings.game_creation.landscape == LT_TROPIC) ? 1 + gwp_desert_amount : 1);
+		SetGeneratingWorldProgress(GWP_LANDSCAPE, (_settings_game.game_creation.landscape == LT_TROPIC) ? 1 + gwp_desert_amount : 1);
 		LoadHeightmap(_file_to_saveload.name);
 		IncreaseGeneratingWorldProgress(GWP_LANDSCAPE);
-	} else if (_settings.game_creation.land_generator == LG_TERRAGENESIS) {
-		SetGeneratingWorldProgress(GWP_LANDSCAPE, (_settings.game_creation.landscape == LT_TROPIC) ? 3 + gwp_desert_amount : 3);
+	} else if (_settings_game.game_creation.land_generator == LG_TERRAGENESIS) {
+		SetGeneratingWorldProgress(GWP_LANDSCAPE, (_settings_game.game_creation.landscape == LT_TROPIC) ? 3 + gwp_desert_amount : 3);
 		GenerateTerrainPerlin();
 	} else {
-		switch (_settings.game_creation.landscape) {
+		switch (_settings_game.game_creation.landscape) {
 			case LT_ARCTIC: {
 				SetGeneratingWorldProgress(GWP_LANDSCAPE, 2);
 
@@ -872,9 +872,9 @@
 
 				uint32 r = Random();
 
-				uint i = ScaleByMapSize(GB(r, 0, 7) + (3 - _settings.difficulty.quantity_sea_lakes) * 256 + 100);
+				uint i = ScaleByMapSize(GB(r, 0, 7) + (3 - _settings_game.difficulty.quantity_sea_lakes) * 256 + 100);
 				for (; i != 0; --i) {
-					GenerateTerrain(_settings.difficulty.terrain_type, 0);
+					GenerateTerrain(_settings_game.difficulty.terrain_type, 0);
 				}
 				IncreaseGeneratingWorldProgress(GWP_LANDSCAPE);
 			} break;
@@ -883,7 +883,7 @@
 
 	ConvertGroundTilesIntoWaterTiles();
 
-	if (_settings.game_creation.landscape == LT_TROPIC) CreateDesertOrRainForest();
+	if (_settings_game.game_creation.landscape == LT_TROPIC) CreateDesertOrRainForest();
 }
 
 void OnTick_Town();
--- a/src/lang/afrikaans.txt	Thu May 29 12:52:24 2008 +0000
+++ b/src/lang/afrikaans.txt	Thu May 29 15:56:32 2008 +0000
@@ -361,9 +361,9 @@
 STR_SORT_BY                                                     :{BLACK}Sorteer by
 
 STR_SORT_BY_POPULATION                                          :{BLACK}Populasie
-STR_SORT_BY_PRODUCTION                                          :{BLACK}Produksie
-STR_SORT_BY_TYPE                                                :{BLACK}Tipe
-STR_SORT_BY_TRANSPORTED                                         :{BLACK}Uitgervoer
+STR_SORT_BY_PRODUCTION                                          :Produksie
+STR_SORT_BY_TYPE                                                :Tipe
+STR_SORT_BY_TRANSPORTED                                         :Uitgervoer
 STR_SORT_BY_NAME                                                :{BLACK}Naam
 STR_SORT_BY_DROPDOWN_NAME                                       :Naam
 STR_SORT_BY_DATE                                                :{BLACK}Datum
--- a/src/lang/brazilian_portuguese.txt	Thu May 29 12:52:24 2008 +0000
+++ b/src/lang/brazilian_portuguese.txt	Thu May 29 15:56:32 2008 +0000
@@ -364,9 +364,9 @@
 STR_SORT_BY                                                     :{BLACK}Ordenar por
 
 STR_SORT_BY_POPULATION                                          :{BLACK}População
-STR_SORT_BY_PRODUCTION                                          :{BLACK}Produção
-STR_SORT_BY_TYPE                                                :{BLACK}Tipo
-STR_SORT_BY_TRANSPORTED                                         :{BLACK}Transportado
+STR_SORT_BY_PRODUCTION                                          :Produção
+STR_SORT_BY_TYPE                                                :Tipo
+STR_SORT_BY_TRANSPORTED                                         :Transportado
 STR_SORT_BY_NAME                                                :{BLACK}Nome
 STR_SORT_BY_DROPDOWN_NAME                                       :Nome
 STR_SORT_BY_DATE                                                :{BLACK}Data
--- a/src/lang/bulgarian.txt	Thu May 29 12:52:24 2008 +0000
+++ b/src/lang/bulgarian.txt	Thu May 29 15:56:32 2008 +0000
@@ -365,9 +365,9 @@
 STR_SORT_BY                                                     :{BLACK}Сортирай по
 
 STR_SORT_BY_POPULATION                                          :{BLACK}Население
-STR_SORT_BY_PRODUCTION                                          :{BLACK}Продукция
-STR_SORT_BY_TYPE                                                :{BLACK}Вид
-STR_SORT_BY_TRANSPORTED                                         :{BLACK}Транспортирано
+STR_SORT_BY_PRODUCTION                                          :Продукция
+STR_SORT_BY_TYPE                                                :Вид
+STR_SORT_BY_TRANSPORTED                                         :Транспортирано
 STR_SORT_BY_NAME                                                :{BLACK}Име
 STR_SORT_BY_DROPDOWN_NAME                                       :Име
 STR_SORT_BY_DATE                                                :{BLACK}Дата
--- a/src/lang/catalan.txt	Thu May 29 12:52:24 2008 +0000
+++ b/src/lang/catalan.txt	Thu May 29 15:56:32 2008 +0000
@@ -363,9 +363,9 @@
 STR_SORT_BY                                                     :{BLACK}Ordenar per
 
 STR_SORT_BY_POPULATION                                          :{BLACK}Població
-STR_SORT_BY_PRODUCTION                                          :{BLACK}Producció
-STR_SORT_BY_TYPE                                                :{BLACK}Tipus
-STR_SORT_BY_TRANSPORTED                                         :{BLACK}Transportat
+STR_SORT_BY_PRODUCTION                                          :Producció
+STR_SORT_BY_TYPE                                                :Tipus
+STR_SORT_BY_TRANSPORTED                                         :Transportat
 STR_SORT_BY_NAME                                                :{BLACK}Nom
 STR_SORT_BY_DROPDOWN_NAME                                       :Nom
 STR_SORT_BY_DATE                                                :{BLACK}Data
--- a/src/lang/croatian.txt	Thu May 29 12:52:24 2008 +0000
+++ b/src/lang/croatian.txt	Thu May 29 15:56:32 2008 +0000
@@ -363,9 +363,9 @@
 STR_SORT_BY                                                     :{BLACK}Sortiraj prema
 
 STR_SORT_BY_POPULATION                                          :{BLACK}Stanovnici
-STR_SORT_BY_PRODUCTION                                          :{BLACK}Produkcija
-STR_SORT_BY_TYPE                                                :{BLACK}Vrsta
-STR_SORT_BY_TRANSPORTED                                         :{BLACK}Prevezeno
+STR_SORT_BY_PRODUCTION                                          :Produkcija
+STR_SORT_BY_TYPE                                                :Vrsta
+STR_SORT_BY_TRANSPORTED                                         :Prevezeno
 STR_SORT_BY_NAME                                                :{BLACK}Ime
 STR_SORT_BY_DROPDOWN_NAME                                       :Ime
 STR_SORT_BY_DATE                                                :{BLACK}Datum
--- a/src/lang/czech.txt	Thu May 29 12:52:24 2008 +0000
+++ b/src/lang/czech.txt	Thu May 29 15:56:32 2008 +0000
@@ -421,9 +421,9 @@
 STR_SORT_BY                                                     :{BLACK}Řadit podle
 
 STR_SORT_BY_POPULATION                                          :{BLACK}Populace
-STR_SORT_BY_PRODUCTION                                          :{BLACK}Prudukce
-STR_SORT_BY_TYPE                                                :{BLACK}Typu
-STR_SORT_BY_TRANSPORTED                                         :{BLACK}Přepraveno
+STR_SORT_BY_PRODUCTION                                          :Prudukce
+STR_SORT_BY_TYPE                                                :Typu
+STR_SORT_BY_TRANSPORTED                                         :Přepraveno
 STR_SORT_BY_NAME                                                :{BLACK}Podle jména
 STR_SORT_BY_DROPDOWN_NAME                                       :jména
 STR_SORT_BY_DATE                                                :{BLACK}Podle data
--- a/src/lang/danish.txt	Thu May 29 12:52:24 2008 +0000
+++ b/src/lang/danish.txt	Thu May 29 15:56:32 2008 +0000
@@ -362,9 +362,9 @@
 STR_SORT_BY                                                     :{BLACK}Sortér på
 
 STR_SORT_BY_POPULATION                                          :{BLACK}Indbyggertal
-STR_SORT_BY_PRODUCTION                                          :{BLACK}Produktion
-STR_SORT_BY_TYPE                                                :{BLACK}Type
-STR_SORT_BY_TRANSPORTED                                         :{BLACK}Transporteret
+STR_SORT_BY_PRODUCTION                                          :Produktion
+STR_SORT_BY_TYPE                                                :Type
+STR_SORT_BY_TRANSPORTED                                         :Transporteret
 STR_SORT_BY_NAME                                                :{BLACK}Navn
 STR_SORT_BY_DROPDOWN_NAME                                       :Navn
 STR_SORT_BY_DATE                                                :{BLACK}Dato
--- a/src/lang/dutch.txt	Thu May 29 12:52:24 2008 +0000
+++ b/src/lang/dutch.txt	Thu May 29 15:56:32 2008 +0000
@@ -363,9 +363,9 @@
 STR_SORT_BY                                                     :{BLACK}Sorteer op
 
 STR_SORT_BY_POPULATION                                          :{BLACK}Inwoners
-STR_SORT_BY_PRODUCTION                                          :{BLACK}Productie
-STR_SORT_BY_TYPE                                                :{BLACK}Soort
-STR_SORT_BY_TRANSPORTED                                         :{BLACK}Vervoerd
+STR_SORT_BY_PRODUCTION                                          :Productie
+STR_SORT_BY_TYPE                                                :Soort
+STR_SORT_BY_TRANSPORTED                                         :Vervoerd
 STR_SORT_BY_NAME                                                :{BLACK}Naam
 STR_SORT_BY_DROPDOWN_NAME                                       :Naam
 STR_SORT_BY_DATE                                                :{BLACK}Datum
--- a/src/lang/english.txt	Thu May 29 12:52:24 2008 +0000
+++ b/src/lang/english.txt	Thu May 29 15:56:32 2008 +0000
@@ -363,9 +363,9 @@
 STR_SORT_BY                                                     :{BLACK}Sort by
 
 STR_SORT_BY_POPULATION                                          :{BLACK}Population
-STR_SORT_BY_PRODUCTION                                          :{BLACK}Production
-STR_SORT_BY_TYPE                                                :{BLACK}Type
-STR_SORT_BY_TRANSPORTED                                         :{BLACK}Transported
+STR_SORT_BY_PRODUCTION                                          :Production
+STR_SORT_BY_TYPE                                                :Type
+STR_SORT_BY_TRANSPORTED                                         :Transported
 STR_SORT_BY_NAME                                                :{BLACK}Name
 STR_SORT_BY_DROPDOWN_NAME                                       :Name
 STR_SORT_BY_DATE                                                :{BLACK}Date
--- a/src/lang/english_US.txt	Thu May 29 12:52:24 2008 +0000
+++ b/src/lang/english_US.txt	Thu May 29 15:56:32 2008 +0000
@@ -361,9 +361,9 @@
 STR_SORT_BY                                                     :{BLACK}Sort by
 
 STR_SORT_BY_POPULATION                                          :{BLACK}Population
-STR_SORT_BY_PRODUCTION                                          :{BLACK}Production
-STR_SORT_BY_TYPE                                                :{BLACK}Type
-STR_SORT_BY_TRANSPORTED                                         :{BLACK}Transported
+STR_SORT_BY_PRODUCTION                                          :Production
+STR_SORT_BY_TYPE                                                :Type
+STR_SORT_BY_TRANSPORTED                                         :Transported
 STR_SORT_BY_NAME                                                :{BLACK}Name
 STR_SORT_BY_DROPDOWN_NAME                                       :Name
 STR_SORT_BY_DATE                                                :{BLACK}Date
--- a/src/lang/esperanto.txt	Thu May 29 12:52:24 2008 +0000
+++ b/src/lang/esperanto.txt	Thu May 29 15:56:32 2008 +0000
@@ -362,9 +362,9 @@
 STR_SORT_BY                                                     :{BLACK}Ordigu laŭ
 
 STR_SORT_BY_POPULATION                                          :{BLACK}Enloĝantaro
-STR_SORT_BY_PRODUCTION                                          :{BLACK}Produktado
-STR_SORT_BY_TYPE                                                :{BLACK}Tipo
-STR_SORT_BY_TRANSPORTED                                         :{BLACK}Transportiĝis
+STR_SORT_BY_PRODUCTION                                          :Produktado
+STR_SORT_BY_TYPE                                                :Tipo
+STR_SORT_BY_TRANSPORTED                                         :Transportiĝis
 STR_SORT_BY_NAME                                                :{BLACK}Nomo
 STR_SORT_BY_DROPDOWN_NAME                                       :Nomo
 STR_SORT_BY_DATE                                                :{BLACK}Dato
--- a/src/lang/estonian.txt	Thu May 29 12:52:24 2008 +0000
+++ b/src/lang/estonian.txt	Thu May 29 15:56:32 2008 +0000
@@ -463,9 +463,9 @@
 STR_SORT_BY                                                     :{BLACK}Sorteeri:
 
 STR_SORT_BY_POPULATION                                          :{BLACK}Rahvaarv
-STR_SORT_BY_PRODUCTION                                          :{BLACK}Toodang
-STR_SORT_BY_TYPE                                                :{BLACK}Tüüp
-STR_SORT_BY_TRANSPORTED                                         :{BLACK}Veetud
+STR_SORT_BY_PRODUCTION                                          :Toodang
+STR_SORT_BY_TYPE                                                :Tüüp
+STR_SORT_BY_TRANSPORTED                                         :Veetud
 STR_SORT_BY_NAME                                                :{BLACK}Nimi
 STR_SORT_BY_DROPDOWN_NAME                                       :Nimi
 STR_SORT_BY_DATE                                                :{BLACK}Daatum
--- a/src/lang/finnish.txt	Thu May 29 12:52:24 2008 +0000
+++ b/src/lang/finnish.txt	Thu May 29 15:56:32 2008 +0000
@@ -361,9 +361,9 @@
 STR_SORT_BY                                                     :{BLACK}Lajittele
 
 STR_SORT_BY_POPULATION                                          :{BLACK}Asukasluku
-STR_SORT_BY_PRODUCTION                                          :{BLACK}Tuotto
-STR_SORT_BY_TYPE                                                :{BLACK}Tyyppi
-STR_SORT_BY_TRANSPORTED                                         :{BLACK}Kuljetettu
+STR_SORT_BY_PRODUCTION                                          :Tuotto
+STR_SORT_BY_TYPE                                                :Tyyppi
+STR_SORT_BY_TRANSPORTED                                         :Kuljetettu
 STR_SORT_BY_NAME                                                :{BLACK}Nimi
 STR_SORT_BY_DROPDOWN_NAME                                       :Nimi
 STR_SORT_BY_DATE                                                :{BLACK}Päiväys
--- a/src/lang/french.txt	Thu May 29 12:52:24 2008 +0000
+++ b/src/lang/french.txt	Thu May 29 15:56:32 2008 +0000
@@ -364,9 +364,9 @@
 STR_SORT_BY                                                     :{BLACK}Trier par
 
 STR_SORT_BY_POPULATION                                          :{BLACK}Population
-STR_SORT_BY_PRODUCTION                                          :{BLACK}Production
-STR_SORT_BY_TYPE                                                :{BLACK}Type
-STR_SORT_BY_TRANSPORTED                                         :{BLACK}Transporté
+STR_SORT_BY_PRODUCTION                                          :Production
+STR_SORT_BY_TYPE                                                :Type
+STR_SORT_BY_TRANSPORTED                                         :Transporté
 STR_SORT_BY_NAME                                                :{BLACK}Nom
 STR_SORT_BY_DROPDOWN_NAME                                       :Nom
 STR_SORT_BY_DATE                                                :{BLACK}Date
--- a/src/lang/galician.txt	Thu May 29 12:52:24 2008 +0000
+++ b/src/lang/galician.txt	Thu May 29 15:56:32 2008 +0000
@@ -360,9 +360,9 @@
 STR_SORT_BY                                                     :{BLACK}Ordear por
 
 STR_SORT_BY_POPULATION                                          :{BLACK}Poboación
-STR_SORT_BY_PRODUCTION                                          :{BLACK}Producción
-STR_SORT_BY_TYPE                                                :{BLACK}Tipo
-STR_SORT_BY_TRANSPORTED                                         :{BLACK}Transportado
+STR_SORT_BY_PRODUCTION                                          :Producción
+STR_SORT_BY_TYPE                                                :Tipo
+STR_SORT_BY_TRANSPORTED                                         :Transportado
 STR_SORT_BY_NAME                                                :{BLACK}Nome
 STR_SORT_BY_DROPDOWN_NAME                                       :Nome
 STR_SORT_BY_DATE                                                :{BLACK}Data
--- a/src/lang/german.txt	Thu May 29 12:52:24 2008 +0000
+++ b/src/lang/german.txt	Thu May 29 15:56:32 2008 +0000
@@ -363,9 +363,9 @@
 STR_SORT_BY                                                     :{BLACK}Sortieren nach
 
 STR_SORT_BY_POPULATION                                          :{BLACK}Bevölkerung
-STR_SORT_BY_PRODUCTION                                          :{BLACK}Produktion
-STR_SORT_BY_TYPE                                                :{BLACK}Typ
-STR_SORT_BY_TRANSPORTED                                         :{BLACK}Transportiert
+STR_SORT_BY_PRODUCTION                                          :Produktion
+STR_SORT_BY_TYPE                                                :Typ
+STR_SORT_BY_TRANSPORTED                                         :Transportiert
 STR_SORT_BY_NAME                                                :{BLACK}Name
 STR_SORT_BY_DROPDOWN_NAME                                       :Name
 STR_SORT_BY_DATE                                                :{BLACK}Datum
--- a/src/lang/hungarian.txt	Thu May 29 12:52:24 2008 +0000
+++ b/src/lang/hungarian.txt	Thu May 29 15:56:32 2008 +0000
@@ -427,9 +427,9 @@
 STR_SORT_BY                                                     :{BLACK}Rendezés
 
 STR_SORT_BY_POPULATION                                          :{BLACK}Lakosság
-STR_SORT_BY_PRODUCTION                                          :{BLACK}Termelés
-STR_SORT_BY_TYPE                                                :{BLACK}Típus
-STR_SORT_BY_TRANSPORTED                                         :{BLACK}Elszállítás
+STR_SORT_BY_PRODUCTION                                          :Termelés
+STR_SORT_BY_TYPE                                                :Típus
+STR_SORT_BY_TRANSPORTED                                         :Elszállítás
 STR_SORT_BY_NAME                                                :{BLACK}Név
 STR_SORT_BY_DROPDOWN_NAME                                       :Név
 STR_SORT_BY_DATE                                                :{BLACK}Dátum
--- a/src/lang/icelandic.txt	Thu May 29 12:52:24 2008 +0000
+++ b/src/lang/icelandic.txt	Thu May 29 15:56:32 2008 +0000
@@ -363,9 +363,9 @@
 STR_SORT_BY                                                     :{BLACK}Flokka eftir
 
 STR_SORT_BY_POPULATION                                          :{BLACK}Fólksfjöldi
-STR_SORT_BY_PRODUCTION                                          :{BLACK}Framleiðsla
-STR_SORT_BY_TYPE                                                :{BLACK}Tegund
-STR_SORT_BY_TRANSPORTED                                         :{BLACK}Flutt
+STR_SORT_BY_PRODUCTION                                          :Framleiðsla
+STR_SORT_BY_TYPE                                                :Tegund
+STR_SORT_BY_TRANSPORTED                                         :Flutt
 STR_SORT_BY_NAME                                                :{BLACK}Nafn
 STR_SORT_BY_DROPDOWN_NAME                                       :Nafn
 STR_SORT_BY_DATE                                                :{BLACK}Dagsetning
--- a/src/lang/italian.txt	Thu May 29 12:52:24 2008 +0000
+++ b/src/lang/italian.txt	Thu May 29 15:56:32 2008 +0000
@@ -365,9 +365,9 @@
 STR_SORT_BY                                                     :{BLACK}Ordina per
 
 STR_SORT_BY_POPULATION                                          :{BLACK}Popolazione
-STR_SORT_BY_PRODUCTION                                          :{BLACK}Produzione
-STR_SORT_BY_TYPE                                                :{BLACK}Tipo
-STR_SORT_BY_TRANSPORTED                                         :{BLACK}Trasportato
+STR_SORT_BY_PRODUCTION                                          :Produzione
+STR_SORT_BY_TYPE                                                :Tipo
+STR_SORT_BY_TRANSPORTED                                         :Trasportato
 STR_SORT_BY_NAME                                                :{BLACK}Nome
 STR_SORT_BY_DROPDOWN_NAME                                       :Nome
 STR_SORT_BY_DATE                                                :{BLACK}Data
--- a/src/lang/japanese.txt	Thu May 29 12:52:24 2008 +0000
+++ b/src/lang/japanese.txt	Thu May 29 15:56:32 2008 +0000
@@ -362,9 +362,9 @@
 STR_SORT_BY                                                     :{BLACK}並べ替え
 
 STR_SORT_BY_POPULATION                                          :{BLACK}人口
-STR_SORT_BY_PRODUCTION                                          :{BLACK}生産量
-STR_SORT_BY_TYPE                                                :{BLACK}種類
-STR_SORT_BY_TRANSPORTED                                         :{BLACK}運送済み
+STR_SORT_BY_PRODUCTION                                          :生産量
+STR_SORT_BY_TYPE                                                :種類
+STR_SORT_BY_TRANSPORTED                                         :運送済み
 STR_SORT_BY_NAME                                                :{BLACK}名前
 STR_SORT_BY_DROPDOWN_NAME                                       :名前
 STR_SORT_BY_DATE                                                :{BLACK}日付
--- a/src/lang/korean.txt	Thu May 29 12:52:24 2008 +0000
+++ b/src/lang/korean.txt	Thu May 29 15:56:32 2008 +0000
@@ -363,9 +363,9 @@
 STR_SORT_BY                                                     :{BLACK}정렬
 
 STR_SORT_BY_POPULATION                                          :{BLACK}인구
-STR_SORT_BY_PRODUCTION                                          :{BLACK}생산
-STR_SORT_BY_TYPE                                                :{BLACK}종류
-STR_SORT_BY_TRANSPORTED                                         :{BLACK}수송량
+STR_SORT_BY_PRODUCTION                                          :생산
+STR_SORT_BY_TYPE                                                :종류
+STR_SORT_BY_TRANSPORTED                                         :수송량
 STR_SORT_BY_NAME                                                :{BLACK}이름
 STR_SORT_BY_DROPDOWN_NAME                                       :이름
 STR_SORT_BY_DATE                                                :{BLACK}날짜
--- a/src/lang/lithuanian.txt	Thu May 29 12:52:24 2008 +0000
+++ b/src/lang/lithuanian.txt	Thu May 29 15:56:32 2008 +0000
@@ -395,9 +395,9 @@
 STR_SORT_BY                                                     :{BLACK}Rikiuoti pagal
 
 STR_SORT_BY_POPULATION                                          :{BLACK}Populiacija
-STR_SORT_BY_PRODUCTION                                          :{BLACK}Produkcija
-STR_SORT_BY_TYPE                                                :{BLACK}Tipa
-STR_SORT_BY_TRANSPORTED                                         :{BLACK}Pervezimus
+STR_SORT_BY_PRODUCTION                                          :Produkcija
+STR_SORT_BY_TYPE                                                :Tipa
+STR_SORT_BY_TRANSPORTED                                         :Pervezimus
 STR_SORT_BY_NAME                                                :{BLACK}Varda
 STR_SORT_BY_DROPDOWN_NAME                                       :Varda
 STR_SORT_BY_DATE                                                :{BLACK}Data
--- a/src/lang/norwegian_bokmal.txt	Thu May 29 12:52:24 2008 +0000
+++ b/src/lang/norwegian_bokmal.txt	Thu May 29 15:56:32 2008 +0000
@@ -362,9 +362,9 @@
 STR_SORT_BY                                                     :{BLACK}Sorter etter
 
 STR_SORT_BY_POPULATION                                          :{BLACK}Innbyggertall
-STR_SORT_BY_PRODUCTION                                          :{BLACK}Produksjon
-STR_SORT_BY_TYPE                                                :{BLACK}Type
-STR_SORT_BY_TRANSPORTED                                         :{BLACK}Transportert
+STR_SORT_BY_PRODUCTION                                          :Produksjon
+STR_SORT_BY_TYPE                                                :Type
+STR_SORT_BY_TRANSPORTED                                         :Transportert
 STR_SORT_BY_NAME                                                :{BLACK}Navn
 STR_SORT_BY_DROPDOWN_NAME                                       :Navn
 STR_SORT_BY_DATE                                                :{BLACK}Dato
--- a/src/lang/norwegian_nynorsk.txt	Thu May 29 12:52:24 2008 +0000
+++ b/src/lang/norwegian_nynorsk.txt	Thu May 29 15:56:32 2008 +0000
@@ -362,9 +362,9 @@
 STR_SORT_BY                                                     :{BLACK}Sorter etter
 
 STR_SORT_BY_POPULATION                                          :{BLACK}Innbyggjartal
-STR_SORT_BY_PRODUCTION                                          :{BLACK}Produksjon
-STR_SORT_BY_TYPE                                                :{BLACK}Type
-STR_SORT_BY_TRANSPORTED                                         :{BLACK}Transportert
+STR_SORT_BY_PRODUCTION                                          :Produksjon
+STR_SORT_BY_TYPE                                                :Type
+STR_SORT_BY_TRANSPORTED                                         :Transportert
 STR_SORT_BY_NAME                                                :{BLACK}Namn
 STR_SORT_BY_DROPDOWN_NAME                                       :Namn
 STR_SORT_BY_DATE                                                :{BLACK}Dato
--- a/src/lang/piglatin.txt	Thu May 29 12:52:24 2008 +0000
+++ b/src/lang/piglatin.txt	Thu May 29 15:56:32 2008 +0000
@@ -361,9 +361,9 @@
 STR_SORT_BY                                                     :{BLACK}Ortsay ybay
 
 STR_SORT_BY_POPULATION                                          :{BLACK}Opulationpay
-STR_SORT_BY_PRODUCTION                                          :{BLACK}Oductionpray
-STR_SORT_BY_TYPE                                                :{BLACK}Ypetay
-STR_SORT_BY_TRANSPORTED                                         :{BLACK}Ansportedtray
+STR_SORT_BY_PRODUCTION                                          :Oductionpray
+STR_SORT_BY_TYPE                                                :Ypetay
+STR_SORT_BY_TRANSPORTED                                         :Ansportedtray
 STR_SORT_BY_NAME                                                :{BLACK}Amenay
 STR_SORT_BY_DROPDOWN_NAME                                       :Amenay
 STR_SORT_BY_DATE                                                :{BLACK}Ateday
--- a/src/lang/polish.txt	Thu May 29 12:52:24 2008 +0000
+++ b/src/lang/polish.txt	Thu May 29 15:56:32 2008 +0000
@@ -414,9 +414,9 @@
 STR_SORT_BY                                                     :{BLACK}Sortuj wg
 
 STR_SORT_BY_POPULATION                                          :{BLACK}Populacja
-STR_SORT_BY_PRODUCTION                                          :{BLACK}Produkcja
-STR_SORT_BY_TYPE                                                :{BLACK}Typ
-STR_SORT_BY_TRANSPORTED                                         :{BLACK}Przetransportowano
+STR_SORT_BY_PRODUCTION                                          :Produkcja
+STR_SORT_BY_TYPE                                                :Typ
+STR_SORT_BY_TRANSPORTED                                         :Przetransportowano
 STR_SORT_BY_NAME                                                :{BLACK}Nazwa
 STR_SORT_BY_DROPDOWN_NAME                                       :Nazwa
 STR_SORT_BY_DATE                                                :{BLACK}Data
--- a/src/lang/portuguese.txt	Thu May 29 12:52:24 2008 +0000
+++ b/src/lang/portuguese.txt	Thu May 29 15:56:32 2008 +0000
@@ -362,9 +362,9 @@
 STR_SORT_BY                                                     :{BLACK}Ordenar por
 
 STR_SORT_BY_POPULATION                                          :{BLACK}População
-STR_SORT_BY_PRODUCTION                                          :{BLACK}Produção
-STR_SORT_BY_TYPE                                                :{BLACK}Tipo
-STR_SORT_BY_TRANSPORTED                                         :{BLACK}Transportado
+STR_SORT_BY_PRODUCTION                                          :Produção
+STR_SORT_BY_TYPE                                                :Tipo
+STR_SORT_BY_TRANSPORTED                                         :Transportado
 STR_SORT_BY_NAME                                                :{BLACK}Nome
 STR_SORT_BY_DROPDOWN_NAME                                       :Nome
 STR_SORT_BY_DATE                                                :{BLACK}Data
--- a/src/lang/romanian.txt	Thu May 29 12:52:24 2008 +0000
+++ b/src/lang/romanian.txt	Thu May 29 15:56:32 2008 +0000
@@ -361,9 +361,9 @@
 STR_SORT_BY                                                     :{BLACK}Ordoneaza dupa
 
 STR_SORT_BY_POPULATION                                          :{BLACK}Populatia
-STR_SORT_BY_PRODUCTION                                          :{BLACK}Productie
-STR_SORT_BY_TYPE                                                :{BLACK}Tip
-STR_SORT_BY_TRANSPORTED                                         :{BLACK}Transportat
+STR_SORT_BY_PRODUCTION                                          :Productie
+STR_SORT_BY_TYPE                                                :Tip
+STR_SORT_BY_TRANSPORTED                                         :Transportat
 STR_SORT_BY_NAME                                                :{BLACK}Nume
 STR_SORT_BY_DROPDOWN_NAME                                       :Nume
 STR_SORT_BY_DATE                                                :{BLACK}Datã
--- a/src/lang/russian.txt	Thu May 29 12:52:24 2008 +0000
+++ b/src/lang/russian.txt	Thu May 29 15:56:32 2008 +0000
@@ -365,9 +365,9 @@
 STR_SORT_BY                                                     :{BLACK}Сортировка
 
 STR_SORT_BY_POPULATION                                          :{BLACK}Население
-STR_SORT_BY_PRODUCTION                                          :{BLACK}Продукция
-STR_SORT_BY_TYPE                                                :{BLACK}Тип
-STR_SORT_BY_TRANSPORTED                                         :{BLACK}Вывоз
+STR_SORT_BY_PRODUCTION                                          :Продукция
+STR_SORT_BY_TYPE                                                :Тип
+STR_SORT_BY_TRANSPORTED                                         :Вывоз
 STR_SORT_BY_NAME                                                :{BLACK}Имя
 STR_SORT_BY_DROPDOWN_NAME                                       :Название
 STR_SORT_BY_DATE                                                :{BLACK}Дата
--- a/src/lang/simplified_chinese.txt	Thu May 29 12:52:24 2008 +0000
+++ b/src/lang/simplified_chinese.txt	Thu May 29 15:56:32 2008 +0000
@@ -361,9 +361,9 @@
 STR_SORT_BY                                                     :{BLACK}排序
 
 STR_SORT_BY_POPULATION                                          :{BLACK}人口
-STR_SORT_BY_PRODUCTION                                          :{BLACK}产出
-STR_SORT_BY_TYPE                                                :{BLACK}类型
-STR_SORT_BY_TRANSPORTED                                         :{BLACK}已运输
+STR_SORT_BY_PRODUCTION                                          :产出
+STR_SORT_BY_TYPE                                                :类型
+STR_SORT_BY_TRANSPORTED                                         :已运输
 STR_SORT_BY_NAME                                                :{BLACK}姓名
 STR_SORT_BY_DROPDOWN_NAME                                       :姓名
 STR_SORT_BY_DATE                                                :{BLACK}日期
--- a/src/lang/slovak.txt	Thu May 29 12:52:24 2008 +0000
+++ b/src/lang/slovak.txt	Thu May 29 15:56:32 2008 +0000
@@ -427,9 +427,9 @@
 STR_SORT_BY                                                     :{BLACK}Usporiadat
 
 STR_SORT_BY_POPULATION                                          :{BLACK}Populacia
-STR_SORT_BY_PRODUCTION                                          :{BLACK}Produkcia
-STR_SORT_BY_TYPE                                                :{BLACK}Typ
-STR_SORT_BY_TRANSPORTED                                         :{BLACK}Prepravene
+STR_SORT_BY_PRODUCTION                                          :Produkcia
+STR_SORT_BY_TYPE                                                :Typ
+STR_SORT_BY_TRANSPORTED                                         :Prepravene
 STR_SORT_BY_NAME                                                :{BLACK}Nazov
 STR_SORT_BY_DROPDOWN_NAME                                       :Nazov
 STR_SORT_BY_DATE                                                :{BLACK}Datum
--- a/src/lang/slovenian.txt	Thu May 29 12:52:24 2008 +0000
+++ b/src/lang/slovenian.txt	Thu May 29 15:56:32 2008 +0000
@@ -405,9 +405,9 @@
 STR_SORT_BY                                                     :{BLACK}Sortiraj po
 
 STR_SORT_BY_POPULATION                                          :{BLACK}Prebivalstvo
-STR_SORT_BY_PRODUCTION                                          :{BLACK}Proizvodnja
-STR_SORT_BY_TYPE                                                :{BLACK}Tip
-STR_SORT_BY_TRANSPORTED                                         :{BLACK}Prepeljano
+STR_SORT_BY_PRODUCTION                                          :Proizvodnja
+STR_SORT_BY_TYPE                                                :Tip
+STR_SORT_BY_TRANSPORTED                                         :Prepeljano
 STR_SORT_BY_NAME                                                :{BLACK}Ime
 STR_SORT_BY_DROPDOWN_NAME                                       :Ime
 STR_SORT_BY_DATE                                                :{BLACK}Datum
--- a/src/lang/spanish.txt	Thu May 29 12:52:24 2008 +0000
+++ b/src/lang/spanish.txt	Thu May 29 15:56:32 2008 +0000
@@ -364,9 +364,9 @@
 STR_SORT_BY                                                     :{BLACK}Ordenar por
 
 STR_SORT_BY_POPULATION                                          :{BLACK}Población
-STR_SORT_BY_PRODUCTION                                          :{BLACK}Producción
-STR_SORT_BY_TYPE                                                :{BLACK}Tipo
-STR_SORT_BY_TRANSPORTED                                         :{BLACK}Transportado
+STR_SORT_BY_PRODUCTION                                          :Producción
+STR_SORT_BY_TYPE                                                :Tipo
+STR_SORT_BY_TRANSPORTED                                         :Transportado
 STR_SORT_BY_NAME                                                :{BLACK}Nombre
 STR_SORT_BY_DROPDOWN_NAME                                       :Nombre
 STR_SORT_BY_DATE                                                :{BLACK}Fecha
--- a/src/lang/swedish.txt	Thu May 29 12:52:24 2008 +0000
+++ b/src/lang/swedish.txt	Thu May 29 15:56:32 2008 +0000
@@ -363,9 +363,9 @@
 STR_SORT_BY                                                     :{BLACK}Sortera efter
 
 STR_SORT_BY_POPULATION                                          :{BLACK}Befolkning
-STR_SORT_BY_PRODUCTION                                          :{BLACK}Produktion
-STR_SORT_BY_TYPE                                                :{BLACK}Typ
-STR_SORT_BY_TRANSPORTED                                         :{BLACK}Transporterat
+STR_SORT_BY_PRODUCTION                                          :Produktion
+STR_SORT_BY_TYPE                                                :Typ
+STR_SORT_BY_TRANSPORTED                                         :Transporterat
 STR_SORT_BY_NAME                                                :{BLACK}Namn
 STR_SORT_BY_DROPDOWN_NAME                                       :Namn
 STR_SORT_BY_DATE                                                :{BLACK}Datum
--- a/src/lang/traditional_chinese.txt	Thu May 29 12:52:24 2008 +0000
+++ b/src/lang/traditional_chinese.txt	Thu May 29 15:56:32 2008 +0000
@@ -361,9 +361,9 @@
 STR_SORT_BY                                                     :{BLACK}排序依照
 
 STR_SORT_BY_POPULATION                                          :{BLACK}人口
-STR_SORT_BY_PRODUCTION                                          :{BLACK}產量
-STR_SORT_BY_TYPE                                                :{BLACK}種類
-STR_SORT_BY_TRANSPORTED                                         :{BLACK}輸出量
+STR_SORT_BY_PRODUCTION                                          :產量
+STR_SORT_BY_TYPE                                                :種類
+STR_SORT_BY_TRANSPORTED                                         :輸出量
 STR_SORT_BY_NAME                                                :{BLACK}名稱
 STR_SORT_BY_DROPDOWN_NAME                                       :名稱
 STR_SORT_BY_DATE                                                :{BLACK}日期
--- a/src/lang/turkish.txt	Thu May 29 12:52:24 2008 +0000
+++ b/src/lang/turkish.txt	Thu May 29 15:56:32 2008 +0000
@@ -361,9 +361,9 @@
 STR_SORT_BY                                                     :{BLACK}Sırala
 
 STR_SORT_BY_POPULATION                                          :{BLACK}Nüfus
-STR_SORT_BY_PRODUCTION                                          :{BLACK}Üretim
-STR_SORT_BY_TYPE                                                :{BLACK}Tür
-STR_SORT_BY_TRANSPORTED                                         :{BLACK}Taşınan
+STR_SORT_BY_PRODUCTION                                          :Üretim
+STR_SORT_BY_TYPE                                                :Tür
+STR_SORT_BY_TRANSPORTED                                         :Taşınan
 STR_SORT_BY_NAME                                                :{BLACK}İsim
 STR_SORT_BY_DROPDOWN_NAME                                       :İsim
 STR_SORT_BY_DATE                                                :{BLACK}Tarih
--- a/src/lang/ukrainian.txt	Thu May 29 12:52:24 2008 +0000
+++ b/src/lang/ukrainian.txt	Thu May 29 15:56:32 2008 +0000
@@ -488,9 +488,9 @@
 STR_SORT_BY                                                     :{BLACK}Сортувати
 
 STR_SORT_BY_POPULATION                                          :{BLACK}за населенням
-STR_SORT_BY_PRODUCTION                                          :{BLACK}за продуктивністю
-STR_SORT_BY_TYPE                                                :{BLACK}за типом
-STR_SORT_BY_TRANSPORTED                                         :{BLACK}за перевезенням
+STR_SORT_BY_PRODUCTION                                          :за продуктивністю
+STR_SORT_BY_TYPE                                                :за типом
+STR_SORT_BY_TRANSPORTED                                         :за перевезенням
 STR_SORT_BY_NAME                                                :{BLACK}за назвою
 STR_SORT_BY_DROPDOWN_NAME                                       :Назва
 STR_SORT_BY_DATE                                                :{BLACK}за датою
--- a/src/lang/unfinished/greek.txt	Thu May 29 12:52:24 2008 +0000
+++ b/src/lang/unfinished/greek.txt	Thu May 29 15:56:32 2008 +0000
@@ -360,9 +360,9 @@
 STR_SORT_BY                                                     :{BLACK}Ταξινόμηση κατά
 
 STR_SORT_BY_POPULATION                                          :{BLACK}Πληθυσμός
-STR_SORT_BY_PRODUCTION                                          :{BLACK}Παραγωγή
-STR_SORT_BY_TYPE                                                :{BLACK}Τύπος
-STR_SORT_BY_TRANSPORTED                                         :{BLACK}Μεταφέρθηκαν
+STR_SORT_BY_PRODUCTION                                          :Παραγωγή
+STR_SORT_BY_TYPE                                                :Τύπος
+STR_SORT_BY_TRANSPORTED                                         :Μεταφέρθηκαν
 STR_SORT_BY_NAME                                                :{BLACK}Όνομα
 STR_SORT_BY_DROPDOWN_NAME                                       :Όνομα
 STR_SORT_BY_DATE                                                :{BLACK}Μέρα
--- a/src/lang/unfinished/latvian.txt	Thu May 29 12:52:24 2008 +0000
+++ b/src/lang/unfinished/latvian.txt	Thu May 29 15:56:32 2008 +0000
@@ -359,9 +359,9 @@
 STR_SORT_BY                                                     :{BLACK}Saka'rtot pe'c
 
 STR_SORT_BY_POPULATION                                          :{BLACK}Iedzi'vota'ju skaita
-STR_SORT_BY_PRODUCTION                                          :{BLACK}Produkcijas
-STR_SORT_BY_TYPE                                                :{BLACK}Tipa
-STR_SORT_BY_TRANSPORTED                                         :{BLACK}Transporte'ta'
+STR_SORT_BY_PRODUCTION                                          :Produkcijas
+STR_SORT_BY_TYPE                                                :Tipa
+STR_SORT_BY_TRANSPORTED                                         :Transporte'ta'
 STR_SORT_BY_NAME                                                :{BLACK}Va'rda
 STR_SORT_BY_DROPDOWN_NAME                                       :Va'rds
 STR_SORT_BY_DATE                                                :{BLACK}Datums
--- a/src/main_gui.cpp	Thu May 29 12:52:24 2008 +0000
+++ b/src/main_gui.cpp	Thu May 29 15:56:32 2008 +0000
@@ -49,7 +49,7 @@
 void CcGiveMoney(bool success, TileIndex tile, uint32 p1, uint32 p2)
 {
 #ifdef ENABLE_NETWORK
-	if (!success || !_settings.economy.give_money) return;
+	if (!success || !_settings_game.economy.give_money) return;
 
 	char msg[20];
 	/* Inform the player of this action */
@@ -345,7 +345,7 @@
 					if (cio == NULL) break;
 
 					/* Only players actually playing can speak to team. Eg spectators cannot */
-					if (_settings.gui.prefer_teamchat && IsValidPlayer(cio->client_playas)) {
+					if (_settings_client.gui.prefer_teamchat && IsValidPlayer(cio->client_playas)) {
 						const NetworkClientInfo *ci;
 						FOR_ALL_ACTIVE_CLIENT_INFOS(ci) {
 							if (ci->client_playas == cio->client_playas && ci != cio) {
--- a/src/minilzo.cpp	Thu May 29 12:52:24 2008 +0000
+++ b/src/minilzo.cpp	Thu May 29 15:56:32 2008 +0000
@@ -1183,7 +1183,7 @@
 			break;
 	}
 
-	*out_len = op - out;
+	*out_len = (lzo_uint)(op - out);
 	return pd(in_end,ii);
 }
 
@@ -1233,7 +1233,7 @@
 	*op++ = 0;
 	*op++ = 0;
 
-	*out_len = op - out;
+	*out_len = (lzo_uint)(op - out);
 	return LZO_E_OK;
 }
 
@@ -1555,7 +1555,7 @@
 
 eof_found:
 	assert(t == 1);
-	*out_len = op - out;
+	*out_len = (lzo_uint)(op - out);
 	return (ip == ip_end ? LZO_E_OK :
 		   (ip < ip_end  ? LZO_E_INPUT_NOT_CONSUMED : LZO_E_INPUT_OVERRUN));
 
--- a/src/misc.cpp	Thu May 29 12:52:24 2008 +0000
+++ b/src/misc.cpp	Thu May 29 15:56:32 2008 +0000
@@ -56,7 +56,7 @@
 void InitializeNPF();
 void InitializeOldNames();
 
-void InitializeGame(int mode, uint size_x, uint size_y)
+void InitializeGame(uint size_x, uint size_y, bool reset_date)
 {
 	AllocateMap(size_x, size_y);
 
@@ -68,10 +68,10 @@
 	_realtime_tick = 0;
 	_date_fract = 0;
 	_cur_tileloop_tile = 0;
-	_settings = _settings_newgame;
+	_settings_game = _settings_newgame;
 
-	if ((mode & IG_DATE_RESET) == IG_DATE_RESET) {
-		SetDate(ConvertYMDToDate(_settings.game_creation.starting_year, 0, 1));
+	if (reset_date) {
+		SetDate(ConvertYMDToDate(_settings_game.game_creation.starting_year, 0, 1));
 		InitializeOldNames();
 	}
 
--- a/src/misc_cmd.cpp	Thu May 29 12:52:24 2008 +0000
+++ b/src/misc_cmd.cpp	Thu May 29 15:56:32 2008 +0000
@@ -369,7 +369,7 @@
  */
 CommandCost CmdGiveMoney(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
 {
-	if (!_settings.economy.give_money) return CMD_ERROR;
+	if (!_settings_game.economy.give_money) return CMD_ERROR;
 
 	const Player *p = GetPlayer(_current_player);
 	CommandCost amount(EXPENSES_OTHER, min((Money)p1, (Money)20000000LL));
--- a/src/misc_gui.cpp	Thu May 29 12:52:24 2008 +0000
+++ b/src/misc_gui.cpp	Thu May 29 15:56:32 2008 +0000
@@ -102,7 +102,7 @@
 
 	LandInfoWindow(TileIndex tile) : Window(&_land_info_desc) {
 		Player *p = GetPlayer(IsValidPlayer(_local_player) ? _local_player : PLAYER_FIRST);
-		Town *t = ClosestTownFromTile(tile, _settings.economy.dist_local_authority);
+		Town *t = ClosestTownFromTile(tile, _settings_game.economy.dist_local_authority);
 
 		Money old_money = p->player_money;
 		p->player_money = INT64_MAX;
@@ -396,7 +396,7 @@
 			Window(pt.x, pt.y, width, height, WC_ERRMSG, widget),
 			show_player_face(show_player_face)
 	{
-		this->duration = _settings.gui.errmsg_duration;
+		this->duration = _settings_client.gui.errmsg_duration;
 		CopyOutDParam(this->decode_params, 0, lengthof(this->decode_params));
 		this->message_1 = msg1;
 		this->message_2 = msg2;
@@ -465,7 +465,7 @@
 {
 	DeleteWindowById(WC_ERRMSG, 0);
 
-	if (!_settings.gui.errmsg_duration) return;
+	if (!_settings_client.gui.errmsg_duration) return;
 
 	if (msg_2 == STR_NULL) msg_2 = STR_EMPTY;
 
@@ -620,7 +620,7 @@
 	DeleteWindowById(WC_TOOLTIPS, 0);
 
 	/* We only show measurement tooltips with patch setting on */
-	if (str == STR_NULL || (paramcount != 0 && !_settings.gui.measure_tooltip)) return;
+	if (str == STR_NULL || (paramcount != 0 && !_settings_client.gui.measure_tooltip)) return;
 
 	for (uint i = 0; i != paramcount; i++) SetDParam(i, params[i]);
 	char buffer[512];
@@ -717,30 +717,6 @@
 	}
 }
 
-void SetVScrollCount(Window *w, int num)
-{
-	w->vscroll.count = num;
-	num -= w->vscroll.cap;
-	if (num < 0) num = 0;
-	if (num < w->vscroll.pos) w->vscroll.pos = num;
-}
-
-void SetVScroll2Count(Window *w, int num)
-{
-	w->vscroll2.count = num;
-	num -= w->vscroll2.cap;
-	if (num < 0) num = 0;
-	if (num < w->vscroll2.pos) w->vscroll2.pos = num;
-}
-
-void SetHScrollCount(Window *w, int num)
-{
-	w->hscroll.count = num;
-	num -= w->hscroll.cap;
-	if (num < 0) num = 0;
-	if (num < w->hscroll.pos) w->hscroll.pos = num;
-}
-
 /* Delete a character at the caret position in a text buf.
  * If backspace is set, delete the character before the caret,
  * else delete the character after it. */
@@ -751,7 +727,7 @@
 
 	if (backspace) s = Utf8PrevChar(s);
 
-	size_t len = Utf8Decode(&c, s);
+	uint16 len = (uint16)Utf8Decode(&c, s);
 	uint width = GetCharacterWidth(FS_NORMAL, c);
 
 	tb->width  -= width;
@@ -807,7 +783,7 @@
 bool InsertTextBufferChar(Textbuf *tb, WChar key)
 {
 	const byte charwidth = GetCharacterWidth(FS_NORMAL, key);
-	size_t len = Utf8CharLen(key);
+	uint16 len = (uint16)Utf8CharLen(key);
 	if (tb->length < (tb->maxlength - len) && (tb->maxwidth == 0 || tb->width + charwidth <= tb->maxwidth)) {
 		memmove(tb->buf + tb->caretpos + len, tb->buf + tb->caretpos, tb->length - tb->caretpos + 1);
 		Utf8Encode(tb->buf + tb->caretpos, key);
@@ -847,7 +823,7 @@
 			if (tb->caretpos < tb->length) {
 				WChar c;
 
-				tb->caretpos   += Utf8Decode(&c, tb->buf + tb->caretpos);
+				tb->caretpos   += (uint16)Utf8Decode(&c, tb->buf + tb->caretpos);
 				tb->caretxoffs += GetCharacterWidth(FS_NORMAL, c);
 
 				return true;
@@ -1083,6 +1059,11 @@
 	{
 		EventState state;
 		switch (this->HandleEditBoxKey(QUERY_STR_WIDGET_TEXT, key, keycode, state)) {
+			default: NOT_REACHED();
+			case 0: {
+				Window *osk = FindWindowById(WC_OSK, 0);
+				if (osk != NULL && osk->parent == this) osk->OnInvalidateData();
+			} break;
 			case 1: this->OnOk(); // Enter pressed, confirms change
 			/* FALL THROUGH */
 			case 2: delete this; break; // ESC pressed, closes window, abandons changes
@@ -1093,8 +1074,9 @@
 	~QueryStringWindow()
 	{
 		if (!this->handled && this->parent != NULL) {
-			this->handled = true;
-			this->parent->OnQueryTextFinished(NULL);
+			Window *parent = this->parent;
+			this->parent = NULL; // so parent doesn't try to delete us again
+			parent->OnQueryTextFinished(NULL);
 		}
 		ClrBit(_no_scroll, SCROLL_EDIT);
 	}
@@ -1207,6 +1189,8 @@
 				 * DeleteNonVitalWindows() to be called - we shouldn't be in a window then */
 				QueryCallbackProc *proc = this->proc;
 				Window *parent = this->parent;
+				/* Prevent the destructor calling the callback function */
+				this->proc = NULL;
 				delete this;
 				if (proc != NULL) {
 					proc(parent, true);
--- a/src/mixer.cpp	Thu May 29 12:52:24 2008 +0000
+++ b/src/mixer.cpp	Thu May 29 15:56:32 2008 +0000
@@ -104,7 +104,7 @@
 	return NULL;
 }
 
-void MxSetChannelRawSrc(MixerChannel *mc, int8 *mem, uint size, uint rate, uint flags)
+void MxSetChannelRawSrc(MixerChannel *mc, int8 *mem, size_t size, uint rate, uint flags)
 {
 	mc->memory = mem;
 	mc->flags = flags;
@@ -114,12 +114,12 @@
 	mc->frac_speed = (rate << 16) / _play_rate;
 
 	/* adjust the magnitude to prevent overflow */
-	while (size & 0xFFFF0000) {
+	while (size & ~0xFFFF) {
 		size >>= 1;
 		rate = (rate >> 1) + 1;
 	}
 
-	mc->samples_left = size * _play_rate / rate;
+	mc->samples_left = (uint)size * _play_rate / rate;
 }
 
 void MxSetChannelVolume(MixerChannel *mc, uint left, uint right)
--- a/src/mixer.h	Thu May 29 12:52:24 2008 +0000
+++ b/src/mixer.h	Thu May 29 15:56:32 2008 +0000
@@ -18,7 +18,7 @@
 void MxMixSamples(void *buffer, uint samples);
 
 MixerChannel *MxAllocateChannel();
-void MxSetChannelRawSrc(MixerChannel *mc, int8 *mem, uint size, uint rate, uint flags);
+void MxSetChannelRawSrc(MixerChannel *mc, int8 *mem, size_t size, uint rate, uint flags);
 void MxSetChannelVolume(MixerChannel *mc, uint left, uint right);
 void MxActivateChannel(MixerChannel*);
 
--- a/src/network/network.cpp	Thu May 29 12:52:24 2008 +0000
+++ b/src/network/network.cpp	Thu May 29 15:56:32 2008 +0000
@@ -1009,10 +1009,10 @@
 	_network_game_info.spectators_on = 0;
 
 	_network_game_info.game_date = _date;
-	_network_game_info.start_date = ConvertYMDToDate(_settings.game_creation.starting_year, 0, 1);
+	_network_game_info.start_date = ConvertYMDToDate(_settings_game.game_creation.starting_year, 0, 1);
 	_network_game_info.map_width = MapSizeX();
 	_network_game_info.map_height = MapSizeY();
-	_network_game_info.map_set = _settings.game_creation.landscape;
+	_network_game_info.map_set = _settings_game.game_creation.landscape;
 
 	_network_game_info.use_password = (_network_server_password[0] != '\0');
 
--- a/src/network/network_client.cpp	Thu May 29 12:52:24 2008 +0000
+++ b/src/network/network_client.cpp	Thu May 29 15:56:32 2008 +0000
@@ -83,7 +83,7 @@
 {
 	if (StrEmpty(_network_player_info[_local_player].password)) return;
 
-	_password_game_seed = _settings.game_creation.generation_seed;
+	_password_game_seed = _settings_game.game_creation.generation_seed;
 	ttd_strlcpy(_password_server_unique_id, _network_unique_id, sizeof(_password_server_unique_id));
 
 	const char *new_pw = GenerateCompanyPasswordHash(_network_player_info[_local_player].password);
--- a/src/network/network_gui.cpp	Thu May 29 12:52:24 2008 +0000
+++ b/src/network/network_gui.cpp	Thu May 29 15:56:32 2008 +0000
@@ -190,7 +190,6 @@
 		this->field = NGWW_PLAYER;
 		this->server = NULL;
 
-		this->servers.sort_list = NULL;
 		this->servers.flags = VL_REBUILD | (_ng_sorting.order ? VL_DESC : VL_NONE);
 		this->servers.sort_type = _ng_sorting.criteria;
 
@@ -199,7 +198,6 @@
 
 	~NetworkGameWindow()
 	{
-		free(this->servers.sort_list);
 	}
 
 	/**
@@ -208,23 +206,17 @@
 	 */
 	void BuildNetworkGameList()
 	{
-		NetworkGameList *ngl_temp;
-		uint n = 0;
-
 		if (!(this->servers.flags & VL_REBUILD)) return;
 
-		/* Count the number of games in the list */
-		for (ngl_temp = _network_game_list; ngl_temp != NULL; ngl_temp = ngl_temp->next) n++;
-		if (n == 0) return;
-
 		/* Create temporary array of games to use for listing */
-		this->servers.sort_list = ReallocT(this->servers.sort_list, n);
-		this->servers.list_length = n;
+		this->servers.Clear();
 
-		for (n = 0, ngl_temp = _network_game_list; ngl_temp != NULL; ngl_temp = ngl_temp->next) {
-			this->servers.sort_list[n++] = ngl_temp;
+		for (NetworkGameList *ngl = _network_game_list; ngl != NULL; ngl = ngl->next) {
+			*this->servers.Append() = ngl;
 		}
 
+		this->servers.Compact();
+
 		/* Force resort */
 		this->servers.flags &= ~VL_REBUILD;
 		this->servers.flags |= VL_RESORT;
@@ -242,17 +234,17 @@
 		uint i;
 
 		if (!(this->servers.flags & VL_RESORT)) return;
-		if (this->servers.list_length == 0) return;
+		if (this->servers.Length() == 0) return;
 
 		_internal_sort_order = !!(this->servers.flags & VL_DESC);
-		qsort(this->servers.sort_list, this->servers.list_length, sizeof(this->servers.sort_list[0]), ngame_sorter[this->servers.sort_type]);
+		qsort(this->servers.Begin(), this->servers.Length(), sizeof(*this->servers.Begin()), ngame_sorter[this->servers.sort_type]);
 
 		/* After sorting ngl->sort_list contains the sorted items. Put these back
 		 * into the original list. Basically nothing has changed, we are only
 		 * shuffling the ->next pointers */
-		_network_game_list = this->servers.sort_list[0];
-		for (item = _network_game_list, i = 1; i != this->servers.list_length; i++) {
-			item->next = this->servers.sort_list[i];
+		_network_game_list = this->servers[0];
+		for (item = _network_game_list, i = 1; i != this->servers.Length(); i++) {
+			item->next = this->servers[i];
 			item = item->next;
 		}
 		item->next = NULL;
@@ -300,7 +292,7 @@
 
 		if (this->servers.flags & VL_REBUILD) {
 			this->BuildNetworkGameList();
-			SetVScrollCount(this, this->servers.list_length);
+			SetVScrollCount(this, this->servers.Length());
 		}
 		if (this->servers.flags & VL_RESORT) this->SortNetworkGameList();
 
@@ -582,7 +574,7 @@
 
 		this->widget[NGWW_MATRIX].data = (this->vscroll.cap << 8) + 1;
 
-		SetVScrollCount(this, this->servers.list_length);
+		SetVScrollCount(this, this->servers.Length());
 
 		int widget_width = this->widget[NGWW_FIND].right - this->widget[NGWW_FIND].left;
 		int space = (this->width - 4 * widget_width - 25) / 3;
@@ -1342,7 +1334,7 @@
 
 		if (_network_own_client_index != ci->client_index) {
 			/* We are no spectator and the player we want to give money to is no spectator and money gifts are allowed */
-			if (IsValidPlayer(_network_playas) && IsValidPlayer(ci->client_playas) && _settings.economy.give_money) {
+			if (IsValidPlayer(_network_playas) && IsValidPlayer(ci->client_playas) && _settings_game.economy.give_money) {
 				GetString(this->action[i], STR_NETWORK_CLIENTLIST_GIVE_MONEY, lastof(this->action[i]));
 				this->proc[i++] = &ClientList_GiveMoney;
 			}
--- a/src/network/network_server.cpp	Thu May 29 12:52:24 2008 +0000
+++ b/src/network/network_server.cpp	Thu May 29 15:56:32 2008 +0000
@@ -229,7 +229,7 @@
 
 	Packet *p = NetworkSend_Init(PACKET_SERVER_NEED_PASSWORD);
 	p->Send_uint8(type);
-	p->Send_uint32(_settings.game_creation.generation_seed);
+	p->Send_uint32(_settings_game.game_creation.generation_seed);
 	p->Send_string(_network_unique_id);
 	cs->Send_Packet(p);
 }
@@ -254,7 +254,7 @@
 
 	p = NetworkSend_Init(PACKET_SERVER_WELCOME);
 	p->Send_uint16(cs->index);
-	p->Send_uint32(_settings.game_creation.generation_seed);
+	p->Send_uint32(_settings_game.game_creation.generation_seed);
 	p->Send_string(_network_unique_id);
 	cs->Send_Packet(p);
 
--- a/src/network/network_udp.cpp	Thu May 29 12:52:24 2008 +0000
+++ b/src/network/network_udp.cpp	Thu May 29 15:56:32 2008 +0000
@@ -77,7 +77,7 @@
 	_network_game_info.game_date     = _date;
 	_network_game_info.map_width     = MapSizeX();
 	_network_game_info.map_height    = MapSizeY();
-	_network_game_info.map_set       = _settings.game_creation.landscape;
+	_network_game_info.map_set       = _settings_game.game_creation.landscape;
 	_network_game_info.companies_on  = ActivePlayerCount();
 	_network_game_info.spectators_on = NetworkSpectatorCount();
 	_network_game_info.grfconfig     = _grfconfig;
--- a/src/newgrf.cpp	Thu May 29 12:52:24 2008 +0000
+++ b/src/newgrf.cpp	Thu May 29 15:56:32 2008 +0000
@@ -326,7 +326,7 @@
 	/* Hack for add-on GRFs that need to modify another GRF's engines. This lets
 	 * them use the same engine slots. */
 	const GRFFile *grf_match = NULL;
-	if (_settings.vehicle.dynamic_engines) {
+	if (_settings_game.vehicle.dynamic_engines) {
 		uint32 override = _grf_id_overrides[file->grfid];
 		if (override != 0) {
 			grf_match = GetFileByGRFID(override);
@@ -341,7 +341,7 @@
 	/* Check if this vehicle is already defined... */
 	Engine *e = NULL;
 	FOR_ALL_ENGINES(e) {
-		if (_settings.vehicle.dynamic_engines && e->grffile != NULL && e->grffile != file && e->grffile != grf_match) continue;
+		if (_settings_game.vehicle.dynamic_engines && e->grffile != NULL && e->grffile != file && e->grffile != grf_match) continue;
 		if (e->type != type) continue;
 		if (e->internal_id != internal_id) continue;
 
@@ -377,14 +377,14 @@
 	extern uint32 GetNewGRFOverride(uint32 grfid);
 
 	const GRFFile *grf_match = NULL;
-	if (_settings.vehicle.dynamic_engines) {
+	if (_settings_game.vehicle.dynamic_engines) {
 		uint32 override = _grf_id_overrides[file->grfid];
 		if (override != 0) grf_match = GetFileByGRFID(override);
 	}
 
 	const Engine *e = NULL;
 	FOR_ALL_ENGINES(e) {
-		if (_settings.vehicle.dynamic_engines && e->grffile != file && (grf_match == NULL || e->grffile != grf_match)) continue;
+		if (_settings_game.vehicle.dynamic_engines && e->grffile != file && (grf_match == NULL || e->grffile != grf_match)) continue;
 		if (e->type != type) continue;
 		if (e->internal_id != internal_id) continue;
 
@@ -1437,8 +1437,8 @@
 
 				/* If value of goods is negative, it means in fact food or, if in toyland, fizzy_drink acceptance.
 				 * Else, we have "standard" 3rd cargo type, goods or candy, for toyland once more */
-				CargoID cid = (goods >= 0) ? ((_settings.game_creation.landscape == LT_TOYLAND) ? CT_CANDY : CT_GOODS) :
-						((_settings.game_creation.landscape == LT_TOYLAND) ? CT_FIZZY_DRINKS : CT_FOOD);
+				CargoID cid = (goods >= 0) ? ((_settings_game.game_creation.landscape == LT_TOYLAND) ? CT_CANDY : CT_GOODS) :
+						((_settings_game.game_creation.landscape == LT_TOYLAND) ? CT_FIZZY_DRINKS : CT_FOOD);
 
 				/* Make sure the cargo type is valid in this climate. */
 				if (!GetCargo(cid)->IsValid()) goods = 0;
@@ -2167,11 +2167,11 @@
 				break;
 
 			case 0x17: // Probability in random game
-				indsp->appear_creation[_settings.game_creation.landscape] = grf_load_byte(&buf);
+				indsp->appear_creation[_settings_game.game_creation.landscape] = grf_load_byte(&buf);
 				break;
 
 			case 0x18: // Probability during gameplay
-				indsp->appear_ingame[_settings.game_creation.landscape] = grf_load_byte(&buf);
+				indsp->appear_ingame[_settings_game.game_creation.landscape] = grf_load_byte(&buf);
 				break;
 
 			case 0x19: // Map color
@@ -3557,11 +3557,11 @@
 			return true;
 
 		case 0x03: // current climate, 0=temp, 1=arctic, 2=trop, 3=toyland
-			*value = _settings.game_creation.landscape;
+			*value = _settings_game.game_creation.landscape;
 			return true;
 
 		case 0x06: // road traffic side, bit 4 clear=left, set=right
-			*value = _settings.vehicle.road_side << 4;
+			*value = _settings_game.vehicle.road_side << 4;
 			return true;
 
 		case 0x09: // date fraction
@@ -3592,7 +3592,7 @@
 		case 0x0F: // Rail track type cost factors
 			*value = 0;
 			SB(*value, 0, 8, _railtype_cost_multiplier[0]); // normal rail
-			if (_settings.vehicle.disable_elrails) {
+			if (_settings_game.vehicle.disable_elrails) {
 				/* skip elrail multiplier - disabled */
 				SB(*value, 8, 8, _railtype_cost_multiplier[2]); // monorail
 			} else {
@@ -3635,7 +3635,7 @@
 		/* case 0x1F: // locale dependent settings not implemented */
 
 		case 0x20: // snow line height
-			*value = _settings.game_creation.landscape == LT_ARCTIC ? GetSnowLine() : 0xFF;
+			*value = _settings_game.game_creation.landscape == LT_ARCTIC ? GetSnowLine() : 0xFF;
 			return true;
 
 		case 0x21: // OpenTTD version
@@ -3643,7 +3643,7 @@
 			return true;
 
 		case 0x22: // difficulty level
-			*value = _settings.difficulty.diff_level;
+			*value = _settings_game.difficulty.diff_level;
 			return true;
 
 		default: return false;
@@ -3707,7 +3707,7 @@
 	 *                 to place where parameter is to be stored. */
 
 	/* Preload the next sprite */
-	uint32 pos = FioGetPos();
+	size_t pos = FioGetPos();
 	uint16 num = FioReadWord();
 	uint8 type = FioReadByte();
 
@@ -4188,10 +4188,10 @@
 {
 	switch (param) {
 		/* start year - 1920 */
-		case 0x0B: return max(_settings.game_creation.starting_year, ORIGINAL_BASE_YEAR) - ORIGINAL_BASE_YEAR;
+		case 0x0B: return max(_settings_game.game_creation.starting_year, ORIGINAL_BASE_YEAR) - ORIGINAL_BASE_YEAR;
 
 		/* freight trains weight factor */
-		case 0x0E: return _settings.vehicle.freight_trains;
+		case 0x0E: return _settings_game.vehicle.freight_trains;
 
 		/* empty wagon speed increase */
 		case 0x0F: return 0;
@@ -4200,7 +4200,7 @@
 		 * the following is good for 1x, 2x and 4x (most common?) and...
 		 * well not really for 3x. */
 		case 0x10:
-			switch (_settings.vehicle.plane_speed) {
+			switch (_settings_game.vehicle.plane_speed) {
 				default:
 				case 4: return 1;
 				case 3: return 2;
@@ -4382,7 +4382,7 @@
 						case 0x01: // Road Vehicles
 						case 0x02: // Ships
 						case 0x03: // Aircraft
-							if (!_settings.vehicle.dynamic_engines) {
+							if (!_settings_game.vehicle.dynamic_engines) {
 								src1 = PerformGRM(&_grm_engines[_engine_offsets[feature]], _engine_counts[feature], count, op, target, "vehicles");
 								if (_skip_sprites == -1) return;
 							} else {
@@ -4544,7 +4544,7 @@
 
 		case 0x8F: // Rail track type cost factors
 			_railtype_cost_multiplier[0] = GB(res, 0, 8);
-			if (_settings.vehicle.disable_elrails) {
+			if (_settings_game.vehicle.disable_elrails) {
 				_railtype_cost_multiplier[1] = GB(res, 0, 8);
 				_railtype_cost_multiplier[2] = GB(res, 8, 8);
 			} else {
@@ -5079,23 +5079,23 @@
 
 static void InitializeGRFSpecial()
 {
-	_ttdpatch_flags[0] =  ((_settings.station.always_small_airport ? 1 : 0) << 0x0C)  // keepsmallairport
+	_ttdpatch_flags[0] =  ((_settings_game.station.always_small_airport ? 1 : 0) << 0x0C)  // keepsmallairport
 	                   |                                                 (1 << 0x0D)  // newairports
 	                   |                                                 (1 << 0x0E)  // largestations
-	                   |      ((_settings.construction.longbridges ? 1 : 0) << 0x0F)  // longbridges
+	                   |      ((_settings_game.construction.longbridges ? 1 : 0) << 0x0F)  // longbridges
 	                   |                                                 (0 << 0x10)  // loadtime
 	                   |                                                 (1 << 0x12)  // presignals
 	                   |                                                 (1 << 0x13)  // extpresignals
-	                   | ((_settings.vehicle.never_expire_vehicles ? 1 : 0) << 0x16)  // enginespersist
+	                   | ((_settings_game.vehicle.never_expire_vehicles ? 1 : 0) << 0x16)  // enginespersist
 	                   |                                                 (1 << 0x1B)  // multihead
 	                   |                                                 (1 << 0x1D)  // lowmemory
 	                   |                                                 (1 << 0x1E); // generalfixes
 
-	_ttdpatch_flags[1] =   ((_settings.economy.station_noise_level ? 1 : 0) << 0x07)  // moreairports - based on units of noise
-	                   |        ((_settings.vehicle.mammoth_trains ? 1 : 0) << 0x08)  // mammothtrains
+	_ttdpatch_flags[1] =   ((_settings_game.economy.station_noise_level ? 1 : 0) << 0x07)  // moreairports - based on units of noise
+	                   |        ((_settings_game.vehicle.mammoth_trains ? 1 : 0) << 0x08)  // mammothtrains
 	                   |                                                 (1 << 0x09)  // trainrefit
 	                   |                                                 (0 << 0x0B)  // subsidiaries
-	                   |         ((_settings.order.gradual_loading ? 1 : 0) << 0x0C)  // gradualloading
+	                   |         ((_settings_game.order.gradual_loading ? 1 : 0) << 0x0C)  // gradualloading
 	                   |                                                 (1 << 0x12)  // unifiedmaglevmode - set bit 0 mode. Not revelant to OTTD
 	                   |                                                 (1 << 0x13)  // unifiedmaglevmode - set bit 1 mode
 	                   |                                                 (1 << 0x14)  // bridgespeedlimits
@@ -5104,14 +5104,14 @@
 	                   |                                                 (1 << 0x18)  // newrvs
 	                   |                                                 (1 << 0x19)  // newships
 	                   |                                                 (1 << 0x1A)  // newplanes
-	                   |      ((_settings.construction.signal_side ? 1 : 0) << 0x1B)  // signalsontrafficside
-	                   |       ((_settings.vehicle.disable_elrails ? 0 : 1) << 0x1C); // electrifiedrailway
+	                   |      ((_settings_game.construction.signal_side ? 1 : 0) << 0x1B)  // signalsontrafficside
+	                   |       ((_settings_game.vehicle.disable_elrails ? 0 : 1) << 0x1C); // electrifiedrailway
 
 	_ttdpatch_flags[2] =                                                 (1 << 0x01)  // loadallgraphics - obsolote
 	                   |                                                 (1 << 0x03)  // semaphores
 	                   |                                                 (0 << 0x0B)  // enhancedgui
 	                   |                                                 (0 << 0x0C)  // newagerating
-	                   |  ((_settings.construction.build_on_slopes ? 1 : 0) << 0x0D)  // buildonslopes
+	                   |  ((_settings_game.construction.build_on_slopes ? 1 : 0) << 0x0D)  // buildonslopes
 	                   |                                                 (1 << 0x0E)  // fullloadany
 	                   |                                                 (1 << 0x0F)  // planespeed
 	                   |                                                 (0 << 0x10)  // moreindustriesperclimate - obsolete
@@ -5119,15 +5119,15 @@
 	                   |                                                 (1 << 0x12)  // newstations
 	                   |                                                 (1 << 0x13)  // tracktypecostdiff
 	                   |                                                 (1 << 0x14)  // manualconvert
-	                   |  ((_settings.construction.build_on_slopes ? 1 : 0) << 0x15)  // buildoncoasts
+	                   |  ((_settings_game.construction.build_on_slopes ? 1 : 0) << 0x15)  // buildoncoasts
 	                   |                                                 (1 << 0x16)  // canals
 	                   |                                                 (1 << 0x17)  // newstartyear
-	                   |    ((_settings.vehicle.freight_trains > 1 ? 1 : 0) << 0x18)  // freighttrains
+	                   |    ((_settings_game.vehicle.freight_trains > 1 ? 1 : 0) << 0x18)  // freighttrains
 	                   |                                                 (1 << 0x19)  // newhouses
 	                   |                                                 (1 << 0x1A)  // newbridges
 	                   |                                                 (1 << 0x1B)  // newtownnames
 	                   |                                                 (1 << 0x1C)  // moreanimation
-	                   |    ((_settings.vehicle.wagon_speed_limits ? 1 : 0) << 0x1D)  // wagonspeedlimits
+	                   |    ((_settings_game.vehicle.wagon_speed_limits ? 1 : 0) << 0x1D)  // wagonspeedlimits
 	                   |                                                 (1 << 0x1E)  // newshistory
 	                   |                                                 (0 << 0x1F); // custombridgeheads
 
@@ -5139,13 +5139,13 @@
 	                   |                                                 (1 << 0x05)  // resolutionwidth
 	                   |                                                 (1 << 0x06)  // resolutionheight
 	                   |                                                 (1 << 0x07)  // newindustries
-	                   |           ((_settings.order.improved_load ? 1 : 0) << 0x08)  // fifoloading
+	                   |           ((_settings_game.order.improved_load ? 1 : 0) << 0x08)  // fifoloading
 	                   |                                                 (0 << 0x09)  // townroadbranchprob
 	                   |                                                 (0 << 0x0A)  // tempsnowline
 	                   |                                                 (1 << 0x0B)  // newcargo
 	                   |                                                 (1 << 0x0C)  // enhancemultiplayer
 	                   |                                                 (1 << 0x0D)  // onewayroads
-	                   |   ((_settings.station.nonuniform_stations ? 1 : 0) << 0x0E)  // irregularstations
+	                   |   ((_settings_game.station.nonuniform_stations ? 1 : 0) << 0x0E)  // irregularstations
 	                   |                                                 (1 << 0x0F)  // statistics
 	                   |                                                 (1 << 0x10)  // newsounds
 	                   |                                                 (1 << 0x11)  // autoreplace
@@ -5155,7 +5155,7 @@
 	                   |                                                 (0 << 0x15)  // enhancetunnels
 	                   |                                                 (1 << 0x16)  // shortrvs
 	                   |                                                 (1 << 0x17)  // articulatedrvs
-	                   |       ((_settings.vehicle.dynamic_engines ? 1 : 0) << 0x18)  // dynamic engines
+	                   |       ((_settings_game.vehicle.dynamic_engines ? 1 : 0) << 0x18)  // dynamic engines
 	                   |                                                 (1 << 0x1E); // variablerunningcosts
 }
 
@@ -5352,7 +5352,7 @@
 	ResetNewGRFErrors();
 
 	/* Set up the default cargo types */
-	SetupCargoForClimate(_settings.game_creation.landscape);
+	SetupCargoForClimate(_settings_game.game_creation.landscape);
 
 	/* Reset misc GRF features and train list display variables */
 	_misc_grf_features = 0;
--- a/src/newgrf.h	Thu May 29 12:52:24 2008 +0000
+++ b/src/newgrf.h	Thu May 29 15:56:32 2008 +0000
@@ -52,7 +52,7 @@
 struct GRFLabel {
 	byte label;
 	uint32 nfo_line;
-	uint32 pos;
+	size_t pos;
 	struct GRFLabel *next;
 };
 
--- a/src/newgrf_commons.cpp	Thu May 29 12:52:24 2008 +0000
+++ b/src/newgrf_commons.cpp	Thu May 29 15:56:32 2008 +0000
@@ -278,7 +278,7 @@
  *         Terrain type: 0 normal, 1 desert, 2 rainforest, 4 on or above snowline */
 uint32 GetTerrainType(TileIndex tile)
 {
-	switch (_settings.game_creation.landscape) {
+	switch (_settings_game.game_creation.landscape) {
 		case LT_TROPIC: return GetTropicZone(tile);
 		case LT_ARCTIC: return GetTileZ(tile) > GetSnowLine() ? 4 : 0;
 		default:        return 0;
--- a/src/newgrf_engine.cpp	Thu May 29 12:52:24 2008 +0000
+++ b/src/newgrf_engine.cpp	Thu May 29 15:56:32 2008 +0000
@@ -1123,7 +1123,7 @@
 		/* Populate map with current list positions */
 		Engine *e;
 		FOR_ALL_ENGINES_OF_TYPE(e, VEH_TRAIN) {
-			if (!_settings.vehicle.dynamic_engines || e->grffile == source_e->grffile) {
+			if (!_settings_game.vehicle.dynamic_engines || e->grffile == source_e->grffile) {
 				if (e->internal_id == target) target_e = e;
 				lptr_map[e->list_position] = e;
 			}
--- a/src/newgrf_town.cpp	Thu May 29 12:52:24 2008 +0000
+++ b/src/newgrf_town.cpp	Thu May 29 15:56:32 2008 +0000
@@ -21,7 +21,7 @@
 	switch (variable) {
 		/* Larger towns */
 		case 0x40:
-			if (_settings.economy.larger_towns == 0) return 2;
+			if (_settings_game.economy.larger_towns == 0) return 2;
 			if (t->larger_town) return 1;
 			return 0;
 
--- a/src/news_gui.cpp	Thu May 29 12:52:24 2008 +0000
+++ b/src/news_gui.cpp	Thu May 29 15:56:32 2008 +0000
@@ -24,52 +24,24 @@
 #include "table/sprites.h"
 #include "table/strings.h"
 
-/** @file news_gui.cpp
- *
- * News system is realized as a FIFO queue (in an array)
- * The positions in the queue can't be rearranged, we only access
- * the array elements through pointers to the elements. Once the
- * array is full, the oldest entry (\a _oldest_news) is being overwritten
- * by the newest (\a _latest_news).
- *
- * \verbatim
- * oldest                   current   lastest
- *  |                          |         |
- * [O------------F-------------C---------L           ]
- *               |
- *            forced
- * \endverbatim
- *
- * Of course by using an array we can have situations like
- *
- * \verbatim
- * [----L          O-----F---------C-----------------]
- * This is where we have wrapped around the array and have
- * (MAX_NEWS - O) + L news items
- * \endverbatim
- */
-
 #define NB_WIDG_PER_SETTING 4
 
-typedef byte NewsID;
-#define INVALID_NEWS 255
-
 NewsItem _statusbar_news_item;
 bool _news_ticker_sound;
-static NewsItem *_news_items = NULL;        ///< The news FIFO queue
-static uint _max_news_items = 0;            ///< size of news FIFO queue
-static NewsID _current_news = INVALID_NEWS; ///< points to news item that should be shown next
-static NewsID _oldest_news = 0;             ///< points to first item in fifo queue
-static NewsID _latest_news = INVALID_NEWS;  ///< points to last item in fifo queue
+
+static uint MIN_NEWS_AMOUNT = 30;           ///< prefered minimum amount of news messages
+static uint _total_news = 0;                ///< current number of news items
+static NewsItem *_oldest_news = NULL;       ///< head of news items queue
+static NewsItem *_latest_news = NULL;       ///< tail of news items queue
 
 /** Forced news item.
  * Users can force an item by accessing the history or "last message".
- * If the message being shown was forced by the user, its index is stored in
- * _forced_news. Otherwise, \a _forced_news variable is INVALID_NEWS. */
-static NewsID _forced_news = INVALID_NEWS;
+ * If the message being shown was forced by the user, a pointer is stored
+ * in _forced_news. Otherwise, \a _forced_news variable is NULL. */
+static NewsItem *_forced_news = NULL;       ///< item the user has asked for
 
-static uint _total_news = 0; ///< Number of news items in FIFO queue @see _news_items
-static void MoveToNextItem();
+/** Current news item (last item shown regularly). */
+static NewsItem *_current_news = NULL;
 
 
 typedef void DrawNewsCallbackProc(struct Window *w, const NewsItem *ni);
@@ -172,18 +144,26 @@
 	{ NT_GENERAL,         NM_NORMAL,   NF_TILE,                NULL                    }, ///< NS_GENERAL
 };
 
-/** Initialize the news-items data structures */
-void InitNewsItemStructs()
-{
-	free(_news_items);
-	_max_news_items = max(ScaleByMapSize(30), 30U);
-	_news_items = CallocT<NewsItem>(_max_news_items);
-	_current_news = INVALID_NEWS;
-	_oldest_news = 0;
-	_latest_news = INVALID_NEWS;
-	_forced_news = INVALID_NEWS;
-	_total_news = 0;
-}
+/**
+ * Per-NewsType data
+ */
+NewsTypeData _news_type_data[NT_END] = {
+	/* name,              age, sound,           display */
+	{ "arrival_player",    60, SND_1D_APPLAUSE, ND_FULL },  ///< NT_ARRIVAL_PLAYER
+	{ "arrival_other",     60, SND_1D_APPLAUSE, ND_FULL },  ///< NT_ARRIVAL_OTHER
+	{ "accident",          90, SND_BEGIN,       ND_FULL },  ///< NT_ACCIDENT
+	{ "company_info",      60, SND_BEGIN,       ND_FULL },  ///< NT_COMPANY_INFO
+	{ "openclose",         90, SND_BEGIN,       ND_FULL },  ///< NT_OPENCLOSE
+	{ "economy",           30, SND_BEGIN,       ND_FULL },  ///< NT_ECONOMY
+	{ "production_player", 30, SND_BEGIN,       ND_FULL },  ///< NT_INDUSTRY_PLAYER
+	{ "production_other",  30, SND_BEGIN,       ND_FULL },  ///< NT_INDUSTRY_OTHER
+	{ "production_nobody", 30, SND_BEGIN,       ND_FULL },  ///< NT_INDUSTRY_NOBODY
+	{ "advice",           150, SND_BEGIN,       ND_FULL },  ///< NT_ADVICE
+	{ "new_vehicles",      30, SND_1E_OOOOH,    ND_FULL },  ///< NT_NEW_VEHICLES
+	{ "acceptance",        90, SND_BEGIN,       ND_FULL },  ///< NT_ACCEPTANCE
+	{ "subsidies",        180, SND_BEGIN,       ND_FULL },  ///< NT_SUBSIDIES
+	{ "general",           60, SND_BEGIN,       ND_FULL },  ///< NT_GENERAL
+};
 
 struct NewsWindow : Window {
 	uint16 chat_height;
@@ -194,7 +174,7 @@
 		const Window *w = FindWindowById(WC_SEND_NETWORK_MSG, 0);
 		this->chat_height = (w != NULL) ? w->height : 0;
 
-		this->ni = &_news_items[_forced_news == INVALID_NEWS ? _current_news : _forced_news];
+		this->ni = _forced_news == NULL ? _current_news : _forced_news;
 		this->flags4 |= WF_DISABLE_VP_SCROLL;
 
 		this->FindWindowPlacementAndResize(desc);
@@ -280,7 +260,7 @@
 			case 1:
 				this->ni->duration = 0;
 				delete this;
-				_forced_news = INVALID_NEWS;
+				_forced_news = NULL;
 				break;
 
 			case 0:
@@ -334,105 +314,6 @@
 	}
 };
 
-/**
- * Return the correct index in the pseudo-fifo
- * queue and deals with overflows when increasing the index
- */
-static inline NewsID IncreaseIndex(NewsID i)
-{
-	assert(i != INVALID_NEWS);
-	return (i + 1) % _max_news_items;
-}
-
-/**
- * Return the correct index in the pseudo-fifo
- * queue and deals with overflows when decreasing the index
- */
-static inline NewsID DecreaseIndex(NewsID i)
-{
-	assert(i != INVALID_NEWS);
-	return (i + _max_news_items - 1) % _max_news_items;
-}
-
-/**
- * Add a new newsitem to be shown.
- * @param string String to display
- * @param subtype news category, any of the NewsSubtype enums (NS_)
- * @param data_a news-specific value based on news type
- * @param data_b news-specific value based on news type
- *
- * @see NewsSubype
- */
-void AddNewsItem(StringID string, NewsSubtype subtype, uint data_a, uint data_b)
-{
-	if (_game_mode == GM_MENU) return;
-
-	/* check the rare case that the oldest (to be overwritten) news item is open */
-	if (_total_news == _max_news_items && (_oldest_news == _current_news || _oldest_news == _forced_news)) {
-		MoveToNextItem();
-	}
-
-	if (_total_news < _max_news_items) _total_news++;
-
-	/* Increase _latest_news. If we have no news yet, use _oldest news as an
-	 * index. We cannot use 0 as _oldest_news can jump around due to
-	 * DeleteVehicleNews */
-	NewsID l_news = _latest_news;
-	_latest_news = (_latest_news == INVALID_NEWS) ? _oldest_news : IncreaseIndex(_latest_news);
-
-	/* If the fifo-buffer is full, overwrite the oldest entry */
-	if (l_news != INVALID_NEWS && _latest_news == _oldest_news) {
-		assert(_total_news == _max_news_items);
-		_oldest_news = IncreaseIndex(_oldest_news);
-	}
-
-	/*DEBUG(misc, 0, "+cur %3d, old %2d, lat %3d, for %3d, tot %2d",
-	  _current_news, _oldest_news, _latest_news, _forced_news, _total_news);*/
-
-	/* Add news to _latest_news */
-	NewsItem *ni = &_news_items[_latest_news];
-	memset(ni, 0, sizeof(*ni));
-
-	ni->string_id = string;
-	ni->subtype = subtype;
-	ni->flags = _news_subtype_data[subtype].flags;
-
-	/* show this news message in color? */
-	if (_cur_year >= _settings.gui.colored_news_year) ni->flags |= NF_INCOLOR;
-
-	ni->data_a = data_a;
-	ni->data_b = data_b;
-	ni->date = _date;
-	CopyOutDParam(ni->params, 0, lengthof(ni->params));
-
-	Window *w = FindWindowById(WC_MESSAGE_HISTORY, 0);
-	if (w == NULL) return;
-	w->SetDirty();
-	w->vscroll.count = _total_news;
-}
-
-
-/**
- * Per-NewsType data
- */
-NewsTypeData _news_type_data[NT_END] = {
-	/* name,              age, sound,           display */
-	{ "arrival_player",    60, SND_1D_APPLAUSE, ND_FULL },  ///< NT_ARRIVAL_PLAYER
-	{ "arrival_other",     60, SND_1D_APPLAUSE, ND_FULL },  ///< NT_ARRIVAL_OTHER
-	{ "accident",          90, SND_BEGIN,       ND_FULL },  ///< NT_ACCIDENT
-	{ "company_info",      60, SND_BEGIN,       ND_FULL },  ///< NT_COMPANY_INFO
-	{ "openclose",         90, SND_BEGIN,       ND_FULL },  ///< NT_OPENCLOSE
-	{ "economy",           30, SND_BEGIN,       ND_FULL },  ///< NT_ECONOMY
-	{ "production_player", 30, SND_BEGIN,       ND_FULL },  ///< NT_INDUSTRY_PLAYER
-	{ "production_other",  30, SND_BEGIN,       ND_FULL },  ///< NT_INDUSTRY_OTHER
-	{ "production_nobody", 30, SND_BEGIN,       ND_FULL },  ///< NT_INDUSTRY_NOBODY
-	{ "advice",           150, SND_BEGIN,       ND_FULL },  ///< NT_ADVICE
-	{ "new_vehicles",      30, SND_1E_OOOOH,    ND_FULL },  ///< NT_NEW_VEHICLES
-	{ "acceptance",        90, SND_BEGIN,       ND_FULL },  ///< NT_ACCEPTANCE
-	{ "subsidies",        180, SND_BEGIN,       ND_FULL },  ///< NT_SUBSIDIES
-	{ "general",           60, SND_BEGIN,       ND_FULL },  ///< NT_GENERAL
-};
-
 
 static const Widget _news_type13_widgets[] = {
 {      WWT_PANEL,   RESIZE_NONE,    15,     0,   429,     0,   169, 0x0, STR_NULL},
@@ -516,9 +397,6 @@
 			}
 			break;
 	}
-
-	/*DEBUG(misc, 0, " cur %3d, old %2d, lat %3d, for %3d, tot %2d",
-	  _current_news, _oldest_news, _latest_news, _forced_news, _total_news);*/
 }
 
 /** Show news item in the ticker */
@@ -530,6 +408,21 @@
 	InvalidateWindowData(WC_STATUS_BAR, 0, SBI_SHOW_TICKER);
 }
 
+/** Initialize the news-items data structures */
+void InitNewsItemStructs()
+{
+	for (NewsItem *ni = _oldest_news; ni != NULL; ) {
+		NewsItem *next = ni->next;
+		delete ni;
+		ni = next;
+	}
+
+	_total_news = 0;
+	_oldest_news = NULL;
+	_latest_news = NULL;
+	_forced_news = NULL;
+	_current_news = NULL;
+}
 
 /**
  * Are we ready to show another news item?
@@ -537,10 +430,8 @@
  */
 static bool ReadyForNextItem()
 {
-	NewsID item = (_forced_news == INVALID_NEWS) ? _current_news : _forced_news;
-
-	if (item >= _max_news_items) return true;
-	NewsItem *ni = &_news_items[item];
+	NewsItem *ni = _forced_news == NULL ? _current_news : _forced_news;
+	if (ni == NULL) return true;
 
 	/* Ticker message
 	 * Check if the status bar message is still being displayed? */
@@ -557,12 +448,12 @@
 static void MoveToNextItem()
 {
 	DeleteWindowById(WC_NEWS_WINDOW, 0);
-	_forced_news = INVALID_NEWS;
+	_forced_news = NULL;
 
 	/* if we're not at the last item, then move on */
 	if (_current_news != _latest_news) {
-		_current_news = (_current_news == INVALID_NEWS) ? _oldest_news : IncreaseIndex(_current_news);
-		NewsItem *ni = &_news_items[_current_news];
+		_current_news = (_current_news == NULL) ? _oldest_news : _current_news->next;
+		NewsItem *ni = _current_news;
 		const NewsType type = _news_subtype_data[ni->subtype].type;
 
 		/* check the date, don't show too old items */
@@ -588,27 +479,140 @@
 	}
 }
 
+/**
+ * Add a new newsitem to be shown.
+ * @param string String to display
+ * @param subtype news category, any of the NewsSubtype enums (NS_)
+ * @param data_a news-specific value based on news type
+ * @param data_b news-specific value based on news type
+ *
+ * @see NewsSubype
+ */
+void AddNewsItem(StringID string, NewsSubtype subtype, uint data_a, uint data_b)
+{
+	if (_game_mode == GM_MENU) return;
+
+	/* Create new news item node */
+	NewsItem *ni = new NewsItem;
+
+	ni->string_id = string;
+	ni->subtype = subtype;
+	ni->flags = _news_subtype_data[subtype].flags;
+
+	/* show this news message in color? */
+	if (_cur_year >= _settings_client.gui.colored_news_year) ni->flags |= NF_INCOLOR;
+
+	ni->data_a = data_a;
+	ni->data_b = data_b;
+	ni->date = _date;
+	CopyOutDParam(ni->params, 0, lengthof(ni->params));
+
+	if (_total_news++ == 0) {
+		assert(_oldest_news == NULL);
+		_oldest_news = ni;
+		ni->prev = NULL;
+	} else {
+		assert(_latest_news->next == NULL);
+		_latest_news->next = ni;
+		ni->prev = _latest_news;
+	}
+
+	ni->next = NULL;
+	_latest_news = ni;
+
+	InvalidateWindow(WC_MESSAGE_HISTORY, 0);
+}
+
+/** Delete a news item from the queue */
+static void DeleteNewsItem(NewsItem *ni)
+{
+	if (_forced_news == ni) {
+		/* about to remove the currently forced item; skip to next */
+		MoveToNextItem();
+	}
+
+	if ((_current_news == ni) && (FindWindowById(WC_MESSAGE_HISTORY, 0) != NULL)) {
+		/* about to remove the currently displayed item; also skip */
+		MoveToNextItem();
+	}
+
+	/* delete item */
+
+	if (ni->prev != NULL) {
+		ni->prev->next = ni->next;
+	} else {
+		assert(_oldest_news == ni);
+		_oldest_news = ni->next;
+	}
+
+	if (ni->next != NULL) {
+		ni->next->prev = ni->prev;
+	} else {
+		assert(_latest_news == ni);
+		_latest_news = ni->prev;
+	}
+
+	if (_current_news == ni) _current_news = ni->prev;
+	_total_news--;
+	delete ni;
+
+	InvalidateWindow(WC_MESSAGE_HISTORY, 0);
+}
+
+void DeleteVehicleNews(VehicleID vid, StringID news)
+{
+	NewsItem *ni = _oldest_news;
+
+	while (ni != NULL) {
+		if (ni->flags & NF_VEHICLE &&
+				ni->data_a == vid &&
+				(news == INVALID_STRING_ID || ni->string_id == news)) {
+			/* grab a pointer to the next item before ni is freed */
+			NewsItem *p = ni->next;
+			DeleteNewsItem(ni);
+			ni = p;
+		} else {
+			ni = ni->next;
+		}
+	}
+}
+
+void RemoveOldNewsItems()
+{
+	NewsItem *next;
+	for (NewsItem *cur = _oldest_news; _total_news > MIN_NEWS_AMOUNT && cur != NULL; cur = next) {
+		next = cur->next;
+		if (_date - _news_type_data[_news_subtype_data[cur->subtype].type].age * _settings_client.gui.news_message_timeout > cur->date) DeleteNewsItem(cur);
+	}
+}
+
 void NewsLoop()
 {
 	/* no news item yet */
 	if (_total_news == 0) return;
 
+	static byte _last_clean_month = 0;
+
+	if (_last_clean_month != _cur_month) {
+		RemoveOldNewsItems();
+		_last_clean_month = _cur_month;
+	}
+
 	if (ReadyForNextItem()) MoveToNextItem();
 }
 
 /** Do a forced show of a specific message */
-static void ShowNewsMessage(NewsID i)
+static void ShowNewsMessage(NewsItem *ni)
 {
-	if (_total_news == 0) return;
+	assert(_total_news != 0);
 
 	/* Delete the news window */
 	DeleteWindowById(WC_NEWS_WINDOW, 0);
 
 	/* setup forced news item */
-	_forced_news = i;
+	_forced_news = ni;
 
-	if (_forced_news != INVALID_NEWS) {
-		NewsItem *ni = &_news_items[_forced_news];
+	if (_forced_news != NULL) {
 		ni->duration = 555;
 		ni->flags |= NF_FORCE_BIG;
 		DeleteWindowById(WC_NEWS_WINDOW, 0);
@@ -619,37 +623,23 @@
 /** Show previous news item */
 void ShowLastNewsMessage()
 {
-	if (_forced_news == INVALID_NEWS) {
+	if (_total_news == 0) {
+		return;
+	} else if (_forced_news == NULL) {
 		/* Not forced any news yet, show the current one, unless a news window is
 		 * open (which can only be the current one), then show the previous item */
 		const Window *w = FindWindowById(WC_NEWS_WINDOW, 0);
-		ShowNewsMessage((w == NULL || (_current_news == _oldest_news)) ? _current_news : DecreaseIndex(_current_news));
+		ShowNewsMessage((w == NULL || (_current_news == _oldest_news)) ? _current_news : _current_news->prev);
 	} else if (_forced_news == _oldest_news) {
 		/* We have reached the oldest news, start anew with the latest */
 		ShowNewsMessage(_latest_news);
 	} else {
 		/* 'Scrolling' through news history show each one in turn */
-		ShowNewsMessage(DecreaseIndex(_forced_news));
+		ShowNewsMessage(_forced_news->prev);
 	}
 }
 
 
-/* return news by number, with 0 being the most
- * recent news. Returns INVALID_NEWS if end of queue reached. */
-static NewsID getNews(NewsID i)
-{
-	if (i >= _total_news) return INVALID_NEWS;
-
-	if (_latest_news < i) {
-		i = _latest_news + _max_news_items - i;
-	} else {
-		i = _latest_news - i;
-	}
-
-	i %= _max_news_items;
-	return i;
-}
-
 /**
  * Draw an unformatted news message truncated to a maximum length. If
  * length exceeds maximum length it will be postfixed by '...'
@@ -715,27 +705,37 @@
 		this->DrawWidgets();
 
 		if (_total_news == 0) return;
-		NewsID show = min(_total_news, this->vscroll.cap);
 
-		for (NewsID p = this->vscroll.pos; p < this->vscroll.pos + show; p++) {
-			/* get news in correct order */
-			const NewsItem *ni = &_news_items[getNews(p)];
+		NewsItem *ni = _latest_news;
+		for (int n = this->vscroll.pos; n > 0; n--) {
+			ni = ni->prev;
+			if (ni == NULL) return;
+		}
 
+		for (int n = this->vscroll.cap; n > 0; n--) {
 			SetDParam(0, ni->date);
 			DrawString(4, y, STR_SHORT_DATE, TC_WHITE);
 
 			DrawNewsString(82, y, TC_WHITE, ni, this->width - 95);
 			y += 12;
+
+			ni = ni->prev;
+			if (ni == NULL) return;
 		}
 	}
 
 	virtual void OnClick(Point pt, int widget)
 	{
 		if (widget == 3) {
-			int y = (pt.y - 19) / 12;
-			NewsID p = getNews(y + this->vscroll.pos);
+			NewsItem *ni = _latest_news;
+			if (ni == NULL) return;
 
-			if (p != INVALID_NEWS) ShowNewsMessage(p);
+			for (int n = (pt.y - 19) / 12 + this->vscroll.pos; n > 0; n--) {
+				ni = ni->prev;
+				if (ni == NULL) return;
+			}
+
+			ShowNewsMessage(ni);
 		}
 	}
 
@@ -976,66 +976,3 @@
 	DeleteWindowById(WC_GAME_OPTIONS, 0);
 	new MessageOptionsWindow(&_message_options_desc);
 }
-
-
-void DeleteVehicleNews(VehicleID vid, StringID news)
-{
-	for (NewsID n = _oldest_news; _latest_news != INVALID_NEWS; n = IncreaseIndex(n)) {
-		const NewsItem *ni = &_news_items[n];
-
-		if (ni->flags & NF_VEHICLE &&
-				ni->data_a == vid &&
-				(news == INVALID_STRING_ID || ni->string_id == news)) {
-			/* If we delete a forced news and it is just before the current news
-			 * then we need to advance to the next news (if any) */
-			if (_forced_news == n) MoveToNextItem();
-			if (_forced_news == INVALID_NEWS && _current_news == n) MoveToNextItem();
-			_total_news--;
-
-			/* If this is the last news item, invalidate _latest_news */
-			if (_total_news == 0) {
-				assert(_latest_news == _oldest_news);
-				_latest_news = INVALID_NEWS;
-				_current_news = INVALID_NEWS;
-			}
-
-			/* Since we only imitate a FIFO removing an arbitrary element does need
-			 * some magic. Remove the item by shifting head towards the tail. eg
-			 *    oldest    remove  last
-			 *        |        |     |
-			 * [------O--------n-----L--]
-			 * will become (change dramatized to make clear)
-			 * [---------O-----------L--]
-			 * We also need an update of the current, forced and visible (open window)
-			 * news's as this shifting could change the items they were pointing to */
-			if (_total_news != 0) {
-				NewsWindow *w = dynamic_cast<NewsWindow*>(FindWindowById(WC_NEWS_WINDOW, 0));
-				NewsID visible_news = (w != NULL) ? (NewsID)(w->ni - _news_items) : INVALID_NEWS;
-
-				for (NewsID i = n;; i = DecreaseIndex(i)) {
-					_news_items[i] = _news_items[DecreaseIndex(i)];
-
-					if (i != _latest_news) {
-						if (i == _current_news) _current_news = IncreaseIndex(_current_news);
-						if (i == _forced_news) _forced_news = IncreaseIndex(_forced_news);
-						if (i == visible_news) w->ni = &_news_items[IncreaseIndex(visible_news)];
-					}
-
-					if (i == _oldest_news) break;
-				}
-				_oldest_news = IncreaseIndex(_oldest_news);
-			}
-
-			/*DEBUG(misc, 0, "-cur %3d, old %2d, lat %3d, for %3d, tot %2d",
-			  _current_news, _oldest_news, _latest_news, _forced_news, _total_news);*/
-
-			Window *w = FindWindowById(WC_MESSAGE_HISTORY, 0);
-			if (w != NULL) {
-				w->SetDirty();
-				w->vscroll.count = _total_news;
-			}
-		}
-
-		if (n == _latest_news) break;
-	}
-}
--- a/src/news_type.h	Thu May 29 12:52:24 2008 +0000
+++ b/src/news_type.h	Thu May 29 15:56:32 2008 +0000
@@ -101,6 +101,8 @@
 };
 
 struct NewsItem {
+	NewsItem *prev;        ///< Previous news item
+	NewsItem *next;        ///< Next news item
 	StringID string_id;    ///< Message text
 	uint16 duration;       ///< Remaining time for showing this news message
 	Date date;             ///< Date of the news
--- a/src/npf.cpp	Thu May 29 12:52:24 2008 +0000
+++ b/src/npf.cpp	Thu May 29 15:56:32 2008 +0000
@@ -213,7 +213,7 @@
 
 	if (z2 - z1 > 1) {
 		/* Slope up */
-		return _settings.pf.npf.npf_rail_slope_penalty;
+		return _settings_game.pf.npf.npf_rail_slope_penalty;
 	}
 	return 0;
 	/* Should we give a bonus for slope down? Probably not, we
@@ -260,10 +260,10 @@
 	cost = _trackdir_length[trackdir]; // Should be different for diagonal tracks
 
 	if (IsBuoyTile(current->tile) && IsDiagonalTrackdir(trackdir))
-		cost += _settings.pf.npf.npf_buoy_penalty; // A small penalty for going over buoys
+		cost += _settings_game.pf.npf.npf_buoy_penalty; // A small penalty for going over buoys
 
 	if (current->direction != NextTrackdir((Trackdir)parent->path.node.direction))
-		cost += _settings.pf.npf.npf_water_curve_penalty;
+		cost += _settings_game.pf.npf.npf_water_curve_penalty;
 
 	/* @todo More penalties? */
 
@@ -285,13 +285,13 @@
 		case MP_ROAD:
 			cost = NPF_TILE_LENGTH;
 			/* Increase the cost for level crossings */
-			if (IsLevelCrossing(tile)) cost += _settings.pf.npf.npf_crossing_penalty;
+			if (IsLevelCrossing(tile)) cost += _settings_game.pf.npf.npf_crossing_penalty;
 			break;
 
 		case MP_STATION:
 			cost = NPF_TILE_LENGTH;
 			/* Increase the cost for drive-through road stops */
-			if (IsDriveThroughStopTile(tile)) cost += _settings.pf.npf.npf_road_drive_through_penalty;
+			if (IsDriveThroughStopTile(tile)) cost += _settings_game.pf.npf.npf_road_drive_through_penalty;
 			break;
 
 		default:
@@ -306,7 +306,7 @@
 	/* Check for turns. Road vehicles only really drive diagonal, turns are
 	 * represented by non-diagonal tracks */
 	if (!IsDiagonalTrackdir((Trackdir)current->direction))
-		cost += _settings.pf.npf.npf_road_curve_penalty;
+		cost += _settings_game.pf.npf.npf_road_curve_penalty;
 
 	NPFMarkTile(tile);
 	DEBUG(npf, 4, "Calculating G for: (%d, %d). Result: %d", TileX(current->tile), TileY(current->tile), cost);
@@ -344,7 +344,7 @@
 			 * give any station tile a penalty, because every possible route will get
 			 * this penalty exactly once, on its end tile (if it's a station) and it
 			 * will therefore not make a difference. */
-			cost = NPF_TILE_LENGTH + _settings.pf.npf.npf_rail_station_penalty;
+			cost = NPF_TILE_LENGTH + _settings_game.pf.npf.npf_rail_station_penalty;
 			break;
 
 		default:
@@ -366,9 +366,9 @@
 				SignalType sigtype = GetSignalType(tile, TrackdirToTrack(trackdir));
 				if (sigtype == SIGTYPE_EXIT || sigtype == SIGTYPE_COMBO) {
 					/* Penalise exit and combo signals differently (heavier) */
-					cost += _settings.pf.npf.npf_rail_firstred_exit_penalty;
+					cost += _settings_game.pf.npf.npf_rail_firstred_exit_penalty;
 				} else {
-					cost += _settings.pf.npf.npf_rail_firstred_penalty;
+					cost += _settings_game.pf.npf.npf_rail_firstred_penalty;
 				}
 			}
 			/* Record the state of this signal */
@@ -386,14 +386,14 @@
 	 * of course... */
 	new_node.path.node = *current;
 	if (as->EndNodeCheck(as, &new_node) == AYSTAR_FOUND_END_NODE && NPFGetFlag(current, NPF_FLAG_LAST_SIGNAL_RED))
-		cost += _settings.pf.npf.npf_rail_lastred_penalty;
+		cost += _settings_game.pf.npf.npf_rail_lastred_penalty;
 
 	/* Check for slope */
 	cost += NPFSlopeCost(current);
 
 	/* Check for turns */
 	if (current->direction != NextTrackdir((Trackdir)parent->path.node.direction))
-		cost += _settings.pf.npf.npf_rail_curve_penalty;
+		cost += _settings_game.pf.npf.npf_rail_curve_penalty;
 	/*TODO, with realistic acceleration, also the amount of straight track between
 	 *      curves should be taken into account, as this affects the speed limit. */
 
@@ -402,7 +402,7 @@
 		/* Penalise any depot tile that is not the last tile in the path. This
 		 * _should_ penalise every occurence of reversing in a depot (and only
 		 * that) */
-		cost += _settings.pf.npf.npf_rail_depot_reverse_penalty;
+		cost += _settings_game.pf.npf.npf_rail_depot_reverse_penalty;
 	}
 
 	/* Check for occupied track */
@@ -634,7 +634,7 @@
 	trackdirbits &= TrackdirReachesTrackdirs(src_trackdir);
 
 	/* Filter out trackdirs that would make 90 deg turns for trains */
-	if (_settings.pf.forbid_90_deg && (type == TRANSPORT_RAIL || type == TRANSPORT_WATER)) trackdirbits &= ~TrackdirCrossesTrackdirs(src_trackdir);
+	if (_settings_game.pf.forbid_90_deg && (type == TRANSPORT_RAIL || type == TRANSPORT_WATER)) trackdirbits &= ~TrackdirCrossesTrackdirs(src_trackdir);
 
 	DEBUG(npf, 6, "After filtering: (%d, %d), possible trackdirs: 0x%X", TileX(dst_tile), TileY(dst_tile), trackdirbits);
 
@@ -970,7 +970,7 @@
 	//_npf_aystar.max_search_nodes = 0;
 	/* We will limit the number of nodes for now, until we have a better
 	 * solution to really fix performance */
-	_npf_aystar.max_search_nodes = _settings.pf.npf.npf_max_search_nodes;
+	_npf_aystar.max_search_nodes = _settings_game.pf.npf.npf_max_search_nodes;
 }
 
 void NPFFillWithOrderData(NPFFindStationOrTileData* fstd, Vehicle* v)
--- a/src/oldloader.cpp	Thu May 29 12:52:24 2008 +0000
+++ b/src/oldloader.cpp	Thu May 29 15:56:32 2008 +0000
@@ -318,8 +318,8 @@
 	/* Convert town-names if needed */
 	FOR_ALL_TOWNS(town) {
 		if (IsInsideMM(town->townnametype, 0x20C1, 0x20C3)) {
-			town->townnametype = SPECSTR_TOWNNAME_ENGLISH + _settings.game_creation.town_name;
-			town->townnameparts = GetOldTownName(town->townnameparts, _settings.game_creation.town_name);
+			town->townnametype = SPECSTR_TOWNNAME_ENGLISH + _settings_game.game_creation.town_name;
+			town->townnameparts = GetOldTownName(town->townnameparts, _settings_game.game_creation.town_name);
 		}
 	}
 }
@@ -1244,8 +1244,8 @@
 
 static inline bool LoadOldGameDifficulty(LoadgameState *ls, int num)
 {
-	bool ret = LoadChunk(ls, &_settings.difficulty, game_difficulty_chunk);
-	_settings.difficulty.max_loan *= 1000;
+	bool ret = LoadChunk(ls, &_settings_game.difficulty, game_difficulty_chunk);
+	_settings_game.difficulty.max_loan *= 1000;
 	return ret;
 }
 
@@ -1424,8 +1424,8 @@
 
 	OCL_VAR ( OC_FILE_U8 | OC_VAR_U16,    1, &_station_tick_ctr ),
 
-	OCL_VAR (  OC_UINT8,    1, &_settings.gui.currency ),
-	OCL_VAR (  OC_UINT8,    1, &_settings.gui.units ),
+	OCL_VAR (  OC_UINT8,    1, &_settings_client.gui.currency ),
+	OCL_VAR (  OC_UINT8,    1, &_settings_client.gui.units ),
 	OCL_VAR ( OC_FILE_U8 | OC_VAR_U32,    1, &_cur_player_tick_index ),
 
 	OCL_NULL( 2 ),               ///< Date stuff, calculated automatically
@@ -1435,19 +1435,19 @@
 	OCL_VAR (  OC_UINT8,    1, &_economy.infl_amount_pr ),
 	OCL_VAR (  OC_UINT8,    1, &_economy.interest_rate ),
 	OCL_NULL( 1 ), // available airports
-	OCL_VAR (  OC_UINT8,    1, &_settings.vehicle.road_side ),
-	OCL_VAR (  OC_UINT8,    1, &_settings.game_creation.town_name ),
+	OCL_VAR (  OC_UINT8,    1, &_settings_game.vehicle.road_side ),
+	OCL_VAR (  OC_UINT8,    1, &_settings_game.game_creation.town_name ),
 
 	OCL_CHUNK( 1, LoadOldGameDifficulty ),
 
 	OCL_ASSERT( 0x77130 ),
 
-	OCL_VAR (  OC_UINT8,    1, &_settings.difficulty.diff_level ),
-	OCL_VAR (  OC_UINT8,    1, &_settings.game_creation.landscape ),
+	OCL_VAR (  OC_UINT8,    1, &_settings_game.difficulty.diff_level ),
+	OCL_VAR (  OC_UINT8,    1, &_settings_game.game_creation.landscape ),
 	OCL_VAR (  OC_UINT8,    1, &_trees_tick_ctr ),
 
 	OCL_NULL( 1 ),               ///< Custom vehicle types yes/no, no longer used
-	OCL_VAR (  OC_UINT8,    1, &_settings.game_creation.snow_line ),
+	OCL_VAR (  OC_UINT8,    1, &_settings_game.game_creation.snow_line ),
 
 	OCL_NULL( 32 ),              ///< new_industry_randtable, no longer used (because of new design)
 	OCL_NULL( 36 ),              ///< cargo-stuff, calculated in InitializeLandscapeVariables
@@ -1482,7 +1482,7 @@
 	DEBUG(oldloader, 3, "Done, converting game data...");
 
 	/* Fix some general stuff */
-	_settings.game_creation.landscape = _settings.game_creation.landscape & 0xF;
+	_settings_game.game_creation.landscape = _settings_game.game_creation.landscape & 0xF;
 
 	/* Remap some pointers */
 	_cur_town_ctr      = REMAP_TOWN_IDX(_old_cur_town_ctr);
@@ -1544,7 +1544,7 @@
 	FixOldVehicles();
 
 	/* We have a new difficulty setting */
-	_settings.difficulty.town_council_tolerance = Clamp(_settings.difficulty.diff_level, 0, 2);
+	_settings_game.difficulty.town_council_tolerance = Clamp(_settings_game.difficulty.diff_level, 0, 2);
 
 	DEBUG(oldloader, 3, "Finished converting game data");
 	DEBUG(oldloader, 1, "TTD(Patch) savegame successfully converted");
--- a/src/openttd.cpp	Thu May 29 12:52:24 2008 +0000
+++ b/src/openttd.cpp	Thu May 29 15:56:32 2008 +0000
@@ -23,10 +23,7 @@
 #include "gui.h"
 #include "mixer.h"
 #include "sound_func.h"
-#include "viewport_func.h"
 #include "window_func.h"
-#include "window_gui.h"
-#include "zoom_func.h"
 
 #include "debug.h"
 #include "saveload.h"
@@ -289,7 +286,6 @@
 static void InitializeDynamicVariables()
 {
 	/* Dynamic stuff needs to be initialized somewhere... */
-	_town_sort     = NULL;
 	_industry_mngr.ResetMapping();
 	_industile_mngr.ResetMapping();
 }
@@ -325,8 +321,6 @@
 	_CargoPacket_pool.CleanPool();
 	_Engine_pool.CleanPool();
 
-	free((void*)_town_sort);
-
 	free(_config_file);
 
 	/* Close all and any open filehandles */
@@ -351,8 +345,6 @@
 
 	_pause_game = 0;
 	SetLocalPlayer(PLAYER_FIRST);
-	/* Make sure you can't scroll in the menu */
-	_scrolling_viewport = 0;
 	_cursor.fix_at = false;
 	MarkWholeScreenDirty();
 
@@ -362,7 +354,6 @@
 	if (_music_driver->IsSongPlaying()) ResetMusic();
 }
 
-byte _no_scroll;
 byte _savegame_sort_order;
 #if defined(UNIX) && !defined(__MORPHOS__)
 extern void DedicatedFork();
@@ -598,10 +589,8 @@
 	/* XXX - ugly hack, if diff_level is 9, it means we got no setting from the config file */
 	if (_settings_newgame.difficulty.diff_level == 9) SetDifficultyLevel(0, &_settings_newgame.difficulty);
 
-	/* Make sure _patches is filled with _patches_newgame if we switch to a game directly */
-	if (_switch_mode != SM_NONE) {
-		UpdatePatches();
-	}
+	/* Make sure _settings is filled with _settings_newgame if we switch to a game directly */
+	if (_switch_mode != SM_NONE) _settings_game = _settings_newgame;
 
 	/* initialize the ingame console */
 	IConsoleInit();
@@ -661,7 +650,7 @@
 {
 	if (_game_mode == GM_MENU) { // do not ask to quit on the main screen
 		_exit_game = true;
-	} else if (_settings.gui.autosave_on_exit) {
+	} else if (_settings_client.gui.autosave_on_exit) {
 		DoExitSave();
 		_exit_game = true;
 	} else {
@@ -693,9 +682,9 @@
 
 	SetLocalPlayer(PLAYER_FIRST);
 	_current_player = _local_player;
-	DoCommandP(0, (_settings.gui.autorenew << 15 ) | (_settings.gui.autorenew_months << 16) | 4, _settings.gui.autorenew_money, NULL, CMD_SET_AUTOREPLACE);
+	DoCommandP(0, (_settings_client.gui.autorenew << 15 ) | (_settings_client.gui.autorenew_months << 16) | 4, _settings_client.gui.autorenew_money, NULL, CMD_SET_AUTOREPLACE);
 
-	SettingsDisableElrail(_settings.vehicle.disable_elrails);
+	SettingsDisableElrail(_settings_game.vehicle.disable_elrails);
 	InitializeRailGUI();
 
 #ifdef ENABLE_NETWORK
@@ -720,7 +709,7 @@
 	_industry_mngr.ResetMapping();
 
 	GenerateWorldSetCallback(&MakeNewGameDone);
-	GenerateWorld(from_heightmap ? GW_HEIGHTMAP : GW_NEWGAME, 1 << _settings.game_creation.map_x, 1 << _settings.game_creation.map_y);
+	GenerateWorld(from_heightmap ? GW_HEIGHTMAP : GW_NEWGAME, 1 << _settings_game.game_creation.map_x, 1 << _settings_game.game_creation.map_y);
 }
 
 static void MakeNewEditorWorldDone()
@@ -737,7 +726,7 @@
 	ResetGRFConfig(true);
 
 	GenerateWorldSetCallback(&MakeNewEditorWorldDone);
-	GenerateWorld(GW_EMPTY, 1 << _settings.game_creation.map_x, 1 << _settings.game_creation.map_y);
+	GenerateWorld(GW_EMPTY, 1 << _settings_game.game_creation.map_x, 1 << _settings_game.game_creation.map_y);
 }
 
 void StartupPlayers();
@@ -776,7 +765,7 @@
 		ShowErrorMessage(INVALID_STRING_ID, STR_012D, 0, 0);
 	}
 
-	_settings.difficulty = _settings_newgame.difficulty;
+	_settings_game.difficulty = _settings_newgame.difficulty;
 
 	/* Inititalize data */
 	StartupEconomy();
@@ -786,7 +775,7 @@
 
 	SetLocalPlayer(PLAYER_FIRST);
 	_current_player = _local_player;
-	DoCommandP(0, (_settings.gui.autorenew << 15 ) | (_settings.gui.autorenew_months << 16) | 4, _settings.gui.autorenew_money, NULL, CMD_SET_AUTOREPLACE);
+	DoCommandP(0, (_settings_client.gui.autorenew << 15 ) | (_settings_client.gui.autorenew_months << 16) | 4, _settings_client.gui.autorenew_money, NULL, CMD_SET_AUTOREPLACE);
 
 	MarkWholeScreenDirty();
 }
@@ -845,7 +834,7 @@
 				/* check if we should reload the config */
 				if (_network_reload_cfg) {
 					LoadFromConfig();
-					_settings = _settings_newgame;
+					_settings_game = _settings_newgame;
 					ResetGRFConfig(false);
 				}
 				NetworkServerStart();
@@ -918,7 +907,7 @@
 		case SM_LOAD_HEIGHTMAP: /* Load heightmap from scenario editor */
 			SetLocalPlayer(OWNER_NONE);
 
-			GenerateWorld(GW_HEIGHTMAP, 1 << _settings.game_creation.map_x, 1 << _settings.game_creation.map_y);
+			GenerateWorld(GW_HEIGHTMAP, 1 << _settings_game.game_creation.map_x, 1 << _settings_game.game_creation.map_y);
 			MarkWholeScreenDirty();
 			break;
 
@@ -952,7 +941,7 @@
 
 		case SM_GENRANDLAND: /* Generate random land within scenario editor */
 			SetLocalPlayer(OWNER_NONE);
-			GenerateWorld(GW_RANDOM, 1 << _settings.game_creation.map_x, 1 << _settings.game_creation.map_y);
+			GenerateWorld(GW_RANDOM, 1 << _settings_game.game_creation.map_x, 1 << _settings_game.game_creation.map_y);
 			/* XXX: set date */
 			MarkWholeScreenDirty();
 			break;
@@ -1068,16 +1057,16 @@
 	if (_networking) return;
 #endif /* PSP */
 
-	if (_settings.gui.keep_all_autosave && _local_player != PLAYER_SPECTATOR) {
+	if (_settings_client.gui.keep_all_autosave && _local_player != PLAYER_SPECTATOR) {
 		SetDParam(0, _local_player);
 		SetDParam(1, _date);
 		GetString(buf, STR_4004, lastof(buf));
 		ttd_strlcat(buf, ".sav", lengthof(buf));
 	} else {
-		/* generate a savegame name and number according to _settings.gui.max_num_autosaves */
+		/* generate a savegame name and number according to _settings_client.gui.max_num_autosaves */
 		snprintf(buf, sizeof(buf), "autosave%d.sav", _autosave_ctr);
 
-		if (++_autosave_ctr >= _settings.gui.max_num_autosaves) _autosave_ctr = 0;
+		if (++_autosave_ctr >= _settings_client.gui.max_num_autosaves) _autosave_ctr = 0;
 	}
 
 	DEBUG(sl, 2, "Autosaving to '%s'", buf);
@@ -1086,53 +1075,6 @@
 	}
 }
 
-static void ScrollMainViewport(int x, int y)
-{
-	if (_game_mode != GM_MENU) {
-		Window *w = FindWindowById(WC_MAIN_WINDOW, 0);
-		assert(w);
-
-		w->viewport->dest_scrollpos_x += ScaleByZoom(x, w->viewport->zoom);
-		w->viewport->dest_scrollpos_y += ScaleByZoom(y, w->viewport->zoom);
-	}
-}
-
-/**
- * Describes all the different arrow key combinations the game allows
- * when it is in scrolling mode.
- * The real arrow keys are bitwise numbered as
- * 1 = left
- * 2 = up
- * 4 = right
- * 8 = down
- */
-static const int8 scrollamt[16][2] = {
-	{ 0,  0}, ///<  no key specified
-	{-2,  0}, ///<  1 : left
-	{ 0, -2}, ///<  2 : up
-	{-2, -1}, ///<  3 : left  + up
-	{ 2,  0}, ///<  4 : right
-	{ 0,  0}, ///<  5 : left  + right = nothing
-	{ 2, -1}, ///<  6 : right + up
-	{ 0, -2}, ///<  7 : right + left  + up = up
-	{ 0  ,2}, ///<  8 : down
-	{-2  ,1}, ///<  9 : down  + left
-	{ 0,  0}, ///< 10 : down  + up    = nothing
-	{-2,  0}, ///< 11 : left  + up    +  down = left
-	{ 2,  1}, ///< 12 : down  + right
-	{ 0,  2}, ///< 13 : left  + right +  down = down
-	{ 2,  0}, ///< 14 : right + up    +  down = right
-	{ 0,  0}, ///< 15 : left  + up    +  right + down  = nothing
-};
-
-static void HandleKeyScrolling()
-{
-	if (_dirkeys && !_no_scroll) {
-		int factor = _shift_pressed ? 50 : 10;
-		ScrollMainViewport(scrollamt[_dirkeys][0] * factor, scrollamt[_dirkeys][1] * factor);
-	}
-}
-
 void GameLoop()
 {
 	ProcessAsyncSaveFinish();
@@ -1144,9 +1086,6 @@
 		RedrawAutosave();
 	}
 
-	/* handle scrolling of the main window */
-	HandleKeyScrolling();
-
 	/* make a screenshot? */
 	if (IsScreenshotRequested()) ShowScreenshotResult(MakeScreenshot());
 
@@ -1159,12 +1098,6 @@
 	IncreaseSpriteLRU();
 	InteractiveRandom();
 
-	if (_scroller_click_timeout > 3) {
-		_scroller_click_timeout -= 3;
-	} else {
-		_scroller_click_timeout = 0;
-	}
-
 	_caret_timer += 3;
 	_palette_animation_counter += 8;
 	CursorTick();
@@ -1198,17 +1131,6 @@
 	MusicLoop();
 }
 
-void BeforeSaveGame()
-{
-	const Window *w = FindWindowById(WC_MAIN_WINDOW, 0);
-
-	if (w != NULL) {
-		_saved_scrollpos_x = w->viewport->scrollpos_x;
-		_saved_scrollpos_y = w->viewport->scrollpos_y;
-		_saved_scrollpos_zoom = w->viewport->zoom;
-	}
-}
-
 static void ConvertTownOwner()
 {
 	for (TileIndex tile = 0; tile != MapSize(); tile++) {
@@ -1267,7 +1189,7 @@
 /* since savegame version 4.2 the currencies are arranged differently */
 static void UpdateCurrencies()
 {
-	_settings.gui.currency = convert_currency[_settings.gui.currency];
+	_settings_client.gui.currency = convert_currency[_settings_client.gui.currency];
 }
 
 /* Up to revision 1413 the invisible tiles at the southern border have not been
@@ -1314,20 +1236,8 @@
 	ResetWindowSystem();
 	SetupColorsAndInitialWindow();
 
-	Window *w = FindWindowById(WC_MAIN_WINDOW, 0);
-
-	w->viewport->scrollpos_x = _saved_scrollpos_x;
-	w->viewport->scrollpos_y = _saved_scrollpos_y;
-	w->viewport->dest_scrollpos_x = _saved_scrollpos_x;
-	w->viewport->dest_scrollpos_y = _saved_scrollpos_y;
-
-	ViewPort *vp = w->viewport;
-	vp->zoom = min(_saved_scrollpos_zoom, ZOOM_LVL_MAX);
-	vp->virtual_width = ScaleByZoom(vp->width, vp->zoom);
-	vp->virtual_height = ScaleByZoom(vp->height, vp->zoom);
-
-	DoZoomInOutWindow(ZOOM_NONE, w); // update button status
-	MarkWholeScreenDirty();
+	extern void ResetViewportAfterLoadGame();
+	ResetViewportAfterLoadGame();
 
 	/* Update coordinates of the signs. */
 	UpdateAllStationVirtCoord();
@@ -1402,7 +1312,7 @@
 		Town *t;
 		FOR_ALL_TOWNS(t) {
 			t->name = CopyFromOldName(t->townnametype);
-			if (t->name != NULL) t->townnametype = SPECSTR_TOWNNAME_START + _settings.game_creation.town_name;
+			if (t->name != NULL) t->townnametype = SPECSTR_TOWNNAME_START + _settings_game.game_creation.town_name;
 		}
 
 		Waypoint *wp;
@@ -1416,7 +1326,7 @@
 	ResetOldNames();
 
 	/* convert road side to my format. */
-	if (_settings.vehicle.road_side) _settings.vehicle.road_side = 1;
+	if (_settings_game.vehicle.road_side) _settings_game.vehicle.road_side = 1;
 
 	/* Check if all NewGRFs are present, we are very strict in MP mode */
 	GRFListCompatibility gcf_res = IsGoodGRFConfigList();
@@ -1436,7 +1346,7 @@
 	SetDate(_date);
 
 	/* Force dynamic engines off when loading older savegames */
-	if (CheckSavegameVersion(95)) _settings.vehicle.dynamic_engines = 0;
+	if (CheckSavegameVersion(95)) _settings_game.vehicle.dynamic_engines = 0;
 
 	/* Load the sprites */
 	GfxLoadSprites();
@@ -1643,9 +1553,9 @@
 		 */
 		if (!_network_dedicated && IsValidPlayer(PLAYER_FIRST)) {
 			p = GetPlayer(PLAYER_FIRST);
-			p->engine_renew        = _settings.gui.autorenew;
-			p->engine_renew_months = _settings.gui.autorenew_months;
-			p->engine_renew_money  = _settings.gui.autorenew_money;
+			p->engine_renew        = _settings_client.gui.autorenew;
+			p->engine_renew_months = _settings_client.gui.autorenew_months;
+			p->engine_renew_money  = _settings_client.gui.autorenew_money;
 		}
 	}
 
@@ -1927,8 +1837,6 @@
 		}
 	}
 
-	if (CheckSavegameVersion(22))  UpdatePatches();
-
 	if (CheckSavegameVersion(25)) {
 		Vehicle *v;
 		FOR_ALL_VEHICLES(v) {
@@ -2030,9 +1938,9 @@
 
 	/* from version 38 we have optional elrails, since we cannot know the
 	 * preference of a user, let elrails enabled; it can be disabled manually */
-	if (CheckSavegameVersion(38)) _settings.vehicle.disable_elrails = false;
+	if (CheckSavegameVersion(38)) _settings_game.vehicle.disable_elrails = false;
 	/* do the same as when elrails were enabled/disabled manually just now */
-	SettingsDisableElrail(_settings.vehicle.disable_elrails);
+	SettingsDisableElrail(_settings_game.vehicle.disable_elrails);
 	InitializeRailGUI();
 
 	/* From version 53, the map array was changed for house tiles to allow
@@ -2197,7 +2105,7 @@
 		Town *t;
 
 		FOR_ALL_TOWNS(t) {
-			if (_settings.economy.larger_towns != 0 && (t->index % _settings.economy.larger_towns) == 0) {
+			if (_settings_game.economy.larger_towns != 0 && (t->index % _settings_game.economy.larger_towns) == 0) {
 				t->larger_town = true;
 			}
 		}
@@ -2234,12 +2142,12 @@
 	if (CheckSavegameVersion(58)) {
 		/* patch difficulty number_industries other then zero get bumped to +1
 		 * since a new option (very low at position1) has been added */
-		if (_settings.difficulty.number_industries > 0) {
-			_settings.difficulty.number_industries++;
+		if (_settings_game.difficulty.number_industries > 0) {
+			_settings_game.difficulty.number_industries++;
 		}
 
 		/* Same goes for number of towns, although no test is needed, just an increment */
-		_settings.difficulty.number_towns++;
+		_settings_game.difficulty.number_towns++;
 	}
 
 	if (CheckSavegameVersion(64)) {
@@ -2472,22 +2380,22 @@
 		}
 
 		/* Convert old PF settings to new */
-		if (_settings.pf.yapf.rail_use_yapf || CheckSavegameVersion(28)) {
-			_settings.pf.pathfinder_for_trains = VPF_YAPF;
+		if (_settings_game.pf.yapf.rail_use_yapf || CheckSavegameVersion(28)) {
+			_settings_game.pf.pathfinder_for_trains = VPF_YAPF;
 		} else {
-			_settings.pf.pathfinder_for_trains = (_settings.pf.new_pathfinding_all ? VPF_NPF : VPF_NTP);
+			_settings_game.pf.pathfinder_for_trains = (_settings_game.pf.new_pathfinding_all ? VPF_NPF : VPF_NTP);
 		}
 
-		if (_settings.pf.yapf.road_use_yapf || CheckSavegameVersion(28)) {
-			_settings.pf.pathfinder_for_roadvehs = VPF_YAPF;
+		if (_settings_game.pf.yapf.road_use_yapf || CheckSavegameVersion(28)) {
+			_settings_game.pf.pathfinder_for_roadvehs = VPF_YAPF;
 		} else {
-			_settings.pf.pathfinder_for_roadvehs = (_settings.pf.new_pathfinding_all ? VPF_NPF : VPF_OPF);
+			_settings_game.pf.pathfinder_for_roadvehs = (_settings_game.pf.new_pathfinding_all ? VPF_NPF : VPF_OPF);
 		}
 
-		if (_settings.pf.yapf.ship_use_yapf) {
-			_settings.pf.pathfinder_for_ships = VPF_YAPF;
+		if (_settings_game.pf.yapf.ship_use_yapf) {
+			_settings_game.pf.pathfinder_for_ships = VPF_YAPF;
 		} else {
-			_settings.pf.pathfinder_for_ships = (_settings.pf.new_pathfinding_all ? VPF_NPF : VPF_OPF);
+			_settings_game.pf.pathfinder_for_ships = (_settings_game.pf.new_pathfinding_all ? VPF_NPF : VPF_OPF);
 		}
 	}
 
--- a/src/openttd.h	Thu May 29 12:52:24 2008 +0000
+++ b/src/openttd.h	Thu May 29 15:56:32 2008 +0000
@@ -29,21 +29,6 @@
 	SM_LOAD_HEIGHTMAP  = 12,
 };
 
-
-/* Modes for GenerateWorld */
-enum GenerateWorldModes {
-	GW_NEWGAME   = 0,    /* Generate a map for a new game */
-	GW_EMPTY     = 1,    /* Generate an empty map (sea-level) */
-	GW_RANDOM    = 2,    /* Generate a random map for SE */
-	GW_HEIGHTMAP = 3,    /* Generate a newgame from a heightmap */
-};
-
-/* Modes for InitializeGame, those are _bits_! */
-enum InitializeGameModes {
-	IG_NONE       = 0,  /* Don't do anything special */
-	IG_DATE_RESET = 1,  /* Reset the date when initializing a game */
-};
-
 /* Display Options */
 enum {
 	DO_SHOW_TOWN_NAMES    = 0,
@@ -54,26 +39,6 @@
 	DO_WAYPOINTS          = 6,
 };
 
-enum {
-	SORT_ASCENDING  = 0,
-	SORT_DESCENDING = 1,
-	SORT_BY_DATE    = 0,
-	SORT_BY_NAME    = 2
-};
-
-extern byte _savegame_sort_order;
-
-/* In certain windows you navigate with the arrow keys. Do not scroll the
- * gameview when here. Bitencoded variable that only allows scrolling if all
- * elements are zero */
-enum {
-	SCROLL_CON  = 0,
-	SCROLL_EDIT = 1,
-	SCROLL_SAVE = 2,
-	SCROLL_CHAT = 4,
-};
-extern byte _no_scroll;
-
 extern byte _game_mode;
 extern bool _exit_game;
 extern int8 _pause_game;
--- a/src/order_cmd.cpp	Thu May 29 12:52:24 2008 +0000
+++ b/src/order_cmd.cpp	Thu May 29 15:56:32 2008 +0000
@@ -156,7 +156,7 @@
 	this->flags = 0;
 
 	/* First handle non-stop */
-	if (_settings.gui.sg_new_nonstop) {
+	if (_settings_client.gui.sg_new_nonstop) {
 		/* OFB_NON_STOP */
 		this->SetNonStopType((old_flags & 8) ? ONSF_NO_STOP_AT_ANY_STATION : ONSF_NO_STOP_AT_INTERMEDIATE_STATIONS);
 	} else {
@@ -176,7 +176,7 @@
 		} else if ((old_flags & 4) == 0) { // !OFB_FULL_LOAD
 			this->SetLoadType(OLF_LOAD_IF_POSSIBLE);
 		} else {
-			this->SetLoadType(_settings.gui.sg_full_load_any ? OLF_FULL_LOAD_ANY : OLFB_FULL_LOAD);
+			this->SetLoadType(_settings_client.gui.sg_full_load_any ? OLF_FULL_LOAD_ANY : OLFB_FULL_LOAD);
 		}
 
 		/* Finally fix the unload flags */
@@ -455,7 +455,7 @@
 
 	if (!HasOrderPoolFree(1)) return_cmd_error(STR_8831_NO_MORE_SPACE_FOR_ORDERS);
 
-	if (v->type == VEH_SHIP && IsHumanPlayer(v->owner) && _settings.pf.pathfinder_for_ships != VPF_NPF) {
+	if (v->type == VEH_SHIP && IsHumanPlayer(v->owner) && _settings_game.pf.pathfinder_for_ships != VPF_NPF) {
 		/* Make sure the new destination is not too far away from the previous */
 		const Order *prev = NULL;
 		uint n = 0;
@@ -1277,7 +1277,7 @@
 			}
 
 			/* Copy timetable if enabled */
-			if (_settings.order.timetabling && !DoCommandP(0, v->index | (i << 16) | (1 << 25),
+			if (_settings_game.order.timetabling && !DoCommandP(0, v->index | (i << 16) | (1 << 25),
 					bak->order[i].wait_time << 16 | bak->order[i].travel_time, NULL,
 					CMD_CHANGE_TIMETABLE | CMD_NO_TEST_IF_IN_NETWORK)) {
 				break;
@@ -1390,13 +1390,13 @@
 void CheckOrders(const Vehicle* v)
 {
 	/* Does the user wants us to check things? */
-	if (_settings.gui.order_review_system == 0) return;
+	if (_settings_client.gui.order_review_system == 0) return;
 
 	/* Do nothing for crashed vehicles */
 	if (v->vehstatus & VS_CRASHED) return;
 
 	/* Do nothing for stopped vehicles if setting is '1' */
-	if (_settings.gui.order_review_system == 1 && v->vehstatus & VS_STOPPED)
+	if (_settings_client.gui.order_review_system == 1 && v->vehstatus & VS_STOPPED)
 		return;
 
 	/* do nothing we we're not the first vehicle in a share-chain */
@@ -1575,7 +1575,7 @@
 
 Date GetServiceIntervalClamped(uint index)
 {
-	return (_settings.vehicle.servint_ispercent) ? Clamp(index, MIN_SERVINT_PERCENT, MAX_SERVINT_PERCENT) : Clamp(index, MIN_SERVINT_DAYS, MAX_SERVINT_DAYS);
+	return (_settings_game.vehicle.servint_ispercent) ? Clamp(index, MIN_SERVINT_PERCENT, MAX_SERVINT_PERCENT) : Clamp(index, MIN_SERVINT_DAYS, MAX_SERVINT_DAYS);
 }
 
 /**
@@ -1836,7 +1836,7 @@
 	if (CheckSavegameVersionOldStyle(5, 2)) {
 		/* Version older than 5.2 did not have a ->next pointer. Convert them
 		    (in the old days, the orderlist was 5000 items big) */
-		uint len = SlGetFieldLength();
+		size_t len = SlGetFieldLength();
 		uint i;
 
 		if (CheckSavegameVersion(5)) {
--- a/src/order_gui.cpp	Thu May 29 12:52:24 2008 +0000
+++ b/src/order_gui.cpp	Thu May 29 15:56:32 2008 +0000
@@ -265,13 +265,13 @@
 	order.index = 0;
 
 	/* check depot first */
-	if (_settings.order.gotodepot) {
+	if (_settings_game.order.gotodepot) {
 		switch (GetTileType(tile)) {
 			case MP_RAILWAY:
 				if (v->type == VEH_TRAIN && IsTileOwner(tile, _local_player)) {
 					if (IsRailDepot(tile)) {
 						order.MakeGoToDepot(GetDepotByTile(tile)->index, ODTFB_PART_OF_ORDERS);
-						if (_settings.gui.new_nonstop) order.SetNonStopType(ONSF_NO_STOP_AT_INTERMEDIATE_STATIONS);
+						if (_settings_client.gui.new_nonstop) order.SetNonStopType(ONSF_NO_STOP_AT_INTERMEDIATE_STATIONS);
 						return order;
 					}
 				}
@@ -280,7 +280,7 @@
 			case MP_ROAD:
 				if (IsRoadDepot(tile) && v->type == VEH_ROAD && IsTileOwner(tile, _local_player)) {
 					order.MakeGoToDepot(GetDepotByTile(tile)->index, ODTFB_PART_OF_ORDERS);
-					if (_settings.gui.new_nonstop) order.SetNonStopType(ONSF_NO_STOP_AT_INTERMEDIATE_STATIONS);
+					if (_settings_client.gui.new_nonstop) order.SetNonStopType(ONSF_NO_STOP_AT_INTERMEDIATE_STATIONS);
 					return order;
 				}
 				break;
@@ -313,7 +313,7 @@
 			IsTileOwner(tile, _local_player) &&
 			IsRailWaypoint(tile)) {
 		order.MakeGoToWaypoint(GetWaypointByTile(tile)->index);
-		if (_settings.gui.new_nonstop) order.SetNonStopType(ONSF_NO_STOP_AT_INTERMEDIATE_STATIONS);
+		if (_settings_client.gui.new_nonstop) order.SetNonStopType(ONSF_NO_STOP_AT_INTERMEDIATE_STATIONS);
 		return order;
 	}
 
@@ -330,7 +330,7 @@
 			(facil = FACIL_TRUCK_STOP, 1);
 			if (st->facilities & facil) {
 				order.MakeGoToStation(st_index);
-				if (_settings.gui.new_nonstop && (v->type == VEH_TRAIN || v->type == VEH_ROAD)) order.SetNonStopType(ONSF_NO_STOP_AT_INTERMEDIATE_STATIONS);
+				if (_settings_client.gui.new_nonstop && (v->type == VEH_TRAIN || v->type == VEH_ROAD)) order.SetNonStopType(ONSF_NO_STOP_AT_INTERMEDIATE_STATIONS);
 				return order;
 			}
 		}
@@ -611,7 +611,7 @@
 		this->resize.step_height = 10;
 		this->selected_order = -1;
 		this->vehicle = v;
-		if (_settings.order.timetabling) {
+		if (_settings_game.order.timetabling) {
 			this->widget[ORDER_WIDGET_CAPTION].right -= 61;
 		} else {
 			this->HideWidget(ORDER_WIDGET_TIMETABLE_VIEW);
--- a/src/osk_gui.cpp	Thu May 29 12:52:24 2008 +0000
+++ b/src/osk_gui.cpp	Thu May 29 15:56:32 2008 +0000
@@ -203,6 +203,11 @@
 		/* make the caret of the parent window also blink */
 		this->parent->InvalidateWidget(this->text_btn);
 	}
+
+	virtual void OnInvalidateData(int)
+	{
+		this->InvalidateWidget(OSK_WIDGET_TEXT);
+	}
 };
 
 static const Widget _osk_widgets[] = {
--- a/src/pathfind.cpp	Thu May 29 12:52:24 2008 +0000
+++ b/src/pathfind.cpp	Thu May 29 15:56:32 2008 +0000
@@ -778,7 +778,7 @@
 	tpf->enum_proc = enum_proc;
 	tpf->tracktype = TRANSPORT_RAIL;
 	tpf->railtypes = railtypes;
-	tpf->maxlength = min(_settings.pf.opf.pf_maxlength * 3, 10000);
+	tpf->maxlength = min(_settings_game.pf.opf.pf_maxlength * 3, 10000);
 	tpf->nstack = 0;
 	tpf->new_link = tpf->links;
 	tpf->num_links_left = lengthof(tpf->links);
--- a/src/player_gui.cpp	Thu May 29 12:52:24 2008 +0000
+++ b/src/player_gui.cpp	Thu May 29 15:56:32 2008 +0000
@@ -1191,7 +1191,7 @@
 		this->SetWidgetHiddenState(PCW_WIDGET_COMPANY_PASSWORD, !local || !_networking);
 
 		if (!local) {
-			if (_settings.economy.allow_shares) { // Shares are allowed
+			if (_settings_game.economy.allow_shares) { // Shares are allowed
 				/* If all shares are owned by someone (none by nobody), disable buy button */
 				this->SetWidgetDisabledState(PCW_WIDGET_BUY_SHARE, GetAmountOwnedBy(p, PLAYER_SPECTATOR) == 0 ||
 						/* Only 25% left to buy. If the player is human, disable buying it up.. TODO issues! */
@@ -1304,10 +1304,10 @@
 		}
 	}
 
-	virtual void OnTick()
+	virtual void OnHundredthTick()
 	{
 		/* redraw the window every now and then */
-		if ((++this->vscroll.pos & 0x1F) == 0) this->SetDirty();
+		this->SetDirty();
 	}
 
 	virtual void OnPlaceObject(Point pt, TileIndex tile)
@@ -1477,7 +1477,7 @@
 		} else {
 			/* in single player _local player is always valid */
 			const Player *p = GetPlayer(_local_player);
-			this->window_number = _settings.difficulty.diff_level;
+			this->window_number = _settings_game.difficulty.diff_level;
 			this->rank = SaveHighScoreValue(p);
 		}
 
@@ -1545,7 +1545,7 @@
 
 		this->SetupHighScoreEndWindow(&x, &y);
 
-		SetDParam(0, _settings.gui.ending_year);
+		SetDParam(0, _settings_client.gui.ending_year);
 		SetDParam(1, this->window_number + STR_6801_EASY);
 		DrawStringMultiCenter(x + (640 / 2), y + 62, !_networking ? STR_0211_TOP_COMPANIES_WHO_REACHED : STR_TOP_COMPANIES_NETWORK_GAME, 500);
 
--- a/src/players.cpp	Thu May 29 12:52:24 2008 +0000
+++ b/src/players.cpp	Thu May 29 15:56:32 2008 +0000
@@ -64,9 +64,9 @@
 	/* Do not update the patches if we are in the intro GUI */
 	if (IsValidPlayer(new_player) && _game_mode != GM_MENU) {
 		const Player *p = GetPlayer(new_player);
-		_settings.gui.autorenew        = p->engine_renew;
-		_settings.gui.autorenew_months = p->engine_renew_months;
-		_settings.gui.autorenew_money  = p->engine_renew_money;
+		_settings_client.gui.autorenew        = p->engine_renew;
+		_settings_client.gui.autorenew_months = p->engine_renew_months;
+		_settings_client.gui.autorenew_money  = p->engine_renew_money;
 		InvalidateWindow(WC_GAME_OPTIONS, 0);
 	}
 }
@@ -540,9 +540,9 @@
 	/* Engine renewal settings */
 	p->engine_renew_list = NULL;
 	p->renew_keep_length = false;
-	p->engine_renew = _settings_newgame.gui.autorenew;
-	p->engine_renew_months = _settings_newgame.gui.autorenew_months;
-	p->engine_renew_money = _settings_newgame.gui.autorenew_money;
+	p->engine_renew = _settings_client.gui.autorenew;
+	p->engine_renew_months = _settings_client.gui.autorenew_months;
+	p->engine_renew_money = _settings_client.gui.autorenew_money;
 
 	GeneratePresidentName(p);
 
@@ -561,7 +561,7 @@
 void StartupPlayers()
 {
 	/* The AI starts like in the setting with +2 month max */
-	_next_competitor_start = _settings.difficulty.competitor_start_time * 90 * DAY_TICKS + RandomRange(60 * DAY_TICKS) + 1;
+	_next_competitor_start = _settings_game.difficulty.competitor_start_time * 90 * DAY_TICKS + RandomRange(60 * DAY_TICKS) + 1;
 }
 
 static void MaybeStartNewPlayer()
@@ -576,10 +576,10 @@
 	}
 
 	/* when there's a lot of computers in game, the probability that a new one starts is lower */
-	if (n < (uint)_settings.difficulty.max_no_competitors &&
+	if (n < (uint)_settings_game.difficulty.max_no_competitors &&
 			n < (_network_server ?
-				InteractiveRandomRange(_settings.difficulty.max_no_competitors + 2) :
-				RandomRange(_settings.difficulty.max_no_competitors + 2)
+				InteractiveRandomRange(_settings_game.difficulty.max_no_competitors + 2) :
+				RandomRange(_settings_game.difficulty.max_no_competitors + 2)
 			)) {
 		/* Send a command to all clients to start up a new AI.
 		 * Works fine for Multiplayer and Singleplayer */
@@ -587,7 +587,7 @@
 	}
 
 	/* The next AI starts like the difficulty setting said, with +2 month max */
-	_next_competitor_start = _settings.difficulty.competitor_start_time * 90 * DAY_TICKS + 1;
+	_next_competitor_start = _settings_game.difficulty.competitor_start_time * 90 * DAY_TICKS + 1;
 	_next_competitor_start += _network_server ? InteractiveRandomRange(60 * DAY_TICKS) : RandomRange(60 * DAY_TICKS);
 }
 
@@ -628,7 +628,7 @@
 		}
 	}
 
-	if (_settings.gui.show_finances && _local_player != PLAYER_SPECTATOR) {
+	if (_settings_client.gui.show_finances && _local_player != PLAYER_SPECTATOR) {
 		ShowPlayerFinances(_local_player);
 		p = GetPlayer(_local_player);
 		if (p->num_valid_stat_ent > 5 && p->old_economy[0].performance_history < p->old_economy[4].performance_history) {
@@ -693,7 +693,7 @@
 			if (flags & DC_EXEC) {
 				p->engine_renew = HasBit(p2, 0);
 				if (IsLocalPlayer()) {
-					_settings.gui.autorenew = p->engine_renew;
+					_settings_client.gui.autorenew = p->engine_renew;
 					InvalidateWindow(WC_GAME_OPTIONS, 0);
 				}
 			}
@@ -706,7 +706,7 @@
 			if (flags & DC_EXEC) {
 				p->engine_renew_months = (int16)p2;
 				if (IsLocalPlayer()) {
-					_settings.gui.autorenew_months = p->engine_renew_months;
+					_settings_client.gui.autorenew_months = p->engine_renew_months;
 					InvalidateWindow(WC_GAME_OPTIONS, 0);
 				}
 			}
@@ -719,7 +719,7 @@
 			if (flags & DC_EXEC) {
 				p->engine_renew_money = p2;
 				if (IsLocalPlayer()) {
-					_settings.gui.autorenew_money = p->engine_renew_money;
+					_settings_client.gui.autorenew_money = p->engine_renew_money;
 					InvalidateWindow(WC_GAME_OPTIONS, 0);
 				}
 			}
@@ -769,9 +769,9 @@
 				p->engine_renew_money = p2;
 
 				if (IsLocalPlayer()) {
-					_settings.gui.autorenew = p->engine_renew;
-					_settings.gui.autorenew_months = p->engine_renew_months;
-					_settings.gui.autorenew_money = p->engine_renew_money;
+					_settings_client.gui.autorenew = p->engine_renew;
+					_settings_client.gui.autorenew_months = p->engine_renew_months;
+					_settings_client.gui.autorenew_money = p->engine_renew_money;
 					InvalidateWindow(WC_GAME_OPTIONS, 0);
 				}
 			}
@@ -874,8 +874,8 @@
 		/* Now that we have a new player, broadcast its autorenew settings to
 		 * all clients so everything is in sync */
 		DoCommand(0,
-			(_settings.gui.autorenew << 15 ) | (_settings.gui.autorenew_months << 16) | 4,
-			_settings.gui.autorenew_money,
+			(_settings_client.gui.autorenew << 15 ) | (_settings_client.gui.autorenew_months << 16) | 4,
+			_settings_client.gui.autorenew_money,
 			DC_EXEC,
 			CMD_SET_AUTOREPLACE
 		);
@@ -994,7 +994,7 @@
 /** Save the highscore for the player */
 int8 SaveHighScoreValue(const Player *p)
 {
-	HighScore *hs = _highscore_table[_settings.difficulty.diff_level];
+	HighScore *hs = _highscore_table[_settings_game.difficulty.diff_level];
 	uint i;
 	uint16 score = p->old_economy[0].performance_history;
 
@@ -1122,7 +1122,7 @@
 	}
 
 	/* Initialize end of game variable (when to show highscore chart) */
-	_settings.gui.ending_year = 2051;
+	_settings_client.gui.ending_year = 2051;
 }
 
 /* Save/load of players */
--- a/src/rail.cpp	Thu May 29 12:52:24 2008 +0000
+++ b/src/rail.cpp	Thu May 29 15:56:32 2008 +0000
@@ -207,7 +207,7 @@
 	FOR_ALL_ENGINES_OF_TYPE(e, VEH_TRAIN) {
 		const EngineInfo *ei = &e->info;
 
-		if (HasBit(ei->climates, _settings.game_creation.landscape) &&
+		if (HasBit(ei->climates, _settings_game.game_creation.landscape) &&
 				(HasBit(e->player_avail, p) || _date >= e->intro_date + 365)) {
 			const RailVehicleInfo *rvi = &e->u.rail;
 
--- a/src/rail_cmd.cpp	Thu May 29 12:52:24 2008 +0000
+++ b/src/rail_cmd.cpp	Thu May 29 15:56:32 2008 +0000
@@ -292,7 +292,7 @@
 
 	/* check track/slope combination */
 	if ((f_new == FOUNDATION_INVALID) ||
-	    ((f_new != FOUNDATION_NONE) && (!_settings.construction.build_on_slopes))
+	    ((f_new != FOUNDATION_NONE) && (!_settings_game.construction.build_on_slopes))
 	   ) return_cmd_error(STR_1000_LAND_SLOPED_IN_WRONG_DIRECTION);
 
 	Foundation f_old = GetRailFoundation(tileh, existing);
@@ -755,7 +755,7 @@
 	 */
 
 	if (tileh != SLOPE_FLAT && (
-				!_settings.construction.build_on_slopes ||
+				!_settings_game.construction.build_on_slopes ||
 				IsSteepSlope(tileh) ||
 				!CanBuildDepotByTileh(dir, tileh)
 			)) {
@@ -1223,7 +1223,7 @@
 			RailType type = GetRailType(tile);
 
 			/* Converting to the same type or converting 'hidden' elrail -> rail */
-			if (type == totype || (_settings.vehicle.disable_elrails && totype == RAILTYPE_RAIL && type == RAILTYPE_ELECTRIC)) continue;
+			if (type == totype || (_settings_game.vehicle.disable_elrails && totype == RAILTYPE_RAIL && type == RAILTYPE_ELECTRIC)) continue;
 
 			/* Trying to convert other's rail */
 			if (!CheckTileOwnership(tile)) continue;
@@ -1419,7 +1419,7 @@
 
 static void DrawSingleSignal(TileIndex tile, Track track, byte condition, uint image, uint pos)
 {
-	bool side = (_settings.vehicle.road_side != 0) && _settings.construction.signal_side;
+	bool side = (_settings_game.vehicle.road_side != 0) && _settings_game.construction.signal_side;
 	static const Point SignalPositions[2][12] = {
 		{      /* Signals on the left side */
 		/*  LEFT      LEFT      RIGHT     RIGHT     UPPER     UPPER */
@@ -1788,7 +1788,7 @@
 
 			/* adjust ground tile for desert
 			 * don't adjust for snow, because snow in depots looks weird */
-			if (IsSnowRailGround(ti->tile) && _settings.game_creation.landscape == LT_TROPIC) {
+			if (IsSnowRailGround(ti->tile) && _settings_game.game_creation.landscape == LT_TROPIC) {
 				if (image != SPR_FLAT_GRASS_TILE) {
 					image += rti->snow_offset; // tile with tracks
 				} else {
@@ -1952,7 +1952,7 @@
 		return;
 	}
 
-	switch (_settings.game_creation.landscape) {
+	switch (_settings_game.game_creation.landscape) {
 		case LT_ARCTIC: {
 			uint z;
 			Slope slope = GetTileSlope(tile, &z);
@@ -2328,7 +2328,7 @@
  */
 static CommandCost TestAutoslopeOnRailTile(TileIndex tile, uint flags, uint z_old, Slope tileh_old, uint z_new, Slope tileh_new, TrackBits rail_bits)
 {
-	if (!_settings.construction.build_on_slopes || !AutoslopeEnabled()) return CMD_ERROR;
+	if (!_settings_game.construction.build_on_slopes || !AutoslopeEnabled()) return CMD_ERROR;
 
 	/* Is the slope-rail_bits combination valid in general? I.e. is it save to call GetRailFoundation() ? */
 	if (CmdFailed(CheckRailSlope(tileh_new, rail_bits, TRACK_BIT_NONE, tile))) return CMD_ERROR;
@@ -2404,7 +2404,7 @@
 		/* allow terraforming */
 		return CommandCost(EXPENSES_CONSTRUCTION, was_water ? _price.clear_water : (Money)0);
 	} else {
-		if (_settings.construction.build_on_slopes && AutoslopeEnabled()) {
+		if (_settings_game.construction.build_on_slopes && AutoslopeEnabled()) {
 			switch (GetRailTileType(tile)) {
 				case RAIL_TILE_WAYPOINT: {
 					CommandCost cost = TestAutoslopeOnRailTile(tile, flags, z_old, tileh_old, z_new, tileh_new, GetRailWaypointBits(tile));
--- a/src/rail_gui.cpp	Thu May 29 12:52:24 2008 +0000
+++ b/src/rail_gui.cpp	Thu May 29 15:56:32 2008 +0000
@@ -182,7 +182,7 @@
 		VpSetPlaceSizingLimit(-1);
 	} else if (_railstation.dragdrop) {
 		VpStartPlaceSizing(tile, VPM_X_AND_Y_LIMITED, DDSP_BUILD_STATION);
-		VpSetPlaceSizingLimit(_settings.station.station_spread);
+		VpSetPlaceSizingLimit(_settings_game.station.station_spread);
 	} else {
 		DoCommandP(tile,
 				_railstation.orientation | (_railstation.numtracks << 8) | (_railstation.platlength << 16) | (_ctrl_pressed << 24),
@@ -227,7 +227,7 @@
 			SB(p1, 7, 1, _convert_signal_button);
 		} else {
 			SB(p1, 3, 1, _ctrl_pressed);
-			SB(p1, 4, 1, (_cur_year < _settings.gui.semaphore_build_before ? SIG_SEMAPHORE : SIG_ELECTRIC));
+			SB(p1, 4, 1, (_cur_year < _settings_client.gui.semaphore_build_before ? SIG_SEMAPHORE : SIG_ELECTRIC));
 			SB(p1, 5, 2, SIGTYPE_NORMAL);
 			SB(p1, 7, 1, 0);
 		}
@@ -429,7 +429,7 @@
  */
 static void BuildRailClick_AutoSignals(Window *w)
 {
-	if (_settings.gui.enable_signal_gui != _ctrl_pressed) {
+	if (_settings_client.gui.enable_signal_gui != _ctrl_pressed) {
 		if (HandlePlacePushButton(w, RTW_BUILD_SIGNALS, ANIMCURSOR_BUILDSIGNALS, VHM_RECT, PlaceRail_AutoSignals)) ShowSignalBuilder(w);
 	} else {
 		HandlePlacePushButton(w, RTW_BUILD_SIGNALS, ANIMCURSOR_BUILDSIGNALS, VHM_RECT, PlaceRail_AutoSignals);
@@ -484,7 +484,7 @@
 				if (_railstation.orientation == 0) Swap(x, y);
 				SetTileSelectSize(x, y);
 			} else {
-				VpSetPlaceSizingLimit(_settings.station.station_spread);
+				VpSetPlaceSizingLimit(_settings_game.station.station_spread);
 			}
 		}
 	}
@@ -547,15 +547,15 @@
 		SB(p2,  3, 1, 0);
 		SB(p2,  4, 1, _cur_signal_variant);
 		SB(p2,  6, 1, _ctrl_pressed);
-		SB(p2, 24, 8, _settings.gui.drag_signals_density);
+		SB(p2, 24, 8, _settings_client.gui.drag_signals_density);
 	} else {
 		SB(p2,  3, 1, 0);
-		SB(p2,  4, 1, (_cur_year < _settings.gui.semaphore_build_before ? SIG_SEMAPHORE : SIG_ELECTRIC));
+		SB(p2,  4, 1, (_cur_year < _settings_client.gui.semaphore_build_before ? SIG_SEMAPHORE : SIG_ELECTRIC));
 		SB(p2,  6, 1, _ctrl_pressed);
-		SB(p2, 24, 8, _settings.gui.drag_signals_density);
+		SB(p2, 24, 8, _settings_client.gui.drag_signals_density);
 	}
 
-	/* _settings.gui.drag_signals_density is given as a parameter such that each user
+	/* _settings_client.gui.drag_signals_density is given as a parameter such that each user
 	 * in a network game can specify his/her own signal density */
 	DoCommandP(
 		TileVirtXY(thd->selstart.x, thd->selstart.y),
@@ -617,12 +617,12 @@
 		this->DisableWidget(RTW_REMOVE);
 
 		this->FindWindowPlacementAndResize(desc);
-		if (_settings.gui.link_terraform_toolbar) ShowTerraformToolbar(this);
+		if (_settings_client.gui.link_terraform_toolbar) ShowTerraformToolbar(this);
 	}
 
 	~BuildRailToolbarWindow()
 	{
-		if (_settings.gui.link_terraform_toolbar) DeleteWindowById(WC_SCEN_LAND_GEN, 0);
+		if (_settings_client.gui.link_terraform_toolbar) DeleteWindowById(WC_SCEN_LAND_GEN, 0);
 	}
 
 	void UpdateRemoveWidgetStatus(int clicked_widget)
@@ -1008,13 +1008,13 @@
 				SetTileSelectSize(x, y);
 		}
 
-		int rad = (_settings.station.modified_catchment) ? CA_TRAIN : CA_UNMODIFIED;
+		int rad = (_settings_game.station.modified_catchment) ? CA_TRAIN : CA_UNMODIFIED;
 
 		if (_station_show_coverage)
 			SetTileSelectBigSize(-rad, -rad, 2 * rad, 2 * rad);
 
 		for (uint bits = 0; bits < 7; bits++) {
-			bool disable = bits >= _settings.station.station_spread;
+			bool disable = bits >= _settings_game.station.station_spread;
 			if (statspec == NULL) {
 				this->SetWidgetDisabledState(bits + BRSW_PLATFORM_NUM_1, disable);
 				this->SetWidgetDisabledState(bits + BRSW_PLATFORM_LEN_1, disable);
@@ -1390,8 +1390,8 @@
 
 		this->SetWidgetLoweredState(BSW_CONVERT, _convert_signal_button);
 
-		this->SetWidgetDisabledState(BSW_DRAG_SIGNALS_DENSITY_DECREASE, _settings.gui.drag_signals_density == 1);
-		this->SetWidgetDisabledState(BSW_DRAG_SIGNALS_DENSITY_INCREASE, _settings.gui.drag_signals_density == 20);
+		this->SetWidgetDisabledState(BSW_DRAG_SIGNALS_DENSITY_DECREASE, _settings_client.gui.drag_signals_density == 1);
+		this->SetWidgetDisabledState(BSW_DRAG_SIGNALS_DENSITY_INCREASE, _settings_client.gui.drag_signals_density == 20);
 
 		this->DrawWidgets();
 
@@ -1406,7 +1406,7 @@
 		this->DrawSignalSprite(BSW_ELECTRIC_COMBO,  SPR_IMG_SIGNAL_ELECTRIC_COMBO,  -2,  6);
 
 		/* Draw dragging signal density value in the BSW_DRAG_SIGNALS_DENSITY widget */
-		SetDParam(0, _settings.gui.drag_signals_density);
+		SetDParam(0, _settings_client.gui.drag_signals_density);
 		DrawStringCentered(this->widget[BSW_DRAG_SIGNALS_DENSITY].left + (this->widget[BSW_DRAG_SIGNALS_DENSITY].right -
 				this->widget[BSW_DRAG_SIGNALS_DENSITY].left) / 2 + 1,
 				this->widget[BSW_DRAG_SIGNALS_DENSITY].top + 2, STR_JUST_INT, TC_ORANGE);
@@ -1434,15 +1434,15 @@
 				break;
 
 			case BSW_DRAG_SIGNALS_DENSITY_DECREASE:
-				if (_settings.gui.drag_signals_density > 1) {
-					_settings.gui.drag_signals_density--;
+				if (_settings_client.gui.drag_signals_density > 1) {
+					_settings_client.gui.drag_signals_density--;
 					SetWindowDirty(FindWindowById(WC_GAME_OPTIONS, 0));
 				}
 				break;
 
 			case BSW_DRAG_SIGNALS_DENSITY_INCREASE:
-				if (_settings.gui.drag_signals_density < 20) {
-					_settings.gui.drag_signals_density++;
+				if (_settings_client.gui.drag_signals_density < 20) {
+					_settings_client.gui.drag_signals_density++;
 					SetWindowDirty(FindWindowById(WC_GAME_OPTIONS, 0));
 				}
 				break;
@@ -1701,7 +1701,7 @@
 	if (_local_player == PLAYER_SPECTATOR || !IsValidPlayer(_local_player)) return;
 
 	extern RailType _last_built_railtype;
-	RailType rt = (RailType)_settings.gui.default_rail_type;
+	RailType rt = (RailType)_settings_client.gui.default_rail_type;
 	if (rt >= RAILTYPE_END) {
 		if (rt == RAILTYPE_END + 2) {
 			/* Find the most used rail type */
@@ -1753,7 +1753,7 @@
  */
 int32 ResetSignalVariant(int32 = 0)
 {
-	SignalVariant new_variant = (_cur_year < _settings.gui.semaphore_build_before ? SIG_SEMAPHORE : SIG_ELECTRIC);
+	SignalVariant new_variant = (_cur_year < _settings_client.gui.semaphore_build_before ? SIG_SEMAPHORE : SIG_ELECTRIC);
 
 	if (new_variant != _cur_signal_variant) {
 		Window *w = FindWindowById(WC_BUILD_SIGNAL, 0);
--- a/src/road.cpp	Thu May 29 12:52:24 2008 +0000
+++ b/src/road.cpp	Thu May 29 15:56:32 2008 +0000
@@ -103,7 +103,7 @@
 	FOR_ALL_ENGINES_OF_TYPE(e, VEH_ROAD) {
 		const EngineInfo *ei = &e->info;
 
-		if (HasBit(ei->climates, _settings.game_creation.landscape) &&
+		if (HasBit(ei->climates, _settings_game.game_creation.landscape) &&
 				(HasBit(e->player_avail, p) || _date >= e->intro_date + 365)) {
 			SetBit(rt, HasBit(ei->misc_flags, EF_ROAD_TRAM) ? ROADTYPE_TRAM : ROADTYPE_ROAD);
 		}
--- a/src/road_cmd.cpp	Thu May 29 12:52:24 2008 +0000
+++ b/src/road_cmd.cpp	Thu May 29 15:56:32 2008 +0000
@@ -69,9 +69,9 @@
 
 	if (flags & DC_EXEC) {
 		if (_game_mode == GM_MENU) {
-			_settings.vehicle.road_side = p1;
+			_settings_game.vehicle.road_side = p1;
 		} else {
-			_settings.vehicle.road_side = p1;
+			_settings_game.vehicle.road_side = p1;
 		}
 		InvalidateWindow(WC_GAME_OPTIONS, 0);
 	}
@@ -182,7 +182,7 @@
 	 * then allow it */
 	if (KillFirstBit(n) != ROAD_NONE && (n & remove) != ROAD_NONE) {
 		/* you can remove all kind of roads with extra dynamite */
-		if (!_settings.construction.extra_dynamite) {
+		if (!_settings_game.construction.extra_dynamite) {
 			SetDParam(0, t->index);
 			_error_message = STR_2009_LOCAL_AUTHORITY_REFUSES;
 			return false;
@@ -279,7 +279,7 @@
 			 * @li if build on slopes is disabled */
 			if (IsSteepSlope(tileh) || (IsStraightRoad(other) &&
 					(other & _invalid_tileh_slopes_road[0][tileh & SLOPE_ELEVATED]) != ROAD_NONE) ||
-					(tileh != SLOPE_FLAT && !_settings.construction.build_on_slopes)) {
+					(tileh != SLOPE_FLAT && !_settings_game.construction.build_on_slopes)) {
 				pieces |= MirrorRoadBits(pieces);
 			}
 
@@ -419,7 +419,7 @@
 	RoadBits type_bits = existing | *pieces;
 
 	/* Roads on slopes */
-	if (_settings.construction.build_on_slopes && (_invalid_tileh_slopes_road[0][tileh] & (other | type_bits)) == ROAD_NONE) {
+	if (_settings_game.construction.build_on_slopes && (_invalid_tileh_slopes_road[0][tileh] & (other | type_bits)) == ROAD_NONE) {
 
 		/* If we add leveling we've got to pay for it */
 		if ((other | existing) == ROAD_NONE) return CommandCost(EXPENSES_CONSTRUCTION, _price.terraform);
@@ -439,7 +439,7 @@
 		if (IsSlopeWithOneCornerRaised(tileh)) {
 
 			/* Prevent build on slopes if it isn't allowed */
-			if (_settings.construction.build_on_slopes) {
+			if (_settings_game.construction.build_on_slopes) {
 
 				/* If we add foundation we've got to pay for it */
 				if ((other | existing) == ROAD_NONE) return CommandCost(EXPENSES_CONSTRUCTION, _price.terraform);
@@ -594,7 +594,7 @@
 		CommandCost ret = CheckRoadSlope(tileh, &pieces, existing, other_bits);
 		/* Return an error if we need to build a foundation (ret != 0) but the
 		 * current patch-setting is turned off (or stupid AI@work) */
-		if (CmdFailed(ret) || (ret.GetCost() != 0 && !_settings.construction.build_on_slopes)) {
+		if (CmdFailed(ret) || (ret.GetCost() != 0 && !_settings_game.construction.build_on_slopes)) {
 			return_cmd_error(STR_1000_LAND_SLOPED_IN_WRONG_DIRECTION);
 		}
 		cost.AddCost(ret);
@@ -849,7 +849,7 @@
 
 	Slope tileh = GetTileSlope(tile, NULL);
 	if (tileh != SLOPE_FLAT && (
-				!_settings.construction.build_on_slopes ||
+				!_settings_game.construction.build_on_slopes ||
 				IsSteepSlope(tileh) ||
 				!CanBuildDepotByTileh(dir, tileh)
 			)) {
@@ -997,7 +997,7 @@
 static bool AlwaysDrawUnpavedRoads(TileIndex tile, Roadside roadside)
 {
 	return (IsOnSnow(tile) &&
-			!(_settings.game_creation.landscape == LT_TROPIC && HasGrfMiscBit(GMB_DESERT_PAVED_ROADS) &&
+			!(_settings_game.game_creation.landscape == LT_TROPIC && HasGrfMiscBit(GMB_DESERT_PAVED_ROADS) &&
 				roadside != ROADSIDE_BARREN && roadside != ROADSIDE_GRASS && roadside != ROADSIDE_GRASS_ROAD_WORKS));
 }
 
@@ -1288,7 +1288,7 @@
 
 static void TileLoop_Road(TileIndex tile)
 {
-	switch (_settings.game_creation.landscape) {
+	switch (_settings_game.game_creation.landscape) {
 		case LT_ARCTIC:
 			if (IsOnSnow(tile) != (GetTileZ(tile) > GetSnowLine())) {
 				ToggleSnow(tile);
@@ -1334,7 +1334,7 @@
 
 		{
 			/* Adjust road ground type depending on 'grp' (grp is the distance to the center) */
-			const Roadside* new_rs = (_settings.game_creation.landscape == LT_TOYLAND) ? _town_road_types_2[grp] : _town_road_types[grp];
+			const Roadside* new_rs = (_settings_game.game_creation.landscape == LT_TOYLAND) ? _town_road_types_2[grp] : _town_road_types[grp];
 			Roadside cur_rs = GetRoadside(tile);
 
 			/* We have our desired type, do nothing */
@@ -1356,7 +1356,7 @@
 	} else if (IncreaseRoadWorksCounter(tile)) {
 		TerminateRoadWorks(tile);
 
-		if (_settings.economy.mod_road_rebuild) {
+		if (_settings_game.economy.mod_road_rebuild) {
 			/* Generate a nicer town surface */
 			const RoadBits old_rb = GetAnyRoadBits(tile, ROADTYPE_ROAD);
 			const RoadBits new_rb = CleanUpRoadBits(tile, old_rb);
@@ -1567,7 +1567,7 @@
 
 static CommandCost TerraformTile_Road(TileIndex tile, uint32 flags, uint z_new, Slope tileh_new)
 {
-	if (_settings.construction.build_on_slopes && AutoslopeEnabled()) {
+	if (_settings_game.construction.build_on_slopes && AutoslopeEnabled()) {
 		switch (GetRoadTileType(tile)) {
 			case ROAD_TILE_CROSSING:
 				if (!IsSteepSlope(tileh_new) && (GetTileMaxZ(tile) == z_new + GetSlopeMaxZ(tileh_new)) && HasBit(VALID_LEVEL_CROSSING_SLOPES, tileh_new)) return CommandCost(EXPENSES_CONSTRUCTION, _price.terraform);
--- a/src/road_gui.cpp	Thu May 29 12:52:24 2008 +0000
+++ b/src/road_gui.cpp	Thu May 29 15:56:32 2008 +0000
@@ -409,12 +409,12 @@
 			WIDGET_LIST_END);
 
 		this->FindWindowPlacementAndResize(desc);
-		if (_settings.gui.link_terraform_toolbar) ShowTerraformToolbar(this);
+		if (_settings_client.gui.link_terraform_toolbar) ShowTerraformToolbar(this);
 	}
 
 	~BuildRoadToolbarWindow()
 	{
-		if (_settings.gui.link_terraform_toolbar) DeleteWindowById(WC_SCEN_LAND_GEN, 0);
+		if (_settings_client.gui.link_terraform_toolbar) DeleteWindowById(WC_SCEN_LAND_GEN, 0);
 	}
 
 	/**
@@ -839,7 +839,7 @@
 		this->DrawWidgets();
 
 		if (_station_show_coverage) {
-			int rad = _settings.station.modified_catchment ? CA_TRUCK /* = CA_BUS */ : CA_UNMODIFIED;
+			int rad = _settings_game.station.modified_catchment ? CA_TRUCK /* = CA_BUS */ : CA_UNMODIFIED;
 			SetTileSelectBigSize(-rad, -rad, 2 * rad, 2 * rad);
 		} else {
 			SetTileSelectSize(1, 1);
--- a/src/roadveh_cmd.cpp	Thu May 29 12:52:24 2008 +0000
+++ b/src/roadveh_cmd.cpp	Thu May 29 15:56:32 2008 +0000
@@ -206,7 +206,7 @@
 
 	/* find the first free roadveh id */
 	unit_num = HasBit(p2, 0) ? 0 : GetFreeUnitNumber(VEH_ROAD);
-	if (unit_num > _settings.vehicle.max_roadveh)
+	if (unit_num > _settings_game.vehicle.max_roadveh)
 		return_cmd_error(STR_00E1_TOO_MANY_VEHICLES_IN_GAME);
 
 	if (flags & DC_EXEC) {
@@ -258,7 +258,7 @@
 
 		v->name = NULL;
 
-		v->service_interval = _settings.vehicle.servint_roadveh;
+		v->service_interval = _settings_game.vehicle.servint_roadveh;
 
 		v->date_of_last_service = _date;
 		v->build_year = _cur_year;
@@ -420,7 +420,7 @@
 
 static const Depot* FindClosestRoadDepot(const Vehicle* v)
 {
-	switch (_settings.pf.pathfinder_for_roadvehs) {
+	switch (_settings_game.pf.pathfinder_for_roadvehs) {
 		case VPF_YAPF: /* YAPF */
 			return YapfFindNearestRoadDepot(v);
 
@@ -705,7 +705,7 @@
 		InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
 
 		if (!PlayVehicleSound(v, VSE_BREAKDOWN)) {
-			SndPlayVehicleFx((_settings.game_creation.landscape != LT_TOYLAND) ?
+			SndPlayVehicleFx((_settings_game.game_creation.landscape != LT_TOYLAND) ?
 				SND_0F_VEHICLE_BREAKDOWN : SND_35_COMEDY_BREAKDOWN, v);
 		}
 
@@ -866,7 +866,7 @@
 	/* updates statusbar only if speed have changed to save CPU time */
 	if (spd != v->cur_speed) {
 		v->cur_speed = spd;
-		if (_settings.gui.vehicle_speed) {
+		if (_settings_client.gui.vehicle_speed) {
 			InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
 		}
 	}
@@ -1088,7 +1088,7 @@
 				trackdirs = TRACKDIR_BIT_NONE;
 			} else {
 				/* Proper station type, check if there is free loading bay */
-				if (!_settings.pf.roadveh_queue && IsStandardRoadStopTile(tile) &&
+				if (!_settings_game.pf.roadveh_queue && IsStandardRoadStopTile(tile) &&
 						!GetRoadStopByTile(tile, rstype)->HasFreeBay()) {
 					/* Station is full and RV queuing is off */
 					trackdirs = TRACKDIR_BIT_NONE;
@@ -1127,7 +1127,7 @@
 		return_track(FindFirstBit2x64(trackdirs));
 	}
 
-	switch (_settings.pf.pathfinder_for_roadvehs) {
+	switch (_settings_game.pf.pathfinder_for_roadvehs) {
 		case VPF_YAPF: { /* YAPF */
 			Trackdir trackdir = YapfChooseRoadTrack(v, tile, enterdir);
 			if (trackdir != INVALID_TRACKDIR) return_track(trackdir);
@@ -1214,7 +1214,7 @@
 
 static uint RoadFindPathToStop(const Vehicle *v, TileIndex tile)
 {
-	if (_settings.pf.pathfinder_for_roadvehs == VPF_YAPF) {
+	if (_settings_game.pf.pathfinder_for_roadvehs == VPF_YAPF) {
 		/* use YAPF */
 		return YapfRoadVehDistanceToTile(v, tile);
 	}
@@ -1276,7 +1276,7 @@
 	v->direction = DiagDirToDir(dir);
 
 	Trackdir tdir = _roadveh_depot_exit_trackdir[dir];
-	const RoadDriveEntry *rdp = _road_drive_data[v->u.road.roadtype][(_settings.vehicle.road_side << RVS_DRIVE_SIDE) + tdir];
+	const RoadDriveEntry *rdp = _road_drive_data[v->u.road.roadtype][(_settings_game.vehicle.road_side << RVS_DRIVE_SIDE) + tdir];
 
 	int x = TileX(v->tile) * TILE_SIZE + (rdp[RVC_DEPOT_START_FRAME].x & 0xF);
 	int y = TileY(v->tile) * TILE_SIZE + (rdp[RVC_DEPOT_START_FRAME].y & 0xF);
@@ -1454,7 +1454,7 @@
 	 * In this case v->u.road.state is masked to give the road stop entry direction. */
 	rd = _road_drive_data[v->u.road.roadtype][(
 		(HasBit(v->u.road.state, RVS_IN_DT_ROAD_STOP) ? v->u.road.state & RVSB_ROAD_STOP_TRACKDIR_MASK : v->u.road.state) +
-		(_settings.vehicle.road_side << RVS_DRIVE_SIDE)) ^ v->u.road.overtaking][v->u.road.frame + 1];
+		(_settings_game.vehicle.road_side << RVS_DRIVE_SIDE)) ^ v->u.road.overtaking][v->u.road.frame + 1];
 
 	if (rd.x & RDE_NEXT_TILE) {
 		TileIndex tile = v->tile + TileOffsByDiagDir((DiagDirection)(rd.x & 3));
@@ -1532,7 +1532,7 @@
 		}
 
 		/* Get position data for first frame on the new tile */
-		rdp = _road_drive_data[v->u.road.roadtype][(dir + (_settings.vehicle.road_side << RVS_DRIVE_SIDE)) ^ v->u.road.overtaking];
+		rdp = _road_drive_data[v->u.road.roadtype][(dir + (_settings_game.vehicle.road_side << RVS_DRIVE_SIDE)) ^ v->u.road.overtaking];
 
 		x = TileX(tile) * TILE_SIZE + rdp[start_frame].x;
 		y = TileY(tile) * TILE_SIZE + rdp[start_frame].y;
@@ -1635,7 +1635,7 @@
 			return false;
 		}
 
-		rdp = _road_drive_data[v->u.road.roadtype][(_settings.vehicle.road_side << RVS_DRIVE_SIDE) + dir];
+		rdp = _road_drive_data[v->u.road.roadtype][(_settings_game.vehicle.road_side << RVS_DRIVE_SIDE) + dir];
 
 		x = TileX(v->tile) * TILE_SIZE + rdp[turn_around_start_frame].x;
 		y = TileY(v->tile) * TILE_SIZE + rdp[turn_around_start_frame].y;
@@ -1714,7 +1714,7 @@
 	 * (the station test and stop type test ensure that other vehicles, using the road stop as
 	 * a through route, do not stop) */
 	if (IsRoadVehFront(v) && ((IsInsideMM(v->u.road.state, RVSB_IN_ROAD_STOP, RVSB_IN_ROAD_STOP_END) &&
-			_road_veh_data_1[v->u.road.state - RVSB_IN_ROAD_STOP + (_settings.vehicle.road_side << RVS_DRIVE_SIDE)] == v->u.road.frame) ||
+			_road_veh_data_1[v->u.road.state - RVSB_IN_ROAD_STOP + (_settings_game.vehicle.road_side << RVS_DRIVE_SIDE)] == v->u.road.frame) ||
 			(IsInsideMM(v->u.road.state, RVSB_IN_DT_ROAD_STOP, RVSB_IN_DT_ROAD_STOP_END) &&
 			v->current_order.ShouldStopAtStation(v, GetStationIndex(v->tile)) &&
 			GetRoadStopType(v->tile) == (IsCargoInClass(v->cargo_type, CC_PASSENGERS) ? ROADSTOP_BUS : ROADSTOP_TRUCK) &&
@@ -1890,7 +1890,7 @@
 static void CheckIfRoadVehNeedsService(Vehicle *v)
 {
 	/* If we already got a slot at a stop, use that FIRST, and go to a depot later */
-	if (v->u.road.slot != NULL || _settings.vehicle.servint_roadveh == 0 || !v->NeedsAutomaticServicing()) return;
+	if (v->u.road.slot != NULL || _settings_game.vehicle.servint_roadveh == 0 || !v->NeedsAutomaticServicing()) return;
 	if (v->IsInDepot()) {
 		VehicleServiceInDepot(v);
 		return;
--- a/src/saveload.cpp	Thu May 29 12:52:24 2008 +0000
+++ b/src/saveload.cpp	Thu May 29 15:56:32 2008 +0000
@@ -43,8 +43,8 @@
 uint16 _sl_version;       ///< the major savegame version identifier
 byte   _sl_minor_version; ///< the minor savegame version, DO NOT USE!
 
-typedef void WriterProc(uint len);
-typedef uint ReaderProc();
+typedef void WriterProc(size_t len);
+typedef size_t ReaderProc();
 
 /** The saveload struct, containing reader-writer functions, bufffer, version, etc. */
 static struct {
@@ -53,10 +53,10 @@
 	byte block_mode;                     ///< ???
 	bool error;                          ///< did an error occur or not
 
-	int obj_len;                         ///< the length of the current object we are busy with
+	size_t obj_len;                      ///< the length of the current object we are busy with
 	int array_index, last_array_index;   ///< in the case of an array, the current and last positions
 
-	uint32 offs_base;                    ///< the offset in number of bytes since we started writing data (eg uncompressed savegame size)
+	size_t offs_base;                    ///< the offset in number of bytes since we started writing data (eg uncompressed savegame size)
 
 	WriterProc *write_bytes;             ///< savegame writer function
 	ReaderProc *read_bytes;              ///< savegame loader function
@@ -123,7 +123,7 @@
  */
 static void SlReadFill()
 {
-	uint len = _sl.read_bytes();
+	size_t len = _sl.read_bytes();
 	if (len == 0) SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME, "Unexpected end of chunk");
 
 	_sl.bufp = _sl.buf;
@@ -131,7 +131,7 @@
 	_sl.offs_base += len;
 }
 
-static inline uint32 SlGetOffs() {return _sl.offs_base - (_sl.bufe - _sl.bufp);}
+static inline size_t SlGetOffs() {return _sl.offs_base - (_sl.bufe - _sl.bufp);}
 
 /** Return the size in bytes of a certain type of normal/atomic variable
  * as it appears in memory. See VarTypes
@@ -283,27 +283,27 @@
  * @param i Index being written
  */
 
-static void SlWriteSimpleGamma(uint i)
+static void SlWriteSimpleGamma(size_t i)
 {
 	if (i >= (1 << 7)) {
 		if (i >= (1 << 14)) {
 			if (i >= (1 << 21)) {
 				assert(i < (1 << 28));
-				SlWriteByte((byte)0xE0 | (i >> 24));
+				SlWriteByte((byte)(0xE0 | (i >> 24)));
 				SlWriteByte((byte)(i >> 16));
 			} else {
-				SlWriteByte((byte)0xC0 | (i >> 16));
+				SlWriteByte((byte)(0xC0 | (i >> 16)));
 			}
 			SlWriteByte((byte)(i >> 8));
 		} else {
 			SlWriteByte((byte)(0x80 | (i >> 8)));
 		}
 	}
-	SlWriteByte(i);
+	SlWriteByte((byte)i);
 }
 
 /** Return how many bytes used to encode a gamma value */
-static inline uint SlGetGammaLength(uint i)
+static inline uint SlGetGammaLength(size_t i)
 {
 	return 1 + (i >= (1 << 7)) + (i >= (1 << 14)) + (i >= (1 << 21));
 }
@@ -312,8 +312,8 @@
 static inline void SlWriteSparseIndex(uint index) {SlWriteSimpleGamma(index);}
 
 static inline uint SlReadArrayLength() {return SlReadSimpleGamma();}
-static inline void SlWriteArrayLength(uint length) {SlWriteSimpleGamma(length);}
-static inline uint SlGetArrayLength(uint length) {return SlGetGammaLength(length);}
+static inline void SlWriteArrayLength(size_t length) {SlWriteSimpleGamma(length);}
+static inline uint SlGetArrayLength(size_t length) {return SlGetGammaLength(length);}
 
 void SlSetArrayIndex(uint index)
 {
@@ -321,7 +321,7 @@
 	_sl.array_index = index;
 }
 
-static uint32 _next_offs;
+static size_t _next_offs;
 
 /**
  * Iterate through the elements of an array and read the whole thing
@@ -375,7 +375,7 @@
 			 * The lower 24 bits are normal
 			 * The uppermost 4 bits are bits 24:27 */
 			assert(length < (1 << 28));
-			SlWriteUint32((length & 0xFFFFFF) | ((length >> 24) << 28));
+			SlWriteUint32((uint32)((length & 0xFFFFFF) | ((length >> 24) << 28)));
 			break;
 		case CH_ARRAY:
 			assert(_sl.last_array_index <= _sl.array_index);
@@ -390,7 +390,7 @@
 		default: NOT_REACHED();
 		} break;
 	case NL_CALCLENGTH:
-		_sl.obj_len += length;
+		_sl.obj_len += (int)length;
 		break;
 	}
 }
@@ -422,7 +422,7 @@
 }
 
 /* Get the length of the current object */
-uint SlGetFieldLength() {return _sl.obj_len;}
+size_t SlGetFieldLength() {return _sl.obj_len;}
 
 /** Return a signed-long version of the value of a setting
  * @param ptr pointer to the variable
@@ -628,7 +628,7 @@
  * @param length The length of the array counted in elements
  * @param conv VarType type of the variable that is used in calculating the size
  */
-static inline size_t SlCalcArrayLen(uint length, VarType conv)
+static inline size_t SlCalcArrayLen(size_t length, VarType conv)
 {
 	return SlCalcConvFileLen(conv) * length;
 }
@@ -639,7 +639,7 @@
  * @param length The length of the array in elements
  * @param conv VarType type of the atomic array (int, byte, uint64, etc.)
  */
-void SlArray(void *array, uint length, VarType conv)
+void SlArray(void *array, size_t length, VarType conv)
 {
 	/* Automatically calculate the length? */
 	if (_sl.need_length != NL_NONE) {
@@ -710,7 +710,7 @@
 	std::list<void *> *l = (std::list<void *> *) list;
 
 	if (_sl.save) {
-		SlWriteUint32(l->size());
+		SlWriteUint32((uint32)l->size());
 
 		std::list<void *>::iterator iter;
 		for (iter = l->begin(); iter != l->end(); ++iter) {
@@ -884,7 +884,7 @@
  */
 void SlAutolength(AutolengthProc *proc, void *arg)
 {
-	uint32 offs;
+	size_t offs;
 
 	assert(_sl.save);
 
@@ -912,8 +912,8 @@
 static void SlLoadChunk(const ChunkHandler *ch)
 {
 	byte m = SlReadByte();
-	uint32 len;
-	uint32 endoffs;
+	size_t len;
+	size_t endoffs;
 
 	_sl.block_mode = m;
 	_sl.obj_len = 0;
@@ -1052,7 +1052,7 @@
 
 #include "minilzo.h"
 
-static uint ReadLZO()
+static size_t ReadLZO()
 {
 	byte out[LZO_SIZE + LZO_SIZE / 64 + 16 + 3 + 8];
 	uint32 tmp[2];
@@ -1085,13 +1085,13 @@
 
 /* p contains the pointer to the buffer, len contains the pointer to the length.
  * len bytes will be written, p and l will be updated to reflect the next buffer. */
-static void WriteLZO(uint size)
+static void WriteLZO(size_t size)
 {
 	byte out[LZO_SIZE + LZO_SIZE / 64 + 16 + 3 + 8];
 	byte wrkmem[sizeof(byte*)*4096];
 	uint outlen;
 
-	lzo1x_1_compress(_sl.buf, size, out + sizeof(uint32)*2, &outlen, wrkmem);
+	lzo1x_1_compress(_sl.buf, (lzo_uint)size, out + sizeof(uint32)*2, &outlen, wrkmem);
 	((uint32*)out)[1] = TO_BE32(outlen);
 	((uint32*)out)[0] = TO_BE32(lzo_adler32(0, out + sizeof(uint32), outlen + sizeof(uint32)));
 	if (fwrite(out, outlen + sizeof(uint32)*2, 1, _sl.fh) != 1) SlError(STR_GAME_SAVELOAD_ERROR_FILE_NOT_WRITEABLE);
@@ -1112,12 +1112,12 @@
 /*********************************************
  ******** START OF NOCOMP CODE (uncompressed)*
  *********************************************/
-static uint ReadNoComp()
+static size_t ReadNoComp()
 {
 	return fread(_sl.buf, 1, LZO_SIZE, _sl.fh);
 }
 
-static void WriteNoComp(uint size)
+static void WriteNoComp(size_t size)
 {
 	if (fwrite(_sl.buf, 1, size, _sl.fh) != size) SlError(STR_GAME_SAVELOAD_ERROR_FILE_NOT_WRITEABLE);
 }
@@ -1170,9 +1170,9 @@
 	_Savegame_pool.CleanPool();
 }
 
-static void WriteMem(uint size)
+static void WriteMem(size_t size)
 {
-	_ts.count += size;
+	_ts.count += (uint)size;
 	/* Allocate new block and new buffer-pointer */
 	_Savegame_pool.AddBlockIfNeeded(_ts.count);
 	_sl.buf = GetSavegame(_ts.count);
@@ -1197,7 +1197,7 @@
 	return true;
 }
 
-static uint ReadZlib()
+static size_t ReadZlib()
 {
 	int r;
 
@@ -1237,13 +1237,13 @@
 	return true;
 }
 
-static void WriteZlibLoop(z_streamp z, byte *p, uint len, int mode)
+static void WriteZlibLoop(z_streamp z, byte *p, size_t len, int mode)
 {
 	byte buf[1024]; // output buffer
 	int r;
 	uint n;
 	z->next_in = p;
-	z->avail_in = len;
+	z->avail_in = (uInt)len;
 	do {
 		z->next_out = buf;
 		z->avail_out = sizeof(buf);
@@ -1258,7 +1258,7 @@
 	} while (z->avail_in || !z->avail_out);
 }
 
-static void WriteZlib(uint len)
+static void WriteZlib(size_t len)
 {
 	WriteZlibLoop(&_z, _sl.buf, len, 0);
 }
@@ -1471,9 +1471,9 @@
 }
 
 /* actual loader/saver function */
-void InitializeGame(int mode, uint size_x, uint size_y);
+void InitializeGame(uint size_x, uint size_y, bool reset_date);
 extern bool AfterLoadGame();
-extern void BeforeSaveGame();
+extern void SaveViewportBeforeSaveGame();
 extern bool LoadOldSaveGame(const char *file);
 
 /** Small helper function to close the to be loaded savegame an signal error */
@@ -1634,7 +1634,7 @@
 
 	/* Load a TTDLX or TTDPatch game */
 	if (mode == SL_OLD_LOAD) {
-		InitializeGame(IG_DATE_RESET, 256, 256); // set a mapsize of 256x256 for TTDPatch games or it might get confused
+		InitializeGame(256, 256, true); // set a mapsize of 256x256 for TTDPatch games or it might get confused
 		if (!LoadOldSaveGame(filename)) return SL_REINIT;
 		_sl_version = 0;
 		_sl_minor_version = 0;
@@ -1673,7 +1673,7 @@
 
 			_sl_version = SAVEGAME_VERSION;
 
-			BeforeSaveGame();
+			SaveViewportBeforeSaveGame();
 			SlSaveChunks();
 			SlWriteFill(); // flush the save buffer
 
@@ -1747,7 +1747,7 @@
 			/* Old maps were hardcoded to 256x256 and thus did not contain
 			 * any mapsize information. Pre-initialize to 256x256 to not to
 			 * confuse old games */
-			InitializeGame(IG_DATE_RESET, 256, 256);
+			InitializeGame(256, 256, true);
 
 			SlLoadChunks();
 			fmt->uninit_read();
@@ -1776,7 +1776,7 @@
 	}
 }
 
-/** Do a save when exiting the game (patch option) _settings.gui.autosave_on_exit */
+/** Do a save when exiting the game (patch option) _settings_client.gui.autosave_on_exit */
 void DoExitSave()
 {
 	SaveOrLoad("exit.sav", SL_SAVE, AUTOSAVE_DIR);
--- a/src/saveload.h	Thu May 29 12:52:24 2008 +0000
+++ b/src/saveload.h	Thu May 29 15:56:32 2008 +0000
@@ -305,7 +305,7 @@
  * to add this to the address of the object */
 static inline void *GetVariableAddress(const void *object, const SaveLoad *sld)
 {
-	return (byte*)object + (ptrdiff_t)sld->address;
+	return (byte*)(sld->global ? NULL : object) + (ptrdiff_t)sld->address;
 }
 
 int64 ReadValue(const void *ptr, VarType conv);
@@ -315,7 +315,7 @@
 int SlIterateArray();
 
 void SlAutolength(AutolengthProc *proc, void *arg);
-uint SlGetFieldLength();
+size_t SlGetFieldLength();
 void SlSetLength(size_t length);
 size_t SlCalcObjMemberLength(const void *object, const SaveLoad *sld);
 
@@ -323,7 +323,7 @@
 void SlWriteByte(byte b);
 
 void SlGlobList(const SaveLoadGlobVarList *sldg);
-void SlArray(void *array, uint length, VarType conv);
+void SlArray(void *array, size_t length, VarType conv);
 void SlObject(void *object, const SaveLoad *sld);
 bool SlObjectMember(void *object, const SaveLoad *sld);
 
--- a/src/settings.cpp	Thu May 29 12:52:24 2008 +0000
+++ b/src/settings.cpp	Thu May 29 15:56:32 2008 +0000
@@ -64,8 +64,9 @@
 
 #include "table/strings.h"
 
-Settings _settings;
-Settings _settings_newgame;
+ClientSettings _settings_client;
+GameSettings _settings_game;
+GameSettings _settings_newgame;
 
 struct IniFile;
 struct IniItem;
@@ -766,7 +767,7 @@
 		}
 
 		p = (item == NULL) ? sdb->def : string_to_val(sdb, item->value);
-		ptr = GetVariableAddress(sld->global ? NULL : object, sld);
+		ptr = GetVariableAddress(object, sld);
 
 		switch (sdb->cmd) {
 		case SDT_BOOLX: /* All four are various types of (integer) numbers */
@@ -1121,6 +1122,32 @@
 #define SDT_CONDNULL(length, from, to)\
 	{{"", NULL, {0}, {0}, 0, 0, 0, NULL, STR_NULL, NULL, NULL}, SLE_CONDNULL(length, from, to)}
 
+
+#define SDTC_CONDVAR(var, type, from, to, flags, guiflags, def, min, max, interval, str, proc)\
+	SDTG_GENERAL(#var, SDT_NUMX, SL_VAR, type, flags, guiflags, _settings_client.var, 0, def, min, max, interval, NULL, str, proc, from, to)
+#define SDTC_VAR(var, type, flags, guiflags, def, min, max, interval, str, proc)\
+	SDTC_CONDVAR(var, type, 0, SL_MAX_VERSION, flags, guiflags, def, min, max, interval, str, proc)
+
+#define SDTC_CONDBOOL(var, from, to, flags, guiflags, def, str, proc)\
+	SDTG_GENERAL(#var, SDT_BOOLX, SL_VAR, SLE_BOOL, flags, guiflags, _settings_client.var, 0, def, 0, 1, 0, NULL, str, proc, from, to)
+#define SDTC_BOOL(var, flags, guiflags, def, str, proc)\
+	SDTC_CONDBOOL(var, 0, SL_MAX_VERSION, flags, guiflags, def, str, proc)
+
+#define SDTC_CONDLIST(var, type, length, flags, guiflags, def, str, proc, from, to)\
+	SDTG_GENERAL(#var, SDT_INTLIST, SL_ARR, type, flags, guiflags, _settings_client.var, length, def, 0, 0, 0, NULL, str, proc, from, to)
+#define SDTC_LIST(var, type, flags, guiflags, def, str, proc)\
+	SDTG_GENERAL(var, SDT_INTLIST, SL_ARR, type, flags, guiflags, _settings_client.var, lengthof(_settings_client.var), def, 0, 0, 0, NULL, str, proc, 0, SL_MAX_VERSION)
+
+#define SDTC_CONDSTR(var, type, length, flags, guiflags, def, str, proc, from, to)\
+	SDTG_GENERAL(#var, SDT_STRING, SL_STR, type, flags, guiflags, _settings_client.var, length, def, 0, 0, 0, NULL, str, proc, from, to)
+#define SDTC_STR(var, type, flags, guiflags, def, str, proc)\
+	SDTG_GENERAL(var, SDT_STRING, SL_STR, type, flags, guiflags, _settings_client.var, lengthof(_settings_client.var), def, 0, 0, 0, NULL, str, proc, 0, SL_MAX_VERSION)
+
+#define SDTC_CONDOMANY(var, type, from, to, flags, guiflags, def, max, full, str, proc)\
+	SDTG_GENERAL(#var, SDT_ONEOFMANY, SL_VAR, type, flags, guiflags, _settings_client.var, 0, def, 0, max, 0, full, str, proc, from, to)
+#define SDTC_OMANY(var, type, flags, guiflags, def, max, full, str, proc)\
+	SDTC_CONDOMANY(var, type, 0, SL_MAX_VERSION, flags, guiflags, def, max, full, str, proc)
+
 #define SDT_END() {{NULL, NULL, {0}, {0}, 0, 0, 0, NULL, STR_NULL, NULL, NULL}, SLE_END()}
 
 /* Shortcuts for macros below. Logically if we don't save the value
@@ -1214,7 +1241,7 @@
 static int32 CheckInterval(int32 p1)
 {
 	bool warning;
-	const VehicleSettings *ptc = (_game_mode == GM_MENU) ? &_settings_newgame.vehicle : &_settings.vehicle;
+	const VehicleSettings *ptc = (_game_mode == GM_MENU) ? &_settings_newgame.vehicle : &_settings_game.vehicle;
 
 	if (p1) {
 		warning = ( (IsInsideMM(ptc->servint_trains,   5, 90 + 1) || ptc->servint_trains   == 0) &&
@@ -1236,19 +1263,19 @@
 
 static int32 EngineRenewUpdate(int32 p1)
 {
-	DoCommandP(0, 0, _settings.gui.autorenew, NULL, CMD_SET_AUTOREPLACE);
+	DoCommandP(0, 0, _settings_client.gui.autorenew, NULL, CMD_SET_AUTOREPLACE);
 	return 0;
 }
 
 static int32 EngineRenewMonthsUpdate(int32 p1)
 {
-	DoCommandP(0, 1, _settings.gui.autorenew_months, NULL, CMD_SET_AUTOREPLACE);
+	DoCommandP(0, 1, _settings_client.gui.autorenew_months, NULL, CMD_SET_AUTOREPLACE);
 	return 0;
 }
 
 static int32 EngineRenewMoneyUpdate(int32 p1)
 {
-	DoCommandP(0, 2, _settings.gui.autorenew_money, NULL, CMD_SET_AUTOREPLACE);
+	DoCommandP(0, 2, _settings_client.gui.autorenew_money, NULL, CMD_SET_AUTOREPLACE);
 	return 0;
 }
 
@@ -1322,7 +1349,7 @@
 
 static int32 DifficultyReset(int32 level)
 {
-	SetDifficultyLevel(level, (_game_mode == GM_MENU) ? &_settings_newgame.difficulty : &_settings.difficulty);
+	SetDifficultyLevel(level, (_game_mode == GM_MENU) ? &_settings_newgame.difficulty : &_settings_game.difficulty);
 	return 0;
 }
 
@@ -1331,7 +1358,7 @@
 	if (_game_mode == GM_MENU) {
 		_settings_newgame.difficulty.diff_level = 3;
 	} else {
-		_settings.difficulty.diff_level = 3;
+		_settings_game.difficulty.diff_level = 3;
 	}
 
 	/* If we are a network-client, update the difficult setting (if it is open).
@@ -1348,7 +1375,7 @@
 {
 	if (_game_mode == GM_NORMAL) {
 		UpdateAirportsNoise();
-		if (_settings.economy.station_noise_level) {
+		if (_settings_game.economy.station_noise_level) {
 			InvalidateWindowClassesData(WC_TOWN_VIEW, 0);
 		}
 	}
@@ -1366,14 +1393,14 @@
  */
 static int32 CheckTownLayout(int32 p1)
 {
-	if (_settings.economy.town_layout == TL_NO_ROADS && _game_mode == GM_EDITOR) {
+	if (_settings_game.economy.town_layout == TL_NO_ROADS && _game_mode == GM_EDITOR) {
 		ShowErrorMessage(INVALID_STRING_ID, STR_CONFIG_PATCHES_TOWN_LAYOUT_INVALID, 0, 0);
-		_settings.economy.town_layout = TL_ORIGINAL;
+		_settings_game.economy.town_layout = TL_ORIGINAL;
 	}
 	return 0;
 }
 
-/** Conversion callback for _gameopt_settings.landscape
+/** Conversion callback for _gameopt_settings_game.landscape
  * It converts (or try) between old values and the new ones,
  * without loosing initial setting  of the user
  * @param value that was read from config file
@@ -1393,7 +1420,7 @@
  * So basically, 200, 400, 800 are the lowest allowed values */
 static int32 CheckNoiseToleranceLevel(const char *value)
 {
-	Settings *s = (_game_mode == GM_MENU) ? &_settings_newgame : &_settings;
+	GameSettings *s = (_game_mode == GM_MENU) ? &_settings_newgame : &_settings_game;
 	for (uint16 i = 0; i < lengthof(s->economy.town_noise_population); i++) {
 		s->economy.town_noise_population[i] = max(uint16(200 * (i + 1)), s->economy.town_noise_population[i]);
 	}
@@ -1515,16 +1542,16 @@
 	 SDTG_GENERAL("diff_custom", SDT_INTLIST, SL_ARR, SLE_FILE_I16 | SLE_VAR_U16,    C, 0, _old_diff_custom, 17, 0, 0, 0, 0, NULL, STR_NULL, NULL, 0,  3),
 	 SDTG_GENERAL("diff_custom", SDT_INTLIST, SL_ARR, SLE_UINT16,                    C, 0, _old_diff_custom, 18, 0, 0, 0, 0, NULL, STR_NULL, NULL, 4, 96),
 
-	      SDT_VAR(Settings, difficulty.diff_level,    SLE_UINT8,                     0, 0, 0, 0,  3, 0, STR_NULL, NULL),
-	    SDT_OMANY(Settings, gui.currency,             SLE_UINT8,                     N, 0, 0, CUSTOM_CURRENCY_ID, "GBP|USD|EUR|YEN|ATS|BEF|CHF|CZK|DEM|DKK|ESP|FIM|FRF|GRD|HUF|ISK|ITL|NLG|NOK|PLN|ROL|RUR|SIT|SEK|YTL|SKK|BRR|custom", STR_NULL, NULL, NULL),
-	    SDT_OMANY(Settings, gui.units,                SLE_UINT8,                     N, 0, 1, 2, "imperial|metric|si", STR_NULL, NULL, NULL),
+	      SDT_VAR(GameSettings, difficulty.diff_level,    SLE_UINT8,                     0, 0, 0, 0,  3, 0, STR_NULL, NULL),
+	   SDTC_OMANY(              gui.currency,             SLE_UINT8,                     N, 0, 0, CUSTOM_CURRENCY_ID, "GBP|USD|EUR|YEN|ATS|BEF|CHF|CZK|DEM|DKK|ESP|FIM|FRF|GRD|HUF|ISK|ITL|NLG|NOK|PLN|ROL|RUR|SIT|SEK|YTL|SKK|BRR|custom", STR_NULL, NULL),
+	   SDTC_OMANY(              gui.units,                SLE_UINT8,                     N, 0, 1, 2, "imperial|metric|si", STR_NULL, NULL),
 	/* There are only 21 predefined town_name values (0-20), but you can have more with newgrf action F so allow these bigger values (21-255). Invalid values will fallback to english on use and (undefined string) in GUI. */
-	    SDT_OMANY(Settings, game_creation.town_name,  SLE_UINT8,                     0, 0, 0, 255, "english|french|german|american|latin|silly|swedish|dutch|finnish|polish|slovakish|norwegian|hungarian|austrian|romanian|czech|swiss|danish|turkish|italian|catalan", STR_NULL, NULL, NULL),
-	    SDT_OMANY(Settings, game_creation.landscape,  SLE_UINT8,                     0, 0, 0, 3, "temperate|arctic|tropic|toyland", STR_NULL, NULL, ConvertLandscape),
-	      SDT_VAR(Settings, game_creation.snow_line,  SLE_UINT8,                     0, 0, 7 * TILE_HEIGHT, 2 * TILE_HEIGHT, 13 * TILE_HEIGHT, 0, STR_NULL, NULL),
-	SDT_CONDOMANY(Settings, gui.autosave,             SLE_UINT8,  0, 22,             N, 0, 0, 0, "", STR_NULL, NULL, NULL),
-	SDT_CONDOMANY(Settings, gui.autosave,             SLE_UINT8, 23, SL_MAX_VERSION, S, 0, 1, 4, "off|monthly|quarterly|half year|yearly", STR_NULL, NULL, NULL),
-	    SDT_OMANY(Settings, vehicle.road_side,        SLE_UINT8,                     0, 0, 1, 1, "left|right", STR_NULL, NULL, NULL),
+	    SDT_OMANY(GameSettings, game_creation.town_name,  SLE_UINT8,                     0, 0, 0, 255, "english|french|german|american|latin|silly|swedish|dutch|finnish|polish|slovakish|norwegian|hungarian|austrian|romanian|czech|swiss|danish|turkish|italian|catalan", STR_NULL, NULL, NULL),
+	    SDT_OMANY(GameSettings, game_creation.landscape,  SLE_UINT8,                     0, 0, 0, 3, "temperate|arctic|tropic|toyland", STR_NULL, NULL, ConvertLandscape),
+	      SDT_VAR(GameSettings, game_creation.snow_line,  SLE_UINT8,                     0, 0, 7 * TILE_HEIGHT, 2 * TILE_HEIGHT, 13 * TILE_HEIGHT, 0, STR_NULL, NULL),
+ SDTC_CONDOMANY(              gui.autosave,             SLE_UINT8,  0, 22,             N, 0, 0, 0, "", STR_NULL, NULL),
+ SDTC_CONDOMANY(              gui.autosave,             SLE_UINT8, 23, SL_MAX_VERSION, S, 0, 1, 4, "off|monthly|quarterly|half year|yearly", STR_NULL, NULL),
+	    SDT_OMANY(GameSettings, vehicle.road_side,        SLE_UINT8,                     0, 0, 1, 1, "left|right", STR_NULL, NULL, NULL),
 	    SDT_END()
 };
 
@@ -1541,216 +1568,217 @@
 	/***************************************************************************/
 	/* Saved patch variables. */
 	/* Do not ADD or REMOVE something in this "difficulty.XXX" table or before it. It breaks savegame compatability. */
-	 SDT_CONDVAR(Settings, difficulty.max_no_competitors,        SLE_UINT8, 97, SL_MAX_VERSION, 0, 0,     2,     0,      7,  1, STR_NULL,                                  DifficultyChange),
-	 SDT_CONDVAR(Settings, difficulty.competitor_start_time,     SLE_UINT8, 97, SL_MAX_VERSION, 0,NG,     2,     0,      3,  1, STR_6830_IMMEDIATE,                        DifficultyChange),
-	 SDT_CONDVAR(Settings, difficulty.number_towns,              SLE_UINT8, 97, SL_MAX_VERSION, 0,NG,     2,     0,      3,  1, STR_NUM_VERY_LOW,                          DifficultyChange),
-	 SDT_CONDVAR(Settings, difficulty.number_industries,         SLE_UINT8, 97, SL_MAX_VERSION, 0,NG,     4,     0,      4,  1, STR_NONE,                                  DifficultyChange),
-	 SDT_CONDVAR(Settings, difficulty.max_loan,                 SLE_UINT32, 97, SL_MAX_VERSION, 0,NG|CR,300000,100000,500000,50000,STR_NULL,                               DifficultyChange),
-	 SDT_CONDVAR(Settings, difficulty.initial_interest,          SLE_UINT8, 97, SL_MAX_VERSION, 0,NG,     2,     2,      4,  1, STR_NULL,                                  DifficultyChange),
-	 SDT_CONDVAR(Settings, difficulty.vehicle_costs,             SLE_UINT8, 97, SL_MAX_VERSION, 0, 0,     0,     0,      2,  1, STR_6820_LOW,                              DifficultyChange),
-	 SDT_CONDVAR(Settings, difficulty.competitor_speed,          SLE_UINT8, 97, SL_MAX_VERSION, 0, 0,     2,     0,      4,  1, STR_681B_VERY_SLOW,                        DifficultyChange),
-	 SDT_CONDVAR(Settings, difficulty.competitor_intelligence,   SLE_UINT8, 97, SL_MAX_VERSION, 0, 0,     0,     0,      2,  1, STR_6820_LOW,                              DifficultyChange),
-	 SDT_CONDVAR(Settings, difficulty.vehicle_breakdowns,        SLE_UINT8, 97, SL_MAX_VERSION, 0, 0,     1,     0,      2,  1, STR_6823_NONE,                             DifficultyChange),
-	 SDT_CONDVAR(Settings, difficulty.subsidy_multiplier,        SLE_UINT8, 97, SL_MAX_VERSION, 0, 0,     2,     0,      3,  1, STR_6826_X1_5,                             DifficultyChange),
-	 SDT_CONDVAR(Settings, difficulty.construction_cost,         SLE_UINT8, 97, SL_MAX_VERSION, 0,NG,     0,     0,      2,  1, STR_6820_LOW,                              DifficultyChange),
-	 SDT_CONDVAR(Settings, difficulty.terrain_type,              SLE_UINT8, 97, SL_MAX_VERSION, 0,NG,     1,     0,      3,  1, STR_682A_VERY_FLAT,                        DifficultyChange),
-	 SDT_CONDVAR(Settings, difficulty.quantity_sea_lakes,        SLE_UINT8, 97, SL_MAX_VERSION, 0,NG,     0,     0,      3,  1, STR_VERY_LOW,                              DifficultyChange),
-	 SDT_CONDVAR(Settings, difficulty.economy,                   SLE_UINT8, 97, SL_MAX_VERSION, 0, 0,     0,     0,      1,  1, STR_682E_STEADY,                           DifficultyChange),
-	 SDT_CONDVAR(Settings, difficulty.line_reverse_mode,         SLE_UINT8, 97, SL_MAX_VERSION, 0, 0,     0,     0,      1,  1, STR_6834_AT_END_OF_LINE_AND_AT_STATIONS,   DifficultyChange),
-	 SDT_CONDVAR(Settings, difficulty.disasters,                 SLE_UINT8, 97, SL_MAX_VERSION, 0, 0,     0,     0,      1,  1, STR_6836_OFF,                              DifficultyChange),
-	 SDT_CONDVAR(Settings, difficulty.town_council_tolerance,    SLE_UINT8, 97, SL_MAX_VERSION, 0, 0,     0,     0,      2,  1, STR_PERMISSIVE,                            DifficultyNoiseChange),
-	 SDT_CONDVAR(Settings, difficulty.diff_level,                SLE_UINT8, 97, SL_MAX_VERSION, 0,NG,     0,     0,      3,  0, STR_NULL,                                  DifficultyReset),
+	 SDT_CONDVAR(GameSettings, difficulty.max_no_competitors,        SLE_UINT8, 97, SL_MAX_VERSION, 0, 0,     2,     0,      7,  1, STR_NULL,                                  DifficultyChange),
+	 SDT_CONDVAR(GameSettings, difficulty.competitor_start_time,     SLE_UINT8, 97, SL_MAX_VERSION, 0,NG,     2,     0,      3,  1, STR_6830_IMMEDIATE,                        DifficultyChange),
+	 SDT_CONDVAR(GameSettings, difficulty.number_towns,              SLE_UINT8, 97, SL_MAX_VERSION, 0,NG,     2,     0,      3,  1, STR_NUM_VERY_LOW,                          DifficultyChange),
+	 SDT_CONDVAR(GameSettings, difficulty.number_industries,         SLE_UINT8, 97, SL_MAX_VERSION, 0,NG,     4,     0,      4,  1, STR_NONE,                                  DifficultyChange),
+	 SDT_CONDVAR(GameSettings, difficulty.max_loan,                 SLE_UINT32, 97, SL_MAX_VERSION, 0,NG|CR,300000,100000,500000,50000,STR_NULL,                               DifficultyChange),
+	 SDT_CONDVAR(GameSettings, difficulty.initial_interest,          SLE_UINT8, 97, SL_MAX_VERSION, 0,NG,     2,     2,      4,  1, STR_NULL,                                  DifficultyChange),
+	 SDT_CONDVAR(GameSettings, difficulty.vehicle_costs,             SLE_UINT8, 97, SL_MAX_VERSION, 0, 0,     0,     0,      2,  1, STR_6820_LOW,                              DifficultyChange),
+	 SDT_CONDVAR(GameSettings, difficulty.competitor_speed,          SLE_UINT8, 97, SL_MAX_VERSION, 0, 0,     2,     0,      4,  1, STR_681B_VERY_SLOW,                        DifficultyChange),
+	 SDT_CONDVAR(GameSettings, difficulty.competitor_intelligence,   SLE_UINT8, 97, SL_MAX_VERSION, 0, 0,     0,     0,      2,  1, STR_6820_LOW,                              DifficultyChange),
+	 SDT_CONDVAR(GameSettings, difficulty.vehicle_breakdowns,        SLE_UINT8, 97, SL_MAX_VERSION, 0, 0,     1,     0,      2,  1, STR_6823_NONE,                             DifficultyChange),
+	 SDT_CONDVAR(GameSettings, difficulty.subsidy_multiplier,        SLE_UINT8, 97, SL_MAX_VERSION, 0, 0,     2,     0,      3,  1, STR_6826_X1_5,                             DifficultyChange),
+	 SDT_CONDVAR(GameSettings, difficulty.construction_cost,         SLE_UINT8, 97, SL_MAX_VERSION, 0,NG,     0,     0,      2,  1, STR_6820_LOW,                              DifficultyChange),
+	 SDT_CONDVAR(GameSettings, difficulty.terrain_type,              SLE_UINT8, 97, SL_MAX_VERSION, 0,NG,     1,     0,      3,  1, STR_682A_VERY_FLAT,                        DifficultyChange),
+	 SDT_CONDVAR(GameSettings, difficulty.quantity_sea_lakes,        SLE_UINT8, 97, SL_MAX_VERSION, 0,NG,     0,     0,      3,  1, STR_VERY_LOW,                              DifficultyChange),
+	 SDT_CONDVAR(GameSettings, difficulty.economy,                   SLE_UINT8, 97, SL_MAX_VERSION, 0, 0,     0,     0,      1,  1, STR_682E_STEADY,                           DifficultyChange),
+	 SDT_CONDVAR(GameSettings, difficulty.line_reverse_mode,         SLE_UINT8, 97, SL_MAX_VERSION, 0, 0,     0,     0,      1,  1, STR_6834_AT_END_OF_LINE_AND_AT_STATIONS,   DifficultyChange),
+	 SDT_CONDVAR(GameSettings, difficulty.disasters,                 SLE_UINT8, 97, SL_MAX_VERSION, 0, 0,     0,     0,      1,  1, STR_6836_OFF,                              DifficultyChange),
+	 SDT_CONDVAR(GameSettings, difficulty.town_council_tolerance,    SLE_UINT8, 97, SL_MAX_VERSION, 0, 0,     0,     0,      2,  1, STR_PERMISSIVE,                            DifficultyNoiseChange),
+	 SDT_CONDVAR(GameSettings, difficulty.diff_level,                SLE_UINT8, 97, SL_MAX_VERSION, 0,NG,     0,     0,      3,  0, STR_NULL,                                  DifficultyReset),
 
 	/* There are only 21 predefined town_name values (0-20), but you can have more with newgrf action F so allow these bigger values (21-255). Invalid values will fallback to english on use and (undefined string) in GUI. */
- SDT_CONDOMANY(Settings, game_creation.town_name,              SLE_UINT8, 97, SL_MAX_VERSION, 0,NN, 0, 255, "english|french|german|american|latin|silly|swedish|dutch|finnish|polish|slovakish|norwegian|hungarian|austrian|romanian|czech|swiss|danish|turkish|italian|catalan", STR_NULL, NULL, NULL),
- SDT_CONDOMANY(Settings, game_creation.landscape,              SLE_UINT8, 97, SL_MAX_VERSION, 0,NN, 0,   3, "temperate|arctic|tropic|toyland", STR_NULL, NULL, ConvertLandscape),
-	 SDT_CONDVAR(Settings, game_creation.snow_line,              SLE_UINT8, 97, SL_MAX_VERSION, 0,NN, 7 * TILE_HEIGHT, 2 * TILE_HEIGHT, 13 * TILE_HEIGHT, 0, STR_NULL, NULL),
- SDT_CONDOMANY(Settings, vehicle.road_side,                    SLE_UINT8, 97, SL_MAX_VERSION, 0,NN, 1,   1, "left|right", STR_NULL, NULL, NULL),
-
-	    SDT_BOOL(Settings, construction.build_on_slopes,                                        0,NN,  true,                    STR_CONFIG_PATCHES_BUILDONSLOPES,          NULL),
-	SDT_CONDBOOL(Settings, construction.autoslope,                          75, SL_MAX_VERSION, 0, 0,  true,                    STR_CONFIG_PATCHES_AUTOSLOPE,              NULL),
-	    SDT_BOOL(Settings, construction.extra_dynamite,                                         0, 0, false,                    STR_CONFIG_PATCHES_EXTRADYNAMITE,          NULL),
-	    SDT_BOOL(Settings, construction.longbridges,                                            0,NN,  true,                    STR_CONFIG_PATCHES_LONGBRIDGES,            NULL),
-	    SDT_BOOL(Settings, construction.signal_side,                                            N,NN,  true,                    STR_CONFIG_PATCHES_SIGNALSIDE,             RedrawScreen),
-	    SDT_BOOL(Settings, station.always_small_airport,                                        0,NN, false,                    STR_CONFIG_PATCHES_SMALL_AIRPORTS,         NULL),
-	 SDT_CONDVAR(Settings, economy.town_layout,                  SLE_UINT8, 59, SL_MAX_VERSION, 0,MS,TL_ORIGINAL,TL_NO_ROADS,NUM_TLS-1,1, STR_CONFIG_PATCHES_TOWN_LAYOUT,  CheckTownLayout),
-
-	    SDT_BOOL(Settings, vehicle.realistic_acceleration,                                      0, 0, false,                    STR_CONFIG_PATCHES_REALISTICACCEL,         RealisticAccelerationChanged),
-	    SDT_BOOL(Settings, pf.forbid_90_deg,                                                    0, 0, false,                    STR_CONFIG_PATCHES_FORBID_90_DEG,          NULL),
-	    SDT_BOOL(Settings, vehicle.mammoth_trains,                                              0,NN,  true,                    STR_CONFIG_PATCHES_MAMMOTHTRAINS,          NULL),
-	    SDT_BOOL(Settings, order.gotodepot,                                                     0, 0,  true,                    STR_CONFIG_PATCHES_GOTODEPOT,              NULL),
-	    SDT_BOOL(Settings, pf.roadveh_queue,                                                    0, 0,  true,                    STR_CONFIG_PATCHES_ROADVEH_QUEUE,          NULL),
-
-	SDT_CONDBOOL(Settings, pf.new_pathfinding_all,                           0,             86, 0, 0, false,                    STR_NULL,                                  NULL),
-	SDT_CONDBOOL(Settings, pf.yapf.ship_use_yapf,                           28,             86, 0, 0, false,                    STR_NULL,                                  NULL),
-	SDT_CONDBOOL(Settings, pf.yapf.road_use_yapf,                           28,             86, 0, 0,  true,                    STR_NULL,                                  NULL),
-	SDT_CONDBOOL(Settings, pf.yapf.rail_use_yapf,                           28,             86, 0, 0,  true,                    STR_NULL,                                  NULL),
-
-	 SDT_CONDVAR(Settings, pf.pathfinder_for_trains,             SLE_UINT8, 87, SL_MAX_VERSION, 0, MS,    2,     0,       2, 1, STR_CONFIG_PATCHES_PATHFINDER_FOR_TRAINS,  NULL),
-	 SDT_CONDVAR(Settings, pf.pathfinder_for_roadvehs,           SLE_UINT8, 87, SL_MAX_VERSION, 0, MS,    2,     0,       2, 1, STR_CONFIG_PATCHES_PATHFINDER_FOR_ROADVEH, NULL),
-	 SDT_CONDVAR(Settings, pf.pathfinder_for_ships,              SLE_UINT8, 87, SL_MAX_VERSION, 0, MS,    0,     0,       2, 1, STR_CONFIG_PATCHES_PATHFINDER_FOR_SHIPS,   NULL),
+ SDT_CONDOMANY(GameSettings, game_creation.town_name,              SLE_UINT8, 97, SL_MAX_VERSION, 0,NN, 0, 255, "english|french|german|american|latin|silly|swedish|dutch|finnish|polish|slovakish|norwegian|hungarian|austrian|romanian|czech|swiss|danish|turkish|italian|catalan", STR_NULL, NULL, NULL),
+ SDT_CONDOMANY(GameSettings, game_creation.landscape,              SLE_UINT8, 97, SL_MAX_VERSION, 0,NN, 0,   3, "temperate|arctic|tropic|toyland", STR_NULL, NULL, ConvertLandscape),
+	 SDT_CONDVAR(GameSettings, game_creation.snow_line,              SLE_UINT8, 97, SL_MAX_VERSION, 0,NN, 7 * TILE_HEIGHT, 2 * TILE_HEIGHT, 13 * TILE_HEIGHT, 0, STR_NULL, NULL),
+ SDT_CONDOMANY(GameSettings, vehicle.road_side,                    SLE_UINT8, 97, SL_MAX_VERSION, 0,NN, 1,   1, "left|right", STR_NULL, NULL, NULL),
 
-	    SDT_BOOL(Settings, vehicle.never_expire_vehicles,                                       0,NN, false,                    STR_CONFIG_PATCHES_NEVER_EXPIRE_VEHICLES,  NULL),
-	     SDT_VAR(Settings, vehicle.max_trains,                  SLE_UINT16,                     0, 0,   500,     0,    5000, 0, STR_CONFIG_PATCHES_MAX_TRAINS,             RedrawScreen),
-	     SDT_VAR(Settings, vehicle.max_roadveh,                 SLE_UINT16,                     0, 0,   500,     0,    5000, 0, STR_CONFIG_PATCHES_MAX_ROADVEH,            RedrawScreen),
-	     SDT_VAR(Settings, vehicle.max_aircraft,                SLE_UINT16,                     0, 0,   200,     0,    5000, 0, STR_CONFIG_PATCHES_MAX_AIRCRAFT,           RedrawScreen),
-	     SDT_VAR(Settings, vehicle.max_ships,                   SLE_UINT16,                     0, 0,   300,     0,    5000, 0, STR_CONFIG_PATCHES_MAX_SHIPS,              RedrawScreen),
-	    SDT_BOOL(Settings, vehicle.servint_ispercent,                                           0, 0, false,                    STR_CONFIG_PATCHES_SERVINT_ISPERCENT,      CheckInterval),
-	     SDT_VAR(Settings, vehicle.servint_trains,              SLE_UINT16,                     0,D0,   150,     5,     800, 0, STR_CONFIG_PATCHES_SERVINT_TRAINS,         InValidateDetailsWindow),
-	     SDT_VAR(Settings, vehicle.servint_roadveh,             SLE_UINT16,                     0,D0,   150,     5,     800, 0, STR_CONFIG_PATCHES_SERVINT_ROADVEH,        InValidateDetailsWindow),
-	     SDT_VAR(Settings, vehicle.servint_ships,               SLE_UINT16,                     0,D0,   360,     5,     800, 0, STR_CONFIG_PATCHES_SERVINT_SHIPS,          InValidateDetailsWindow),
-	     SDT_VAR(Settings, vehicle.servint_aircraft,            SLE_UINT16,                     0,D0,   100,     5,     800, 0, STR_CONFIG_PATCHES_SERVINT_AIRCRAFT,       InValidateDetailsWindow),
-	    SDT_BOOL(Settings, order.no_servicing_if_no_breakdowns,                                 0, 0, false,                    STR_CONFIG_PATCHES_NOSERVICE,              NULL),
-	    SDT_BOOL(Settings, vehicle.wagon_speed_limits,                                          0,NN,  true,                    STR_CONFIG_PATCHES_WAGONSPEEDLIMITS,       UpdateConsists),
-	SDT_CONDBOOL(Settings, vehicle.disable_elrails,                         38, SL_MAX_VERSION, 0,NN, false,                    STR_CONFIG_PATCHES_DISABLE_ELRAILS,        SettingsDisableElrail),
-	 SDT_CONDVAR(Settings, vehicle.freight_trains,               SLE_UINT8, 39, SL_MAX_VERSION, 0,NN,     1,     1,     255, 1, STR_CONFIG_PATCHES_FREIGHT_TRAINS,         NULL),
-	SDT_CONDBOOL(Settings, order.timetabling,                               67, SL_MAX_VERSION, 0, 0,  true,                    STR_CONFIG_PATCHES_TIMETABLE_ALLOW,        NULL),
-	 SDT_CONDVAR(Settings, vehicle.plane_speed,                  SLE_UINT8, 90, SL_MAX_VERSION, 0, 0,     4,     1,       4, 0, STR_CONFIG_PATCHES_PLANE_SPEED,            NULL),
-	SDT_CONDBOOL(Settings, vehicle.dynamic_engines,                         95, SL_MAX_VERSION, 0,NN, false,                    STR_CONFIG_PATCHES_DYNAMIC_ENGINES,        NULL),
+	    SDT_BOOL(GameSettings, construction.build_on_slopes,                                        0,NN,  true,                    STR_CONFIG_PATCHES_BUILDONSLOPES,          NULL),
+	SDT_CONDBOOL(GameSettings, construction.autoslope,                          75, SL_MAX_VERSION, 0, 0,  true,                    STR_CONFIG_PATCHES_AUTOSLOPE,              NULL),
+	    SDT_BOOL(GameSettings, construction.extra_dynamite,                                         0, 0, false,                    STR_CONFIG_PATCHES_EXTRADYNAMITE,          NULL),
+	    SDT_BOOL(GameSettings, construction.longbridges,                                            0,NN,  true,                    STR_CONFIG_PATCHES_LONGBRIDGES,            NULL),
+	    SDT_BOOL(GameSettings, construction.signal_side,                                            N,NN,  true,                    STR_CONFIG_PATCHES_SIGNALSIDE,             RedrawScreen),
+	    SDT_BOOL(GameSettings, station.always_small_airport,                                        0,NN, false,                    STR_CONFIG_PATCHES_SMALL_AIRPORTS,         NULL),
+	 SDT_CONDVAR(GameSettings, economy.town_layout,                  SLE_UINT8, 59, SL_MAX_VERSION, 0,MS,TL_ORIGINAL,TL_NO_ROADS,NUM_TLS-1,1, STR_CONFIG_PATCHES_TOWN_LAYOUT,  CheckTownLayout),
 
-	    SDT_BOOL(Settings, station.join_stations,                                               0, 0,  true,                    STR_CONFIG_PATCHES_JOINSTATIONS,           NULL),
-	SDT_CONDBOOL(Settings, gui.sg_full_load_any,                             0,             92, 0, 0 , true,                    STR_NULL,                                  NULL),
-	    SDT_BOOL(Settings, order.improved_load,                                                 0,NN,  true,                    STR_CONFIG_PATCHES_IMPROVEDLOAD,           NULL),
-	    SDT_BOOL(Settings, order.selectgoods,                                                   0, 0,  true,                    STR_CONFIG_PATCHES_SELECTGOODS,            NULL),
-	SDT_CONDBOOL(Settings, gui.sg_new_nonstop,                               0,             92, 0, 0, false,                    STR_NULL,                                  NULL),
-	    SDT_BOOL(Settings, station.nonuniform_stations,                                         0,NN,  true,                    STR_CONFIG_PATCHES_NONUNIFORM_STATIONS,    NULL),
-	     SDT_VAR(Settings, station.station_spread,               SLE_UINT8,                     0, 0,    12,     4,      64, 0, STR_CONFIG_PATCHES_STATION_SPREAD,         InvalidateStationBuildWindow),
-	    SDT_BOOL(Settings, order.serviceathelipad,                                              0, 0,  true,                    STR_CONFIG_PATCHES_SERVICEATHELIPAD,       NULL),
-	    SDT_BOOL(Settings, station.modified_catchment,                                          0, 0,  true,                    STR_CONFIG_PATCHES_CATCHMENT,              NULL),
-	SDT_CONDBOOL(Settings, order.gradual_loading,                           40, SL_MAX_VERSION, 0, 0,  true,                    STR_CONFIG_PATCHES_GRADUAL_LOADING,        NULL),
-	SDT_CONDBOOL(Settings, construction.road_stop_on_town_road,             47, SL_MAX_VERSION, 0, 0,  true,                    STR_CONFIG_PATCHES_STOP_ON_TOWN_ROAD,      NULL),
-	SDT_CONDBOOL(Settings, station.adjacent_stations,                       62, SL_MAX_VERSION, 0, 0,  true,                    STR_CONFIG_PATCHES_ADJACENT_STATIONS,      NULL),
-	SDT_CONDBOOL(Settings, economy.station_noise_level,                     96, SL_MAX_VERSION, 0, 0, false,                    STR_CONFIG_PATCHES_NOISE_LEVEL,            InvalidateTownViewWindow),
+	    SDT_BOOL(GameSettings, vehicle.realistic_acceleration,                                      0, 0, false,                    STR_CONFIG_PATCHES_REALISTICACCEL,         RealisticAccelerationChanged),
+	    SDT_BOOL(GameSettings, pf.forbid_90_deg,                                                    0, 0, false,                    STR_CONFIG_PATCHES_FORBID_90_DEG,          NULL),
+	    SDT_BOOL(GameSettings, vehicle.mammoth_trains,                                              0,NN,  true,                    STR_CONFIG_PATCHES_MAMMOTHTRAINS,          NULL),
+	    SDT_BOOL(GameSettings, order.gotodepot,                                                     0, 0,  true,                    STR_CONFIG_PATCHES_GOTODEPOT,              NULL),
+	    SDT_BOOL(GameSettings, pf.roadveh_queue,                                                    0, 0,  true,                    STR_CONFIG_PATCHES_ROADVEH_QUEUE,          NULL),
 
-	    SDT_BOOL(Settings, economy.inflation,                                                   0, 0,  true,                    STR_CONFIG_PATCHES_INFLATION,              NULL),
-	     SDT_VAR(Settings, construction.raw_industry_construction, SLE_UINT8,                   0,MS,     0,     0,       2, 0, STR_CONFIG_PATCHES_RAW_INDUSTRY_CONSTRUCTION_METHOD, InvalidateBuildIndustryWindow),
-	    SDT_BOOL(Settings, economy.multiple_industry_per_town,                                  0, 0, false,                    STR_CONFIG_PATCHES_MULTIPINDTOWN,          NULL),
-	    SDT_BOOL(Settings, economy.same_industry_close,                                         0, 0, false,                    STR_CONFIG_PATCHES_SAMEINDCLOSE,           NULL),
-	    SDT_BOOL(Settings, economy.bribe,                                                       0, 0,  true,                    STR_CONFIG_PATCHES_BRIBE,                  NULL),
-	SDT_CONDBOOL(Settings, economy.exclusive_rights,                        79, SL_MAX_VERSION, 0, 0,  true,                    STR_CONFIG_PATCHES_ALLOW_EXCLUSIVE,        NULL),
-	SDT_CONDBOOL(Settings, economy.give_money,                              79, SL_MAX_VERSION, 0, 0,  true,                    STR_CONFIG_PATCHES_ALLOW_GIVE_MONEY,       NULL),
-	     SDT_VAR(Settings, game_creation.snow_line_height,       SLE_UINT8,                     0, 0,     7,     2,      13, 0, STR_CONFIG_PATCHES_SNOWLINE_HEIGHT,        NULL),
-	     SDT_VAR(Settings, gui.colored_news_year,                SLE_INT32,                     0,NC,  2000,MIN_YEAR,MAX_YEAR,1,STR_CONFIG_PATCHES_COLORED_NEWS_YEAR,      NULL),
-	     SDT_VAR(Settings, game_creation.starting_year,          SLE_INT32,                     0,NC,  1950,MIN_YEAR,MAX_YEAR,1,STR_CONFIG_PATCHES_STARTING_YEAR,          NULL),
-	     SDT_VAR(Settings, gui.ending_year,                      SLE_INT32,                    0,NC|NO,2051,MIN_YEAR,MAX_YEAR,1,STR_CONFIG_PATCHES_ENDING_YEAR,            NULL),
-	    SDT_BOOL(Settings, economy.smooth_economy,                                              0, 0,  true,                    STR_CONFIG_PATCHES_SMOOTH_ECONOMY,         NULL),
-	    SDT_BOOL(Settings, economy.allow_shares,                                                0, 0, false,                    STR_CONFIG_PATCHES_ALLOW_SHARES,           NULL),
-	 SDT_CONDVAR(Settings, economy.town_growth_rate,             SLE_UINT8, 54, SL_MAX_VERSION, 0, MS,    2,     0,       4, 0, STR_CONFIG_PATCHES_TOWN_GROWTH,            NULL),
-	 SDT_CONDVAR(Settings, economy.larger_towns,                 SLE_UINT8, 54, SL_MAX_VERSION, 0, D0,    4,     0,     255, 1, STR_CONFIG_PATCHES_LARGER_TOWNS,           NULL),
-	 SDT_CONDVAR(Settings, economy.initial_city_size,            SLE_UINT8, 56, SL_MAX_VERSION, 0, 0,     2,     1,      10, 1, STR_CONFIG_PATCHES_CITY_SIZE_MULTIPLIER,   NULL),
-	SDT_CONDBOOL(Settings, economy.mod_road_rebuild,                        77, SL_MAX_VERSION, 0, 0, false,                    STR_CONFIG_MODIFIED_ROAD_REBUILD,          NULL),
+	SDT_CONDBOOL(GameSettings, pf.new_pathfinding_all,                           0,             86, 0, 0, false,                    STR_NULL,                                  NULL),
+	SDT_CONDBOOL(GameSettings, pf.yapf.ship_use_yapf,                           28,             86, 0, 0, false,                    STR_NULL,                                  NULL),
+	SDT_CONDBOOL(GameSettings, pf.yapf.road_use_yapf,                           28,             86, 0, 0,  true,                    STR_NULL,                                  NULL),
+	SDT_CONDBOOL(GameSettings, pf.yapf.rail_use_yapf,                           28,             86, 0, 0,  true,                    STR_NULL,                                  NULL),
+
+	 SDT_CONDVAR(GameSettings, pf.pathfinder_for_trains,             SLE_UINT8, 87, SL_MAX_VERSION, 0, MS,    2,     0,       2, 1, STR_CONFIG_PATCHES_PATHFINDER_FOR_TRAINS,  NULL),
+	 SDT_CONDVAR(GameSettings, pf.pathfinder_for_roadvehs,           SLE_UINT8, 87, SL_MAX_VERSION, 0, MS,    2,     0,       2, 1, STR_CONFIG_PATCHES_PATHFINDER_FOR_ROADVEH, NULL),
+	 SDT_CONDVAR(GameSettings, pf.pathfinder_for_ships,              SLE_UINT8, 87, SL_MAX_VERSION, 0, MS,    0,     0,       2, 1, STR_CONFIG_PATCHES_PATHFINDER_FOR_SHIPS,   NULL),
+
+	    SDT_BOOL(GameSettings, vehicle.never_expire_vehicles,                                       0,NN, false,                    STR_CONFIG_PATCHES_NEVER_EXPIRE_VEHICLES,  NULL),
+	     SDT_VAR(GameSettings, vehicle.max_trains,                  SLE_UINT16,                     0, 0,   500,     0,    5000, 0, STR_CONFIG_PATCHES_MAX_TRAINS,             RedrawScreen),
+	     SDT_VAR(GameSettings, vehicle.max_roadveh,                 SLE_UINT16,                     0, 0,   500,     0,    5000, 0, STR_CONFIG_PATCHES_MAX_ROADVEH,            RedrawScreen),
+	     SDT_VAR(GameSettings, vehicle.max_aircraft,                SLE_UINT16,                     0, 0,   200,     0,    5000, 0, STR_CONFIG_PATCHES_MAX_AIRCRAFT,           RedrawScreen),
+	     SDT_VAR(GameSettings, vehicle.max_ships,                   SLE_UINT16,                     0, 0,   300,     0,    5000, 0, STR_CONFIG_PATCHES_MAX_SHIPS,              RedrawScreen),
+	    SDT_BOOL(GameSettings, vehicle.servint_ispercent,                                           0, 0, false,                    STR_CONFIG_PATCHES_SERVINT_ISPERCENT,      CheckInterval),
+	     SDT_VAR(GameSettings, vehicle.servint_trains,              SLE_UINT16,                     0,D0,   150,     5,     800, 0, STR_CONFIG_PATCHES_SERVINT_TRAINS,         InValidateDetailsWindow),
+	     SDT_VAR(GameSettings, vehicle.servint_roadveh,             SLE_UINT16,                     0,D0,   150,     5,     800, 0, STR_CONFIG_PATCHES_SERVINT_ROADVEH,        InValidateDetailsWindow),
+	     SDT_VAR(GameSettings, vehicle.servint_ships,               SLE_UINT16,                     0,D0,   360,     5,     800, 0, STR_CONFIG_PATCHES_SERVINT_SHIPS,          InValidateDetailsWindow),
+	     SDT_VAR(GameSettings, vehicle.servint_aircraft,            SLE_UINT16,                     0,D0,   100,     5,     800, 0, STR_CONFIG_PATCHES_SERVINT_AIRCRAFT,       InValidateDetailsWindow),
+	    SDT_BOOL(GameSettings, order.no_servicing_if_no_breakdowns,                                 0, 0, false,                    STR_CONFIG_PATCHES_NOSERVICE,              NULL),
+	    SDT_BOOL(GameSettings, vehicle.wagon_speed_limits,                                          0,NN,  true,                    STR_CONFIG_PATCHES_WAGONSPEEDLIMITS,       UpdateConsists),
+	SDT_CONDBOOL(GameSettings, vehicle.disable_elrails,                         38, SL_MAX_VERSION, 0,NN, false,                    STR_CONFIG_PATCHES_DISABLE_ELRAILS,        SettingsDisableElrail),
+	 SDT_CONDVAR(GameSettings, vehicle.freight_trains,               SLE_UINT8, 39, SL_MAX_VERSION, 0,NN,     1,     1,     255, 1, STR_CONFIG_PATCHES_FREIGHT_TRAINS,         NULL),
+	SDT_CONDBOOL(GameSettings, order.timetabling,                               67, SL_MAX_VERSION, 0, 0,  true,                    STR_CONFIG_PATCHES_TIMETABLE_ALLOW,        NULL),
+	 SDT_CONDVAR(GameSettings, vehicle.plane_speed,                  SLE_UINT8, 90, SL_MAX_VERSION, 0, 0,     4,     1,       4, 0, STR_CONFIG_PATCHES_PLANE_SPEED,            NULL),
+	SDT_CONDBOOL(GameSettings, vehicle.dynamic_engines,                         95, SL_MAX_VERSION, 0,NN, false,                    STR_CONFIG_PATCHES_DYNAMIC_ENGINES,        NULL),
+
+	    SDT_BOOL(GameSettings, station.join_stations,                                               0, 0,  true,                    STR_CONFIG_PATCHES_JOINSTATIONS,           NULL),
+ SDTC_CONDBOOL(              gui.sg_full_load_any,                             0,             92, 0, 0 , true,                    STR_NULL,                                  NULL),
+	    SDT_BOOL(GameSettings, order.improved_load,                                                 0,NN,  true,                    STR_CONFIG_PATCHES_IMPROVEDLOAD,           NULL),
+	    SDT_BOOL(GameSettings, order.selectgoods,                                                   0, 0,  true,                    STR_CONFIG_PATCHES_SELECTGOODS,            NULL),
+ SDTC_CONDBOOL(              gui.sg_new_nonstop,                               0,             92, 0, 0, false,                    STR_NULL,                                  NULL),
+	    SDT_BOOL(GameSettings, station.nonuniform_stations,                                         0,NN,  true,                    STR_CONFIG_PATCHES_NONUNIFORM_STATIONS,    NULL),
+	     SDT_VAR(GameSettings, station.station_spread,               SLE_UINT8,                     0, 0,    12,     4,      64, 0, STR_CONFIG_PATCHES_STATION_SPREAD,         InvalidateStationBuildWindow),
+	    SDT_BOOL(GameSettings, order.serviceathelipad,                                              0, 0,  true,                    STR_CONFIG_PATCHES_SERVICEATHELIPAD,       NULL),
+	    SDT_BOOL(GameSettings, station.modified_catchment,                                          0, 0,  true,                    STR_CONFIG_PATCHES_CATCHMENT,              NULL),
+	SDT_CONDBOOL(GameSettings, order.gradual_loading,                           40, SL_MAX_VERSION, 0, 0,  true,                    STR_CONFIG_PATCHES_GRADUAL_LOADING,        NULL),
+	SDT_CONDBOOL(GameSettings, construction.road_stop_on_town_road,             47, SL_MAX_VERSION, 0, 0,  true,                    STR_CONFIG_PATCHES_STOP_ON_TOWN_ROAD,      NULL),
+	SDT_CONDBOOL(GameSettings, station.adjacent_stations,                       62, SL_MAX_VERSION, 0, 0,  true,                    STR_CONFIG_PATCHES_ADJACENT_STATIONS,      NULL),
+	SDT_CONDBOOL(GameSettings, economy.station_noise_level,                     96, SL_MAX_VERSION, 0, 0, false,                    STR_CONFIG_PATCHES_NOISE_LEVEL,            InvalidateTownViewWindow),
+
+	    SDT_BOOL(GameSettings, economy.inflation,                                                   0, 0,  true,                    STR_CONFIG_PATCHES_INFLATION,              NULL),
+	     SDT_VAR(GameSettings, construction.raw_industry_construction, SLE_UINT8,                   0,MS,     0,     0,       2, 0, STR_CONFIG_PATCHES_RAW_INDUSTRY_CONSTRUCTION_METHOD, InvalidateBuildIndustryWindow),
+	    SDT_BOOL(GameSettings, economy.multiple_industry_per_town,                                  0, 0, false,                    STR_CONFIG_PATCHES_MULTIPINDTOWN,          NULL),
+	    SDT_BOOL(GameSettings, economy.same_industry_close,                                         0, 0, false,                    STR_CONFIG_PATCHES_SAMEINDCLOSE,           NULL),
+	    SDT_BOOL(GameSettings, economy.bribe,                                                       0, 0,  true,                    STR_CONFIG_PATCHES_BRIBE,                  NULL),
+	SDT_CONDBOOL(GameSettings, economy.exclusive_rights,                        79, SL_MAX_VERSION, 0, 0,  true,                    STR_CONFIG_PATCHES_ALLOW_EXCLUSIVE,        NULL),
+	SDT_CONDBOOL(GameSettings, economy.give_money,                              79, SL_MAX_VERSION, 0, 0,  true,                    STR_CONFIG_PATCHES_ALLOW_GIVE_MONEY,       NULL),
+	     SDT_VAR(GameSettings, game_creation.snow_line_height,       SLE_UINT8,                     0, 0,     7,     2,      13, 0, STR_CONFIG_PATCHES_SNOWLINE_HEIGHT,        NULL),
+	    SDTC_VAR(              gui.colored_news_year,                SLE_INT32,                     0,NC,  2000,MIN_YEAR,MAX_YEAR,1,STR_CONFIG_PATCHES_COLORED_NEWS_YEAR,      NULL),
+	     SDT_VAR(GameSettings, game_creation.starting_year,          SLE_INT32,                     0,NC,  1950,MIN_YEAR,MAX_YEAR,1,STR_CONFIG_PATCHES_STARTING_YEAR,          NULL),
+	    SDTC_VAR(              gui.ending_year,                      SLE_INT32,                    0,NC|NO,2051,MIN_YEAR,MAX_YEAR,1,STR_CONFIG_PATCHES_ENDING_YEAR,            NULL),
+	    SDT_BOOL(GameSettings, economy.smooth_economy,                                              0, 0,  true,                    STR_CONFIG_PATCHES_SMOOTH_ECONOMY,         NULL),
+	    SDT_BOOL(GameSettings, economy.allow_shares,                                                0, 0, false,                    STR_CONFIG_PATCHES_ALLOW_SHARES,           NULL),
+	 SDT_CONDVAR(GameSettings, economy.town_growth_rate,             SLE_UINT8, 54, SL_MAX_VERSION, 0, MS,    2,     0,       4, 0, STR_CONFIG_PATCHES_TOWN_GROWTH,            NULL),
+	 SDT_CONDVAR(GameSettings, economy.larger_towns,                 SLE_UINT8, 54, SL_MAX_VERSION, 0, D0,    4,     0,     255, 1, STR_CONFIG_PATCHES_LARGER_TOWNS,           NULL),
+	 SDT_CONDVAR(GameSettings, economy.initial_city_size,            SLE_UINT8, 56, SL_MAX_VERSION, 0, 0,     2,     1,      10, 1, STR_CONFIG_PATCHES_CITY_SIZE_MULTIPLIER,   NULL),
+	SDT_CONDBOOL(GameSettings, economy.mod_road_rebuild,                        77, SL_MAX_VERSION, 0, 0, false,                    STR_CONFIG_MODIFIED_ROAD_REBUILD,          NULL),
 
 	SDT_CONDNULL(1, 0, SL_NOAI_MAX_VERSION), // ai-new setting, became invalid with new AI system. Part of the NoAI 'hack' to retain savegame compatability with trunk.
-	    SDT_BOOL(Settings, ai.ai_in_multiplayer,                                                0, 0, false,                    STR_CONFIG_PATCHES_AI_IN_MULTIPLAYER,      Ai_In_Multiplayer_Warning),
-	    SDT_BOOL(Settings, ai.ai_disable_veh_train,                                             0, 0, false,                    STR_CONFIG_PATCHES_AI_BUILDS_TRAINS,       NULL),
-	    SDT_BOOL(Settings, ai.ai_disable_veh_roadveh,                                           0, 0, false,                    STR_CONFIG_PATCHES_AI_BUILDS_ROADVEH,      NULL),
-	    SDT_BOOL(Settings, ai.ai_disable_veh_aircraft,                                          0, 0, false,                    STR_CONFIG_PATCHES_AI_BUILDS_AIRCRAFT,     NULL),
-	    SDT_BOOL(Settings, ai.ai_disable_veh_ship,                                              0, 0, false,                    STR_CONFIG_PATCHES_AI_BUILDS_SHIPS,        NULL),
-
-	     SDT_VAR(Settings, vehicle.extend_vehicle_life,          SLE_UINT8,                     0, 0,     0,     0,     100, 0, STR_NULL,                                  NULL),
-	     SDT_VAR(Settings, economy.dist_local_authority,         SLE_UINT8,                     0, 0,    20,     5,      60, 0, STR_NULL,                                  NULL),
-	     SDT_VAR(Settings, pf.wait_oneway_signal,                SLE_UINT8,                     0, 0,    15,     2,     100, 0, STR_NULL,                                  NULL),
-	     SDT_VAR(Settings, pf.wait_twoway_signal,                SLE_UINT8,                     0, 0,    41,     2,     100, 0, STR_NULL,                                  NULL),
-	SDT_CONDLISTO(Settings, economy.town_noise_population, 3,   SLE_UINT16, 96, SL_MAX_VERSION, 0,D0, "800,2000,4000",          STR_NULL,                                  NULL, CheckNoiseToleranceLevel),
+	    SDT_BOOL(GameSettings, ai.ai_in_multiplayer,                                                0, 0, false,                    STR_CONFIG_PATCHES_AI_IN_MULTIPLAYER,      Ai_In_Multiplayer_Warning),
+	    SDT_BOOL(GameSettings, ai.ai_disable_veh_train,                                             0, 0, false,                    STR_CONFIG_PATCHES_AI_BUILDS_TRAINS,       NULL),
+	    SDT_BOOL(GameSettings, ai.ai_disable_veh_roadveh,                                           0, 0, false,                    STR_CONFIG_PATCHES_AI_BUILDS_ROADVEH,      NULL),
+	    SDT_BOOL(GameSettings, ai.ai_disable_veh_aircraft,                                          0, 0, false,                    STR_CONFIG_PATCHES_AI_BUILDS_AIRCRAFT,     NULL),
+	    SDT_BOOL(GameSettings, ai.ai_disable_veh_ship,                                              0, 0, false,                    STR_CONFIG_PATCHES_AI_BUILDS_SHIPS,        NULL),
 
-	     SDT_VAR(Settings, pf.opf.pf_maxlength,                          SLE_UINT16,                     0, 0,  4096,                    64,   65535, 0, STR_NULL,         NULL),
-	     SDT_VAR(Settings, pf.opf.pf_maxdepth,                            SLE_UINT8,                     0, 0,    48,                     4,     255, 0, STR_NULL,         NULL),
+	     SDT_VAR(GameSettings, vehicle.extend_vehicle_life,          SLE_UINT8,                     0, 0,     0,     0,     100, 0, STR_NULL,                                  NULL),
+	     SDT_VAR(GameSettings, economy.dist_local_authority,         SLE_UINT8,                     0, 0,    20,     5,      60, 0, STR_NULL,                                  NULL),
+	     SDT_VAR(GameSettings, pf.wait_oneway_signal,                SLE_UINT8,                     0, 0,    15,     2,     100, 0, STR_NULL,                                  NULL),
+	     SDT_VAR(GameSettings, pf.wait_twoway_signal,                SLE_UINT8,                     0, 0,    41,     2,     100, 0, STR_NULL,                                  NULL),
+	SDT_CONDLISTO(GameSettings, economy.town_noise_population, 3,   SLE_UINT16, 96, SL_MAX_VERSION, 0,D0, "800,2000,4000",          STR_NULL,                                  NULL, CheckNoiseToleranceLevel),
 
-	     SDT_VAR(Settings, pf.npf.npf_max_search_nodes,                    SLE_UINT,                     0, 0, 10000,                   500,  100000, 0, STR_NULL,         NULL),
-	     SDT_VAR(Settings, pf.npf.npf_rail_firstred_penalty,               SLE_UINT,                     0, 0, ( 10 * NPF_TILE_LENGTH),   0,  100000, 0, STR_NULL,         NULL),
-	     SDT_VAR(Settings, pf.npf.npf_rail_firstred_exit_penalty,          SLE_UINT,                     0, 0, (100 * NPF_TILE_LENGTH),   0,  100000, 0, STR_NULL,         NULL),
-	     SDT_VAR(Settings, pf.npf.npf_rail_lastred_penalty,                SLE_UINT,                     0, 0, ( 10 * NPF_TILE_LENGTH),   0,  100000, 0, STR_NULL,         NULL),
-	     SDT_VAR(Settings, pf.npf.npf_rail_station_penalty,                SLE_UINT,                     0, 0, (  1 * NPF_TILE_LENGTH),   0,  100000, 0, STR_NULL,         NULL),
-	     SDT_VAR(Settings, pf.npf.npf_rail_slope_penalty,                  SLE_UINT,                     0, 0, (  1 * NPF_TILE_LENGTH),   0,  100000, 0, STR_NULL,         NULL),
-	     SDT_VAR(Settings, pf.npf.npf_rail_curve_penalty,                  SLE_UINT,                     0, 0, 1,                         0,  100000, 0, STR_NULL,         NULL),
-	     SDT_VAR(Settings, pf.npf.npf_rail_depot_reverse_penalty,          SLE_UINT,                     0, 0, ( 50 * NPF_TILE_LENGTH),   0,  100000, 0, STR_NULL,         NULL),
-	     SDT_VAR(Settings, pf.npf.npf_buoy_penalty,                        SLE_UINT,                     0, 0, (  2 * NPF_TILE_LENGTH),   0,  100000, 0, STR_NULL,         NULL),
-	     SDT_VAR(Settings, pf.npf.npf_water_curve_penalty,                 SLE_UINT,                     0, 0, (NPF_TILE_LENGTH / 4),     0,  100000, 0, STR_NULL,         NULL),
-	     SDT_VAR(Settings, pf.npf.npf_road_curve_penalty,                  SLE_UINT,                     0, 0, 1,                         0,  100000, 0, STR_NULL,         NULL),
-	     SDT_VAR(Settings, pf.npf.npf_crossing_penalty,                    SLE_UINT,                     0, 0, (  3 * NPF_TILE_LENGTH),   0,  100000, 0, STR_NULL,         NULL),
-	 SDT_CONDVAR(Settings, pf.npf.npf_road_drive_through_penalty,          SLE_UINT, 47, SL_MAX_VERSION, 0, 0, (  8 * NPF_TILE_LENGTH),   0,  100000, 0, STR_NULL,         NULL),
+	     SDT_VAR(GameSettings, pf.opf.pf_maxlength,                          SLE_UINT16,                     0, 0,  4096,                    64,   65535, 0, STR_NULL,         NULL),
+	     SDT_VAR(GameSettings, pf.opf.pf_maxdepth,                            SLE_UINT8,                     0, 0,    48,                     4,     255, 0, STR_NULL,         NULL),
+
+	     SDT_VAR(GameSettings, pf.npf.npf_max_search_nodes,                    SLE_UINT,                     0, 0, 10000,                   500,  100000, 0, STR_NULL,         NULL),
+	     SDT_VAR(GameSettings, pf.npf.npf_rail_firstred_penalty,               SLE_UINT,                     0, 0, ( 10 * NPF_TILE_LENGTH),   0,  100000, 0, STR_NULL,         NULL),
+	     SDT_VAR(GameSettings, pf.npf.npf_rail_firstred_exit_penalty,          SLE_UINT,                     0, 0, (100 * NPF_TILE_LENGTH),   0,  100000, 0, STR_NULL,         NULL),
+	     SDT_VAR(GameSettings, pf.npf.npf_rail_lastred_penalty,                SLE_UINT,                     0, 0, ( 10 * NPF_TILE_LENGTH),   0,  100000, 0, STR_NULL,         NULL),
+	     SDT_VAR(GameSettings, pf.npf.npf_rail_station_penalty,                SLE_UINT,                     0, 0, (  1 * NPF_TILE_LENGTH),   0,  100000, 0, STR_NULL,         NULL),
+	     SDT_VAR(GameSettings, pf.npf.npf_rail_slope_penalty,                  SLE_UINT,                     0, 0, (  1 * NPF_TILE_LENGTH),   0,  100000, 0, STR_NULL,         NULL),
+	     SDT_VAR(GameSettings, pf.npf.npf_rail_curve_penalty,                  SLE_UINT,                     0, 0, 1,                         0,  100000, 0, STR_NULL,         NULL),
+	     SDT_VAR(GameSettings, pf.npf.npf_rail_depot_reverse_penalty,          SLE_UINT,                     0, 0, ( 50 * NPF_TILE_LENGTH),   0,  100000, 0, STR_NULL,         NULL),
+	     SDT_VAR(GameSettings, pf.npf.npf_buoy_penalty,                        SLE_UINT,                     0, 0, (  2 * NPF_TILE_LENGTH),   0,  100000, 0, STR_NULL,         NULL),
+	     SDT_VAR(GameSettings, pf.npf.npf_water_curve_penalty,                 SLE_UINT,                     0, 0, (NPF_TILE_LENGTH / 4),     0,  100000, 0, STR_NULL,         NULL),
+	     SDT_VAR(GameSettings, pf.npf.npf_road_curve_penalty,                  SLE_UINT,                     0, 0, 1,                         0,  100000, 0, STR_NULL,         NULL),
+	     SDT_VAR(GameSettings, pf.npf.npf_crossing_penalty,                    SLE_UINT,                     0, 0, (  3 * NPF_TILE_LENGTH),   0,  100000, 0, STR_NULL,         NULL),
+	 SDT_CONDVAR(GameSettings, pf.npf.npf_road_drive_through_penalty,          SLE_UINT, 47, SL_MAX_VERSION, 0, 0, (  8 * NPF_TILE_LENGTH),   0,  100000, 0, STR_NULL,         NULL),
 
 
-	SDT_CONDBOOL(Settings, pf.yapf.disable_node_optimization,                        28, SL_MAX_VERSION, 0, 0, false,                                    STR_NULL,         NULL),
-	 SDT_CONDVAR(Settings, pf.yapf.max_search_nodes,                       SLE_UINT, 28, SL_MAX_VERSION, 0, 0, 10000,                   500, 1000000, 0, STR_NULL,         NULL),
-	SDT_CONDBOOL(Settings, pf.yapf.rail_firstred_twoway_eol,                         28, SL_MAX_VERSION, 0, 0,  true,                                    STR_NULL,         NULL),
-	 SDT_CONDVAR(Settings, pf.yapf.rail_firstred_penalty,                  SLE_UINT, 28, SL_MAX_VERSION, 0, 0,    10 * YAPF_TILE_LENGTH,  0, 1000000, 0, STR_NULL,         NULL),
-	 SDT_CONDVAR(Settings, pf.yapf.rail_firstred_exit_penalty,             SLE_UINT, 28, SL_MAX_VERSION, 0, 0,   100 * YAPF_TILE_LENGTH,  0, 1000000, 0, STR_NULL,         NULL),
-	 SDT_CONDVAR(Settings, pf.yapf.rail_lastred_penalty,                   SLE_UINT, 28, SL_MAX_VERSION, 0, 0,    10 * YAPF_TILE_LENGTH,  0, 1000000, 0, STR_NULL,         NULL),
-	 SDT_CONDVAR(Settings, pf.yapf.rail_lastred_exit_penalty,              SLE_UINT, 28, SL_MAX_VERSION, 0, 0,   100 * YAPF_TILE_LENGTH,  0, 1000000, 0, STR_NULL,         NULL),
-	 SDT_CONDVAR(Settings, pf.yapf.rail_station_penalty,                   SLE_UINT, 28, SL_MAX_VERSION, 0, 0,    30 * YAPF_TILE_LENGTH,  0, 1000000, 0, STR_NULL,         NULL),
-	 SDT_CONDVAR(Settings, pf.yapf.rail_slope_penalty,                     SLE_UINT, 28, SL_MAX_VERSION, 0, 0,     2 * YAPF_TILE_LENGTH,  0, 1000000, 0, STR_NULL,         NULL),
-	 SDT_CONDVAR(Settings, pf.yapf.rail_curve45_penalty,                   SLE_UINT, 28, SL_MAX_VERSION, 0, 0,     1 * YAPF_TILE_LENGTH,  0, 1000000, 0, STR_NULL,         NULL),
-	 SDT_CONDVAR(Settings, pf.yapf.rail_curve90_penalty,                   SLE_UINT, 28, SL_MAX_VERSION, 0, 0,     6 * YAPF_TILE_LENGTH,  0, 1000000, 0, STR_NULL,         NULL),
-	 SDT_CONDVAR(Settings, pf.yapf.rail_depot_reverse_penalty,             SLE_UINT, 28, SL_MAX_VERSION, 0, 0,    50 * YAPF_TILE_LENGTH,  0, 1000000, 0, STR_NULL,         NULL),
-	 SDT_CONDVAR(Settings, pf.yapf.rail_crossing_penalty,                  SLE_UINT, 28, SL_MAX_VERSION, 0, 0,     3 * YAPF_TILE_LENGTH,  0, 1000000, 0, STR_NULL,         NULL),
-	 SDT_CONDVAR(Settings, pf.yapf.rail_look_ahead_max_signals,            SLE_UINT, 28, SL_MAX_VERSION, 0, 0,    10,                     1,     100, 0, STR_NULL,         NULL),
-	 SDT_CONDVAR(Settings, pf.yapf.rail_look_ahead_signal_p0,               SLE_INT, 28, SL_MAX_VERSION, 0, 0,   500,              -1000000, 1000000, 0, STR_NULL,         NULL),
-	 SDT_CONDVAR(Settings, pf.yapf.rail_look_ahead_signal_p1,               SLE_INT, 28, SL_MAX_VERSION, 0, 0,  -100,              -1000000, 1000000, 0, STR_NULL,         NULL),
-	 SDT_CONDVAR(Settings, pf.yapf.rail_look_ahead_signal_p2,               SLE_INT, 28, SL_MAX_VERSION, 0, 0,     5,              -1000000, 1000000, 0, STR_NULL,         NULL),
-	 SDT_CONDVAR(Settings, pf.yapf.rail_longer_platform_penalty,           SLE_UINT, 33, SL_MAX_VERSION, 0, 0,     8 * YAPF_TILE_LENGTH,  0,   20000, 0, STR_NULL,         NULL),
-	 SDT_CONDVAR(Settings, pf.yapf.rail_longer_platform_per_tile_penalty,  SLE_UINT, 33, SL_MAX_VERSION, 0, 0,     0 * YAPF_TILE_LENGTH,  0,   20000, 0, STR_NULL,         NULL),
-	 SDT_CONDVAR(Settings, pf.yapf.rail_shorter_platform_penalty,          SLE_UINT, 33, SL_MAX_VERSION, 0, 0,    40 * YAPF_TILE_LENGTH,  0,   20000, 0, STR_NULL,         NULL),
-	 SDT_CONDVAR(Settings, pf.yapf.rail_shorter_platform_per_tile_penalty, SLE_UINT, 33, SL_MAX_VERSION, 0, 0,     0 * YAPF_TILE_LENGTH,  0,   20000, 0, STR_NULL,         NULL),
-	 SDT_CONDVAR(Settings, pf.yapf.road_slope_penalty,                     SLE_UINT, 33, SL_MAX_VERSION, 0, 0,     2 * YAPF_TILE_LENGTH,  0, 1000000, 0, STR_NULL,         NULL),
-	 SDT_CONDVAR(Settings, pf.yapf.road_curve_penalty,                     SLE_UINT, 33, SL_MAX_VERSION, 0, 0,     1 * YAPF_TILE_LENGTH,  0, 1000000, 0, STR_NULL,         NULL),
-	 SDT_CONDVAR(Settings, pf.yapf.road_crossing_penalty,                  SLE_UINT, 33, SL_MAX_VERSION, 0, 0,     3 * YAPF_TILE_LENGTH,  0, 1000000, 0, STR_NULL,         NULL),
-	 SDT_CONDVAR(Settings, pf.yapf.road_stop_penalty,                      SLE_UINT, 47, SL_MAX_VERSION, 0, 0,     8 * YAPF_TILE_LENGTH,  0, 1000000, 0, STR_NULL,         NULL),
+	SDT_CONDBOOL(GameSettings, pf.yapf.disable_node_optimization,                        28, SL_MAX_VERSION, 0, 0, false,                                    STR_NULL,         NULL),
+	 SDT_CONDVAR(GameSettings, pf.yapf.max_search_nodes,                       SLE_UINT, 28, SL_MAX_VERSION, 0, 0, 10000,                   500, 1000000, 0, STR_NULL,         NULL),
+	SDT_CONDBOOL(GameSettings, pf.yapf.rail_firstred_twoway_eol,                         28, SL_MAX_VERSION, 0, 0,  true,                                    STR_NULL,         NULL),
+	 SDT_CONDVAR(GameSettings, pf.yapf.rail_firstred_penalty,                  SLE_UINT, 28, SL_MAX_VERSION, 0, 0,    10 * YAPF_TILE_LENGTH,  0, 1000000, 0, STR_NULL,         NULL),
+	 SDT_CONDVAR(GameSettings, pf.yapf.rail_firstred_exit_penalty,             SLE_UINT, 28, SL_MAX_VERSION, 0, 0,   100 * YAPF_TILE_LENGTH,  0, 1000000, 0, STR_NULL,         NULL),
+	 SDT_CONDVAR(GameSettings, pf.yapf.rail_lastred_penalty,                   SLE_UINT, 28, SL_MAX_VERSION, 0, 0,    10 * YAPF_TILE_LENGTH,  0, 1000000, 0, STR_NULL,         NULL),
+	 SDT_CONDVAR(GameSettings, pf.yapf.rail_lastred_exit_penalty,              SLE_UINT, 28, SL_MAX_VERSION, 0, 0,   100 * YAPF_TILE_LENGTH,  0, 1000000, 0, STR_NULL,         NULL),
+	 SDT_CONDVAR(GameSettings, pf.yapf.rail_station_penalty,                   SLE_UINT, 28, SL_MAX_VERSION, 0, 0,    30 * YAPF_TILE_LENGTH,  0, 1000000, 0, STR_NULL,         NULL),
+	 SDT_CONDVAR(GameSettings, pf.yapf.rail_slope_penalty,                     SLE_UINT, 28, SL_MAX_VERSION, 0, 0,     2 * YAPF_TILE_LENGTH,  0, 1000000, 0, STR_NULL,         NULL),
+	 SDT_CONDVAR(GameSettings, pf.yapf.rail_curve45_penalty,                   SLE_UINT, 28, SL_MAX_VERSION, 0, 0,     1 * YAPF_TILE_LENGTH,  0, 1000000, 0, STR_NULL,         NULL),
+	 SDT_CONDVAR(GameSettings, pf.yapf.rail_curve90_penalty,                   SLE_UINT, 28, SL_MAX_VERSION, 0, 0,     6 * YAPF_TILE_LENGTH,  0, 1000000, 0, STR_NULL,         NULL),
+	 SDT_CONDVAR(GameSettings, pf.yapf.rail_depot_reverse_penalty,             SLE_UINT, 28, SL_MAX_VERSION, 0, 0,    50 * YAPF_TILE_LENGTH,  0, 1000000, 0, STR_NULL,         NULL),
+	 SDT_CONDVAR(GameSettings, pf.yapf.rail_crossing_penalty,                  SLE_UINT, 28, SL_MAX_VERSION, 0, 0,     3 * YAPF_TILE_LENGTH,  0, 1000000, 0, STR_NULL,         NULL),
+	 SDT_CONDVAR(GameSettings, pf.yapf.rail_look_ahead_max_signals,            SLE_UINT, 28, SL_MAX_VERSION, 0, 0,    10,                     1,     100, 0, STR_NULL,         NULL),
+	 SDT_CONDVAR(GameSettings, pf.yapf.rail_look_ahead_signal_p0,               SLE_INT, 28, SL_MAX_VERSION, 0, 0,   500,              -1000000, 1000000, 0, STR_NULL,         NULL),
+	 SDT_CONDVAR(GameSettings, pf.yapf.rail_look_ahead_signal_p1,               SLE_INT, 28, SL_MAX_VERSION, 0, 0,  -100,              -1000000, 1000000, 0, STR_NULL,         NULL),
+	 SDT_CONDVAR(GameSettings, pf.yapf.rail_look_ahead_signal_p2,               SLE_INT, 28, SL_MAX_VERSION, 0, 0,     5,              -1000000, 1000000, 0, STR_NULL,         NULL),
+	 SDT_CONDVAR(GameSettings, pf.yapf.rail_longer_platform_penalty,           SLE_UINT, 33, SL_MAX_VERSION, 0, 0,     8 * YAPF_TILE_LENGTH,  0,   20000, 0, STR_NULL,         NULL),
+	 SDT_CONDVAR(GameSettings, pf.yapf.rail_longer_platform_per_tile_penalty,  SLE_UINT, 33, SL_MAX_VERSION, 0, 0,     0 * YAPF_TILE_LENGTH,  0,   20000, 0, STR_NULL,         NULL),
+	 SDT_CONDVAR(GameSettings, pf.yapf.rail_shorter_platform_penalty,          SLE_UINT, 33, SL_MAX_VERSION, 0, 0,    40 * YAPF_TILE_LENGTH,  0,   20000, 0, STR_NULL,         NULL),
+	 SDT_CONDVAR(GameSettings, pf.yapf.rail_shorter_platform_per_tile_penalty, SLE_UINT, 33, SL_MAX_VERSION, 0, 0,     0 * YAPF_TILE_LENGTH,  0,   20000, 0, STR_NULL,         NULL),
+	 SDT_CONDVAR(GameSettings, pf.yapf.road_slope_penalty,                     SLE_UINT, 33, SL_MAX_VERSION, 0, 0,     2 * YAPF_TILE_LENGTH,  0, 1000000, 0, STR_NULL,         NULL),
+	 SDT_CONDVAR(GameSettings, pf.yapf.road_curve_penalty,                     SLE_UINT, 33, SL_MAX_VERSION, 0, 0,     1 * YAPF_TILE_LENGTH,  0, 1000000, 0, STR_NULL,         NULL),
+	 SDT_CONDVAR(GameSettings, pf.yapf.road_crossing_penalty,                  SLE_UINT, 33, SL_MAX_VERSION, 0, 0,     3 * YAPF_TILE_LENGTH,  0, 1000000, 0, STR_NULL,         NULL),
+	 SDT_CONDVAR(GameSettings, pf.yapf.road_stop_penalty,                      SLE_UINT, 47, SL_MAX_VERSION, 0, 0,     8 * YAPF_TILE_LENGTH,  0, 1000000, 0, STR_NULL,         NULL),
 
-	 SDT_CONDVAR(Settings, game_creation.land_generator,                  SLE_UINT8, 30, SL_MAX_VERSION, 0,MS,     1,                     0,       1, 0, STR_CONFIG_PATCHES_LAND_GENERATOR,        NULL),
-	 SDT_CONDVAR(Settings, game_creation.oil_refinery_limit,              SLE_UINT8, 30, SL_MAX_VERSION, 0, 0,    32,                    12,      48, 0, STR_CONFIG_PATCHES_OIL_REF_EDGE_DISTANCE, NULL),
-	 SDT_CONDVAR(Settings, game_creation.tgen_smoothness,                 SLE_UINT8, 30, SL_MAX_VERSION, 0,MS,     1,                     0,       3, 0, STR_CONFIG_PATCHES_ROUGHNESS_OF_TERRAIN,  NULL),
-	 SDT_CONDVAR(Settings, game_creation.generation_seed,                SLE_UINT32, 30, SL_MAX_VERSION, 0, 0,      GENERATE_NEW_SEED, 0, UINT32_MAX, 0, STR_NULL,                                 NULL),
-	 SDT_CONDVAR(Settings, game_creation.tree_placer,                     SLE_UINT8, 30, SL_MAX_VERSION, 0,MS,     2,                     0,       2, 0, STR_CONFIG_PATCHES_TREE_PLACER,           NULL),
-	     SDT_VAR(Settings, game_creation.heightmap_rotation,              SLE_UINT8,                     S,MS,     0,                     0,       1, 0, STR_CONFIG_PATCHES_HEIGHTMAP_ROTATION,    NULL),
-	     SDT_VAR(Settings, game_creation.se_flat_world_height,            SLE_UINT8,                     S, 0,     0,                     0,      15, 0, STR_CONFIG_PATCHES_SE_FLAT_WORLD_HEIGHT,  NULL),
+	 SDT_CONDVAR(GameSettings, game_creation.land_generator,                  SLE_UINT8, 30, SL_MAX_VERSION, 0,MS,     1,                     0,       1, 0, STR_CONFIG_PATCHES_LAND_GENERATOR,        NULL),
+	 SDT_CONDVAR(GameSettings, game_creation.oil_refinery_limit,              SLE_UINT8, 30, SL_MAX_VERSION, 0, 0,    32,                    12,      48, 0, STR_CONFIG_PATCHES_OIL_REF_EDGE_DISTANCE, NULL),
+	 SDT_CONDVAR(GameSettings, game_creation.tgen_smoothness,                 SLE_UINT8, 30, SL_MAX_VERSION, 0,MS,     1,                     0,       3, 0, STR_CONFIG_PATCHES_ROUGHNESS_OF_TERRAIN,  NULL),
+	 SDT_CONDVAR(GameSettings, game_creation.generation_seed,                SLE_UINT32, 30, SL_MAX_VERSION, 0, 0,      GENERATE_NEW_SEED, 0, UINT32_MAX, 0, STR_NULL,                                 NULL),
+	 SDT_CONDVAR(GameSettings, game_creation.tree_placer,                     SLE_UINT8, 30, SL_MAX_VERSION, 0,MS,     2,                     0,       2, 0, STR_CONFIG_PATCHES_TREE_PLACER,           NULL),
+	     SDT_VAR(GameSettings, game_creation.heightmap_rotation,              SLE_UINT8,                     S,MS,     0,                     0,       1, 0, STR_CONFIG_PATCHES_HEIGHTMAP_ROTATION,    NULL),
+	     SDT_VAR(GameSettings, game_creation.se_flat_world_height,            SLE_UINT8,                     S, 0,     0,                     0,      15, 0, STR_CONFIG_PATCHES_SE_FLAT_WORLD_HEIGHT,  NULL),
 
- SDT_CONDOMANY(Settings, gui.currency,                                  SLE_UINT8, 97, SL_MAX_VERSION, N, 0, 0, CUSTOM_CURRENCY_ID, "GBP|USD|EUR|YEN|ATS|BEF|CHF|CZK|DEM|DKK|ESP|FIM|FRF|GRD|HUF|ISK|ITL|NLG|NOK|PLN|ROL|RUR|SIT|SEK|YTL|SKK|BRR|custom", STR_NULL, NULL, NULL),
- SDT_CONDOMANY(Settings, gui.units,                                     SLE_UINT8, 97, SL_MAX_VERSION, N, 0, 1, 2, "imperial|metric|si", STR_NULL, NULL, NULL),
+	     SDT_VAR(GameSettings, game_creation.map_x,                           SLE_UINT8,                     S, 0,     8,                     6,      11, 0, STR_CONFIG_PATCHES_MAP_X,                 NULL),
+	     SDT_VAR(GameSettings, game_creation.map_y,                           SLE_UINT8,                     S, 0,     8,                     6,      11, 0, STR_CONFIG_PATCHES_MAP_Y,                 NULL),
+
+SDTC_CONDOMANY(              gui.currency,                                  SLE_UINT8, 97, SL_MAX_VERSION, N, 0, 0, CUSTOM_CURRENCY_ID, "GBP|USD|EUR|YEN|ATS|BEF|CHF|CZK|DEM|DKK|ESP|FIM|FRF|GRD|HUF|ISK|ITL|NLG|NOK|PLN|ROL|RUR|SIT|SEK|YTL|SKK|BRR|custom", STR_NULL, NULL),
+SDTC_CONDOMANY(              gui.units,                                     SLE_UINT8, 97, SL_MAX_VERSION, N, 0, 1, 2, "imperial|metric|si", STR_NULL, NULL),
 
 	/***************************************************************************/
 	/* Unsaved patch variables. */
- SDT_OMANY(Settings, gui.autosave,               SLE_UINT8, S, 0, 1, 4, "off|monthly|quarterly|half year|yearly", STR_NULL, NULL,               NULL),
-	SDT_BOOL(Settings, gui.vehicle_speed,                     S, 0,  true,                        STR_CONFIG_PATCHES_VEHICLESPEED,                NULL),
-	SDT_BOOL(Settings, gui.status_long_date,                  S, 0,  true,                        STR_CONFIG_PATCHES_LONGDATE,                    NULL),
-	SDT_BOOL(Settings, gui.show_finances,                     S, 0,  true,                        STR_CONFIG_PATCHES_SHOWFINANCES,                NULL),
-	SDT_BOOL(Settings, gui.autoscroll,                        S, 0, false,                        STR_CONFIG_PATCHES_AUTOSCROLL,                  NULL),
-	SDT_BOOL(Settings, gui.reverse_scroll,                    S, 0, false,                        STR_CONFIG_PATCHES_REVERSE_SCROLLING,           NULL),
-	SDT_BOOL(Settings, gui.smooth_scroll,                     S, 0, false,                        STR_CONFIG_PATCHES_SMOOTH_SCROLLING,            NULL),
-	SDT_BOOL(Settings, gui.measure_tooltip,                   S, 0, false,                        STR_CONFIG_PATCHES_MEASURE_TOOLTIP,             NULL),
-	 SDT_VAR(Settings, gui.errmsg_duration,        SLE_UINT8, S, 0,     5,        0,       20, 0, STR_CONFIG_PATCHES_ERRMSG_DURATION,             NULL),
-	 SDT_VAR(Settings, gui.toolbar_pos,            SLE_UINT8, S,MS,     0,        0,        2, 0, STR_CONFIG_PATCHES_TOOLBAR_POS,                 v_PositionMainToolbar),
-	 SDT_VAR(Settings, gui.window_snap_radius,     SLE_UINT8, S,D0,    10,        1,       32, 0, STR_CONFIG_PATCHES_SNAP_RADIUS,                 NULL),
-	SDT_BOOL(Settings, gui.population_in_label,               S, 0,  true,                        STR_CONFIG_PATCHES_POPULATION_IN_LABEL,         PopulationInLabelActive),
-	SDT_BOOL(Settings, gui.link_terraform_toolbar,            S, 0, false,                        STR_CONFIG_PATCHES_LINK_TERRAFORM_TOOLBAR,      NULL),
-	 SDT_VAR(Settings, gui.liveries,               SLE_UINT8, S,MS,     2,        0,        2, 0, STR_CONFIG_PATCHES_LIVERIES,                    RedrawScreen),
-	SDT_BOOL(Settings, gui.prefer_teamchat,                   S, 0, false,                        STR_CONFIG_PATCHES_PREFER_TEAMCHAT,             NULL),
-	 SDT_VAR(Settings, gui.scrollwheel_scrolling,  SLE_UINT8, S,MS,     0,        0,        2, 0, STR_CONFIG_PATCHES_SCROLLWHEEL_SCROLLING,       NULL),
-	 SDT_VAR(Settings, gui.scrollwheel_multiplier, SLE_UINT8, S, 0,     5,        1,       15, 1, STR_CONFIG_PATCHES_SCROLLWHEEL_MULTIPLIER,      NULL),
-	SDT_BOOL(Settings, gui.pause_on_newgame,                  S, 0, false,                        STR_CONFIG_PATCHES_PAUSE_ON_NEW_GAME,           NULL),
-	 SDT_VAR(Settings, gui.advanced_vehicle_list,  SLE_UINT8, S,MS,     1,        0,        2, 0, STR_CONFIG_PATCHES_ADVANCED_VEHICLE_LISTS,      NULL),
-	SDT_BOOL(Settings, gui.timetable_in_ticks,                S, 0, false,                        STR_CONFIG_PATCHES_TIMETABLE_IN_TICKS,          NULL),
-	 SDT_VAR(Settings, gui.loading_indicators,     SLE_UINT8, S,MS,     1,        0,        2, 0, STR_CONFIG_PATCHES_LOADING_INDICATORS,          RedrawScreen),
-	 SDT_VAR(Settings, gui.default_rail_type,      SLE_UINT8, S,MS,     4,        0,        6, 0, STR_CONFIG_PATCHES_DEFAULT_RAIL_TYPE,           NULL),
-	SDT_BOOL(Settings, gui.enable_signal_gui,                 S, 0, false,                        STR_CONFIG_PATCHES_ENABLE_SIGNAL_GUI,           CloseSignalGUI),
-	 SDT_VAR(Settings, gui.drag_signals_density,   SLE_UINT8, S, 0,     4,        1,       20, 0, STR_CONFIG_PATCHES_DRAG_SIGNALS_DENSITY,        DragSignalsDensityChanged),
-	 SDT_VAR(Settings, gui.semaphore_build_before, SLE_INT32, S, NC, 1975, MIN_YEAR, MAX_YEAR, 1, STR_CONFIG_PATCHES_SEMAPHORE_BUILD_BEFORE_DATE, ResetSignalVariant),
-	SDT_BOOL(Settings, gui.train_income_warn,                 S, 0,  true,                        STR_CONFIG_PATCHES_WARN_INCOME_LESS,            NULL),
-	 SDT_VAR(Settings, gui.order_review_system,    SLE_UINT8, S,MS,     2,        0,        2, 0, STR_CONFIG_PATCHES_ORDER_REVIEW,                NULL),
-	SDT_BOOL(Settings, gui.lost_train_warn,                   S, 0,  true,                        STR_CONFIG_PATCHES_WARN_LOST_TRAIN,             NULL),
-	SDT_BOOL(Settings, gui.autorenew,                         S, 0, false,                        STR_CONFIG_PATCHES_AUTORENEW_VEHICLE,           EngineRenewUpdate),
-	 SDT_VAR(Settings, gui.autorenew_months,       SLE_INT16, S, 0,     6,      -12,       12, 0, STR_CONFIG_PATCHES_AUTORENEW_MONTHS,            EngineRenewMonthsUpdate),
-	 SDT_VAR(Settings, gui.autorenew_money,         SLE_UINT, S,CR,100000,        0,  2000000, 0, STR_CONFIG_PATCHES_AUTORENEW_MONEY,             EngineRenewMoneyUpdate),
-	SDT_BOOL(Settings, gui.always_build_infrastructure,       S, 0, false,                        STR_CONFIG_PATCHES_ALWAYS_BUILD_INFRASTRUCTURE, RedrawScreen),
-	SDT_BOOL(Settings, gui.new_nonstop,                       S, 0, false,                        STR_CONFIG_PATCHES_NEW_NONSTOP,                 NULL),
-	SDT_BOOL(Settings, gui.keep_all_autosave,                 S, 0, false,                        STR_NULL,                                       NULL),
-	SDT_BOOL(Settings, gui.autosave_on_exit,                  S, 0, false,                        STR_NULL,                                       NULL),
-	 SDT_VAR(Settings, gui.max_num_autosaves,      SLE_UINT8, S, 0,    16,        0,      255, 0, STR_NULL,                                       NULL),
-	SDT_BOOL(Settings, gui.bridge_pillars,                    S, 0,  true,                        STR_NULL,                                       NULL),
-	SDT_BOOL(Settings, gui.auto_euro,                         S, 0,  true,                        STR_NULL,                                       NULL),
-
-	 SDT_VAR(Settings, game_creation.map_x,        SLE_UINT8, S, 0,     8,        6,       11, 0, STR_CONFIG_PATCHES_MAP_X,                       NULL),
-	 SDT_VAR(Settings, game_creation.map_y,        SLE_UINT8, S, 0,     8,        6,       11, 0, STR_CONFIG_PATCHES_MAP_Y,                       NULL),
+	SDTC_OMANY(gui.autosave,               SLE_UINT8, S, 0, 1, 4, "off|monthly|quarterly|half year|yearly", STR_NULL,                     NULL),
+	 SDTC_BOOL(gui.vehicle_speed,                     S, 0,  true,                        STR_CONFIG_PATCHES_VEHICLESPEED,                NULL),
+	 SDTC_BOOL(gui.status_long_date,                  S, 0,  true,                        STR_CONFIG_PATCHES_LONGDATE,                    NULL),
+	 SDTC_BOOL(gui.show_finances,                     S, 0,  true,                        STR_CONFIG_PATCHES_SHOWFINANCES,                NULL),
+	 SDTC_BOOL(gui.autoscroll,                        S, 0, false,                        STR_CONFIG_PATCHES_AUTOSCROLL,                  NULL),
+	 SDTC_BOOL(gui.reverse_scroll,                    S, 0, false,                        STR_CONFIG_PATCHES_REVERSE_SCROLLING,           NULL),
+	 SDTC_BOOL(gui.smooth_scroll,                     S, 0, false,                        STR_CONFIG_PATCHES_SMOOTH_SCROLLING,            NULL),
+	 SDTC_BOOL(gui.measure_tooltip,                   S, 0, false,                        STR_CONFIG_PATCHES_MEASURE_TOOLTIP,             NULL),
+	  SDTC_VAR(gui.errmsg_duration,        SLE_UINT8, S, 0,     5,        0,       20, 0, STR_CONFIG_PATCHES_ERRMSG_DURATION,             NULL),
+	  SDTC_VAR(gui.toolbar_pos,            SLE_UINT8, S,MS,     0,        0,        2, 0, STR_CONFIG_PATCHES_TOOLBAR_POS,                 v_PositionMainToolbar),
+	  SDTC_VAR(gui.window_snap_radius,     SLE_UINT8, S,D0,    10,        1,       32, 0, STR_CONFIG_PATCHES_SNAP_RADIUS,                 NULL),
+	 SDTC_BOOL(gui.population_in_label,               S, 0,  true,                        STR_CONFIG_PATCHES_POPULATION_IN_LABEL,         PopulationInLabelActive),
+	 SDTC_BOOL(gui.link_terraform_toolbar,            S, 0, false,                        STR_CONFIG_PATCHES_LINK_TERRAFORM_TOOLBAR,      NULL),
+	  SDTC_VAR(gui.liveries,               SLE_UINT8, S,MS,     2,        0,        2, 0, STR_CONFIG_PATCHES_LIVERIES,                    RedrawScreen),
+	 SDTC_BOOL(gui.prefer_teamchat,                   S, 0, false,                        STR_CONFIG_PATCHES_PREFER_TEAMCHAT,             NULL),
+	  SDTC_VAR(gui.scrollwheel_scrolling,  SLE_UINT8, S,MS,     0,        0,        2, 0, STR_CONFIG_PATCHES_SCROLLWHEEL_SCROLLING,       NULL),
+	  SDTC_VAR(gui.scrollwheel_multiplier, SLE_UINT8, S, 0,     5,        1,       15, 1, STR_CONFIG_PATCHES_SCROLLWHEEL_MULTIPLIER,      NULL),
+	 SDTC_BOOL(gui.pause_on_newgame,                  S, 0, false,                        STR_CONFIG_PATCHES_PAUSE_ON_NEW_GAME,           NULL),
+	  SDTC_VAR(gui.advanced_vehicle_list,  SLE_UINT8, S,MS,     1,        0,        2, 0, STR_CONFIG_PATCHES_ADVANCED_VEHICLE_LISTS,      NULL),
+	 SDTC_BOOL(gui.timetable_in_ticks,                S, 0, false,                        STR_CONFIG_PATCHES_TIMETABLE_IN_TICKS,          NULL),
+	  SDTC_VAR(gui.loading_indicators,     SLE_UINT8, S,MS,     1,        0,        2, 0, STR_CONFIG_PATCHES_LOADING_INDICATORS,          RedrawScreen),
+	  SDTC_VAR(gui.default_rail_type,      SLE_UINT8, S,MS,     4,        0,        6, 0, STR_CONFIG_PATCHES_DEFAULT_RAIL_TYPE,           NULL),
+	 SDTC_BOOL(gui.enable_signal_gui,                 S, 0, false,                        STR_CONFIG_PATCHES_ENABLE_SIGNAL_GUI,           CloseSignalGUI),
+	  SDTC_VAR(gui.drag_signals_density,   SLE_UINT8, S, 0,     4,        1,       20, 0, STR_CONFIG_PATCHES_DRAG_SIGNALS_DENSITY,        DragSignalsDensityChanged),
+	  SDTC_VAR(gui.semaphore_build_before, SLE_INT32, S, NC, 1975, MIN_YEAR, MAX_YEAR, 1, STR_CONFIG_PATCHES_SEMAPHORE_BUILD_BEFORE_DATE, ResetSignalVariant),
+	 SDTC_BOOL(gui.train_income_warn,                 S, 0,  true,                        STR_CONFIG_PATCHES_WARN_INCOME_LESS,            NULL),
+	  SDTC_VAR(gui.order_review_system,    SLE_UINT8, S,MS,     2,        0,        2, 0, STR_CONFIG_PATCHES_ORDER_REVIEW,                NULL),
+	 SDTC_BOOL(gui.lost_train_warn,                   S, 0,  true,                        STR_CONFIG_PATCHES_WARN_LOST_TRAIN,             NULL),
+	 SDTC_BOOL(gui.autorenew,                         S, 0, false,                        STR_CONFIG_PATCHES_AUTORENEW_VEHICLE,           EngineRenewUpdate),
+	  SDTC_VAR(gui.autorenew_months,       SLE_INT16, S, 0,     6,      -12,       12, 0, STR_CONFIG_PATCHES_AUTORENEW_MONTHS,            EngineRenewMonthsUpdate),
+	  SDTC_VAR(gui.autorenew_money,         SLE_UINT, S,CR,100000,        0,  2000000, 0, STR_CONFIG_PATCHES_AUTORENEW_MONEY,             EngineRenewMoneyUpdate),
+	 SDTC_BOOL(gui.always_build_infrastructure,       S, 0, false,                        STR_CONFIG_PATCHES_ALWAYS_BUILD_INFRASTRUCTURE, RedrawScreen),
+	 SDTC_BOOL(gui.new_nonstop,                       S, 0, false,                        STR_CONFIG_PATCHES_NEW_NONSTOP,                 NULL),
+	 SDTC_BOOL(gui.keep_all_autosave,                 S, 0, false,                        STR_NULL,                                       NULL),
+	 SDTC_BOOL(gui.autosave_on_exit,                  S, 0, false,                        STR_NULL,                                       NULL),
+	  SDTC_VAR(gui.max_num_autosaves,      SLE_UINT8, S, 0,    16,        0,      255, 0, STR_NULL,                                       NULL),
+	 SDTC_BOOL(gui.bridge_pillars,                    S, 0,  true,                        STR_NULL,                                       NULL),
+	 SDTC_BOOL(gui.auto_euro,                         S, 0,  true,                        STR_NULL,                                       NULL),
+	  SDTC_VAR(gui.news_message_timeout,   SLE_UINT8, S, 0,     2,        1,      255, 0, STR_NULL,                                       NULL),
 
 	/*
 	 * Since the network code (CmdChangePatchSetting and friends) use the index in this array to decide
@@ -1761,7 +1789,7 @@
 
 #ifdef __APPLE__
 	/* We might need to emulate a right mouse button on mac */
-	     SDT_VAR(Settings, gui.right_mouse_btn_emulation, SLE_UINT8, S, MS, 0, 0, 2, 0, STR_CONFIG_PATCHES_RIGHT_MOUSE_BTN_EMU, NULL),
+	 SDTC_VAR(gui.right_mouse_btn_emulation, SLE_UINT8, S, MS, 0, 0, 2, 0, STR_CONFIG_PATCHES_RIGHT_MOUSE_BTN_EMU, NULL),
 #endif
 
 	SDT_END()
@@ -1787,26 +1815,37 @@
 #undef NO
 #undef CR
 
+/**
+ * Prepare for reading and old diff_custom by zero-ing the memory.
+ */
 static void PrepareOldDiffCustom()
 {
 	memset(_old_diff_custom, 0, sizeof(_old_diff_custom));
 }
 
-static void HandleOldDiffCustom()
+/**
+ * Reading of the old diff_custom array and transforming it to the new format.
+ * @param savegame is it read from the config or savegame. In the latter case
+ *                 we are sure there is an array; in the former case we have
+ *                 to check that.
+ */
+static void HandleOldDiffCustom(bool savegame)
 {
-	uint options_to_load = GAME_DIFFICULTY_NUM - (CheckSavegameVersion(4) ? 1 : 0);
+	uint options_to_load = GAME_DIFFICULTY_NUM - ((savegame && CheckSavegameVersion(4)) ? 1 : 0);
 
-	/* If we did read to old_diff_custom, then at least one value must be non 0. */
-	bool old_diff_custom_used = false;
-	for (uint i = 0; i < options_to_load && !old_diff_custom_used; i++) {
-		old_diff_custom_used = (_old_diff_custom[i] != 0);
+	if (!savegame) {
+		/* If we did read to old_diff_custom, then at least one value must be non 0. */
+		bool old_diff_custom_used = false;
+		for (uint i = 0; i < options_to_load && !old_diff_custom_used; i++) {
+			old_diff_custom_used = (_old_diff_custom[i] != 0);
+		}
+
+		if (!old_diff_custom_used) return;
 	}
 
-	if (!old_diff_custom_used) return;
-
 	for (uint i = 0; i < options_to_load; i++) {
 		const SettingDesc *sd = &_patch_settings[i];
-		void *var = GetVariableAddress((_game_mode == GM_MENU) ? &_settings_newgame : &_settings, &sd->save);
+		void *var = GetVariableAddress(savegame ? &_settings_game : &_settings_newgame, &sd->save);
 		Write_ValidateSetting(var, sd, (int32)((i == 4 ? 1000 : 1) * _old_diff_custom[i]));
 	}
 }
@@ -1977,10 +2016,6 @@
 	proc(ini, (const SettingDesc*)_win32_settings,   "win32", NULL);
 #endif /* WIN32 */
 
-	PrepareOldDiffCustom();
-	proc(ini, _gameopt_settings, "gameopt",  &_settings_newgame);
-	HandleOldDiffCustom();
-
 	proc(ini, _patch_settings,   "patches",  &_settings_newgame);
 	proc(ini, _currency_settings,"currency", &_custom_currency);
 
@@ -1996,6 +2031,11 @@
 {
 	IniFile *ini = ini_load(_config_file);
 	ResetCurrencies(false); // Initialize the array of curencies, without preserving the custom one
+
+	PrepareOldDiffCustom();
+	ini_load_settings(ini, _gameopt_settings, "gameopt",  &_settings_newgame);
+	HandleOldDiffCustom(false);
+
 	HandleSettingDescs(ini, ini_load_settings, ini_load_setting_list);
 	_grfconfig_newgame = GRFLoadConfig(ini, "newgrf", false);
 	_grfconfig_static  = GRFLoadConfig(ini, "newgrf-static", true);
@@ -2049,7 +2089,7 @@
 	if ((sd->desc.flags & SGF_NEWGAME_ONLY) && _game_mode != GM_MENU) return CMD_ERROR;
 
 	if (flags & DC_EXEC) {
-		Settings *s = (_game_mode == GM_MENU) ? &_settings_newgame : &_settings;
+		GameSettings *s = (_game_mode == GM_MENU) ? &_settings_newgame : &_settings_game;
 		void *var = GetVariableAddress(s, &sd->save);
 		Write_ValidateSetting(var, sd, (int32)p2);
 		if (sd->desc.proc != NULL) sd->desc.proc((int32)ReadValue(var, sd->save.conv));
@@ -2067,7 +2107,7 @@
  * This only affects patch-members that are not needed to be the same on all
  * clients in a network game.
  * @param value new value of the patch */
-bool SetPatchValue(uint index, const Settings *object, int32 value)
+bool SetPatchValue(uint index, int32 value)
 {
 	const SettingDesc *sd = &_patch_settings[index];
 	/* If an item is player-based, we do not send it over the network
@@ -2075,7 +2115,7 @@
 	 * of patches because changing a player-based setting in a game also
 	 * changes its defaults. At least that is the convention we have chosen */
 	if (sd->save.conv & SLF_NETWORK_NO) {
-		void *var = GetVariableAddress(object, &sd->save);
+		void *var = GetVariableAddress((_game_mode == GM_MENU) ? &_settings_newgame : &_settings_game, &sd->save);
 		Write_ValidateSetting(var, sd, value);
 
 		if (_game_mode != GM_MENU) {
@@ -2131,10 +2171,10 @@
 		return true;
 	}
 
-	Settings *s = (_game_mode == GM_MENU) ? &_settings_newgame : &_settings;
+	GameSettings *s = (_game_mode == GM_MENU) ? &_settings_newgame : &_settings_game;
 	ptr = GetVariableAddress(s, &sd->save);
 
-	success = SetPatchValue(index, s, value);
+	success = SetPatchValue(index, value);
 	return success;
 }
 
@@ -2150,7 +2190,7 @@
 		return;
 	}
 
-	ptr = GetVariableAddress((_game_mode == GM_MENU) ? &_settings_newgame : &_settings, &sd->save);
+	ptr = GetVariableAddress((_game_mode == GM_MENU) ? &_settings_newgame : &_settings_game, &sd->save);
 
 	if (sd->desc.cmd == SDT_BOOLX) {
 		snprintf(value, sizeof(value), (*(bool*)ptr == 1) ? "on" : "off");
@@ -2168,7 +2208,7 @@
 
 	for (const SettingDesc *sd = _patch_settings; sd->save.cmd != SL_END; sd++) {
 		char value[80];
-		const void *ptr = GetVariableAddress((_game_mode == GM_MENU) ? &_settings_newgame : &_settings, &sd->save);
+		const void *ptr = GetVariableAddress((_game_mode == GM_MENU) ? &_settings_newgame : &_settings_game, &sd->save);
 
 		if (sd->desc.cmd == SDT_BOOLX) {
 			snprintf(value, lengthof(value), (*(bool*)ptr == 1) ? "on" : "off");
@@ -2189,7 +2229,7 @@
 {
 	for (; osd->save.cmd != SL_END; osd++) {
 		const SaveLoad *sld = &osd->save;
-		void *ptr = GetVariableAddress(sld->global ? NULL : object, sld);
+		void *ptr = GetVariableAddress(object, sld);
 
 		if (!SlObjectMember(ptr, sld)) continue;
 	}
@@ -2240,8 +2280,8 @@
 	 * a networking environment. This ensures for example that the local
 	 * autosave-frequency stays when joining a network-server */
 	PrepareOldDiffCustom();
-	LoadSettings(_gameopt_settings, &_settings);
-	HandleOldDiffCustom();
+	LoadSettings(_gameopt_settings, &_settings_game);
+	HandleOldDiffCustom(true);
 }
 
 static void Load_PATS()
@@ -2249,32 +2289,26 @@
 	/* Copy over default setting since some might not get loaded in
 	 * a networking environment. This ensures for example that the local
 	 * signal_side stays when joining a network-server */
-	LoadSettings(_patch_settings, &_settings);
+	LoadSettings(_patch_settings, &_settings_game);
 }
 
 static void Save_PATS()
 {
-	SaveSettings(_patch_settings, &_settings);
+	SaveSettings(_patch_settings, &_settings_game);
 }
 
 void CheckConfig()
 {
-	// Increase old default values for pf_maxdepth and pf_maxlength
-	// to support big networks.
+	/*
+	 * Increase old default values for pf_maxdepth and pf_maxlength
+	 * to support big networks.
+	 */
 	if (_settings_newgame.pf.opf.pf_maxdepth == 16 && _settings_newgame.pf.opf.pf_maxlength == 512) {
 		_settings_newgame.pf.opf.pf_maxdepth = 48;
 		_settings_newgame.pf.opf.pf_maxlength = 4096;
 	}
 }
 
-void UpdatePatches()
-{
-	/* Since old(er) savegames don't have any patches saved, we initialise
-	 * them with the default values just as it was in the old days.
-	 * Also new games need this copying-over */
-	_settings = _settings_newgame; /* backwards compatibility */
-}
-
 extern const ChunkHandler _setting_chunk_handlers[] = {
 	{ 'OPTS', NULL,      Load_OPTS, CH_RIFF},
 	{ 'PATS', Save_PATS, Load_PATS, CH_RIFF | CH_LAST},
--- a/src/settings_func.h	Thu May 29 12:52:24 2008 +0000
+++ b/src/settings_func.h	Thu May 29 15:56:32 2008 +0000
@@ -12,6 +12,5 @@
 void LoadFromConfig();
 void SaveToConfig();
 void CheckConfig();
-void UpdatePatches();
 
 #endif /* SETTINGS_FUNC_H */
--- a/src/settings_gui.cpp	Thu May 29 12:52:24 2008 +0000
+++ b/src/settings_gui.cpp	Thu May 29 15:56:32 2008 +0000
@@ -142,11 +142,11 @@
 static void ShowCustCurrency();
 
 struct GameOptionsWindow : Window {
-	Settings *opt;
+	GameSettings *opt;
 
 	GameOptionsWindow(const WindowDesc *desc) : Window(desc)
 	{
-		this->opt = (_game_mode == GM_MENU) ? &_settings_newgame : &_settings;
+		this->opt = (_game_mode == GM_MENU) ? &_settings_newgame : &_settings_game;
 		this->FindWindowPlacementAndResize(desc);
 	}
 
@@ -162,11 +162,11 @@
 		this->SetWidgetDisabledState(GAMEOPT_VEHICLENAME_SAVE, !(_vehicle_design_names & 1));
 		if (!this->IsWidgetDisabled(GAMEOPT_VEHICLENAME_SAVE)) str = STR_02BF_CUSTOM;
 		SetDParam(0, str);
-		SetDParam(1, _currency_specs[this->opt->gui.currency].name);
-		SetDParam(2, STR_UNITS_IMPERIAL + this->opt->gui.units);
+		SetDParam(1, _currency_specs[_settings_client.gui.currency].name);
+		SetDParam(2, STR_UNITS_IMPERIAL + _settings_client.gui.units);
 		SetDParam(3, STR_02E9_DRIVE_ON_LEFT + this->opt->vehicle.road_side);
 		SetDParam(4, TownName(this->opt->game_creation.town_name));
-		SetDParam(5, _autosave_dropdown[this->opt->gui.autosave]);
+		SetDParam(5, _autosave_dropdown[_settings_client.gui.autosave]);
 		SetDParam(6, SPECSTR_LANGUAGE_START + _dynlang.curr);
 		int i = GetCurRes();
 		SetDParam(7, i == _num_resolutions ? STR_RES_OTHER : SPECSTR_RESOLUTION_START + i);
@@ -181,11 +181,11 @@
 	{
 		switch (widget) {
 			case GAMEOPT_CURRENCY_BTN: // Setup currencies dropdown
-				ShowDropDownMenu(this, BuildCurrencyDropdown(), this->opt->gui.currency, GAMEOPT_CURRENCY_BTN, _game_mode == GM_MENU ? 0 : ~GetMaskOfAllowedCurrencies(), 0);
+				ShowDropDownMenu(this, BuildCurrencyDropdown(), _settings_client.gui.currency, GAMEOPT_CURRENCY_BTN, _game_mode == GM_MENU ? 0 : ~GetMaskOfAllowedCurrencies(), 0);
 				break;
 
 			case GAMEOPT_DISTANCE_BTN: // Setup distance unit dropdown
-				ShowDropDownMenu(this, _units_dropdown, this->opt->gui.units, GAMEOPT_DISTANCE_BTN, 0, 0);
+				ShowDropDownMenu(this, _units_dropdown, _settings_client.gui.units, GAMEOPT_DISTANCE_BTN, 0, 0);
 				break;
 
 			case GAMEOPT_ROADSIDE_BTN: { // Setup road-side dropdown
@@ -206,7 +206,7 @@
 				break;
 
 			case GAMEOPT_AUTOSAVE_BTN: // Setup autosave dropdown
-				ShowDropDownMenu(this, _autosave_dropdown, this->opt->gui.autosave, GAMEOPT_AUTOSAVE_BTN, 0, 0);
+				ShowDropDownMenu(this, _autosave_dropdown, _settings_client.gui.autosave, GAMEOPT_AUTOSAVE_BTN, 0, 0);
 				break;
 
 			case GAMEOPT_VEHICLENAME_BTN: // Setup customized vehicle-names dropdown
@@ -265,12 +265,12 @@
 
 			case GAMEOPT_CURRENCY_BTN: /* Currency */
 				if (index == CUSTOM_CURRENCY_ID) ShowCustCurrency();
-				this->opt->gui.currency = index;
+				_settings_client.gui.currency = index;
 				MarkWholeScreenDirty();
 				break;
 
 			case GAMEOPT_DISTANCE_BTN: // Measuring units
-				this->opt->gui.units = index;
+				_settings_client.gui.units = index;
 				MarkWholeScreenDirty();
 				break;
 
@@ -289,7 +289,7 @@
 				break;
 
 			case GAMEOPT_AUTOSAVE_BTN: // Autosave options
-				_settings.gui.autosave = _settings_newgame.gui.autosave = index;
+				_settings_client.gui.autosave = index;
 				this->SetDirty();
 				break;
 
@@ -398,7 +398,7 @@
 	uint8 timeout;
 
 	/* Temporary holding place of values in the difficulty window until 'Save' is clicked */
-	Settings opt_mod_temp;
+	GameSettings opt_mod_temp;
 
 	enum {
 		GAMEDIFF_WND_TOP_OFFSET = 45,
@@ -427,7 +427,7 @@
 	{
 		/* Copy current settings (ingame or in intro) to temporary holding place
 		 * change that when setting stuff, copy back on clicking 'OK' */
-		this->opt_mod_temp = (_game_mode == GM_MENU) ? _settings_newgame : _settings;
+		this->opt_mod_temp = (_game_mode == GM_MENU) ? _settings_newgame : _settings_game;
 		this->clicked_increase = false;
 		this->clicked_button = NO_SETTINGS_BUTTON;
 		this->timeout = 0;
@@ -537,7 +537,7 @@
 				break;
 
 			case GDW_ACCEPT: { // Save button - save changes
-				Settings *opt_ptr = (_game_mode == GM_MENU) ? &_settings_newgame : &_settings;
+				GameSettings *opt_ptr = (_game_mode == GM_MENU) ? &_settings_newgame : &_settings_game;
 
 				uint i;
 				const SettingDesc *sd = GetPatchFromName("difficulty.max_no_competitors", &i);
@@ -737,7 +737,7 @@
 };
 
 struct PatchesSelectionWindow : Window {
-	static Settings *patches_ptr;
+	static GameSettings *patches_ptr;
 	static int patches_max;
 
 	int page;
@@ -748,7 +748,7 @@
 	{
 		static bool first_time = true;
 
-		patches_ptr = (_game_mode == GM_MENU) ? &_settings_newgame : &_settings;
+		patches_ptr = (_game_mode == GM_MENU) ? &_settings_newgame : &_settings_game;
 
 		/* Build up the dynamic settings-array only once per OpenTTD session */
 		if (first_time) {
@@ -761,6 +761,7 @@
 				page->entries = MallocT<PatchEntry>(page->num);
 				for (i = 0; i != page->num; i++) {
 					uint index;
+					printf("%s\n", page->names[i]);
 					const SettingDesc *sd = GetPatchFromName(page->names[i], &index);
 					assert(sd != NULL);
 
@@ -911,7 +912,7 @@
 					}
 
 					if (value != oldvalue) {
-						SetPatchValue(page->entries[btn].index, patches_ptr, value);
+						SetPatchValue(page->entries[btn].index, value);
 						this->SetDirty();
 					}
 				} else {
@@ -954,13 +955,13 @@
 			/* Save the correct currency-translated value */
 			if (sd->desc.flags & SGF_CURRENCY) value /= _currency->rate;
 
-			SetPatchValue(pe->index, patches_ptr, value);
+			SetPatchValue(pe->index, value);
 			this->SetDirty();
 		}
 	}
 };
 
-Settings *PatchesSelectionWindow::patches_ptr = NULL;
+GameSettings *PatchesSelectionWindow::patches_ptr = NULL;
 int PatchesSelectionWindow::patches_max = 0;
 
 static const Widget _patches_selection_widgets[] = {
--- a/src/settings_internal.h	Thu May 29 12:52:24 2008 +0000
+++ b/src/settings_internal.h	Thu May 29 15:56:32 2008 +0000
@@ -84,6 +84,6 @@
 };
 
 const SettingDesc *GetPatchFromName(const char *name, uint *i);
-bool SetPatchValue(uint index, const Settings *object, int32 value);
+bool SetPatchValue(uint index, int32 value);
 
 #endif /* SETTINGS_H */
--- a/src/settings_type.h	Thu May 29 12:52:24 2008 +0000
+++ b/src/settings_type.h	Thu May 29 15:56:32 2008 +0000
@@ -79,6 +79,7 @@
 	int32  autorenew_money;                  ///< how much money before autorenewing for new companies?
 	byte   currency;                         ///< currency we currently use
 	byte   units;                            ///< unit system we show everything
+	byte   news_message_timeout;             ///< how much longer than the news message "age" should we keep the message in the history
 };
 
 /** Settings related to the creation of games. */
@@ -263,10 +264,9 @@
 	byte   station_spread;                   ///< amount a station may spread
 };
 
-/** All settings together. */
-struct Settings {
+/** All settings together for the game. */
+struct GameSettings {
 	DifficultySettings   difficulty;         ///< settings related to the difficulty
-	GUISettings          gui;                ///< settings related to the GUI
 	GameCreationSettings game_creation;      ///< settings used during the creation of a game (map)
 	ConstructionSettings construction;       ///< construction of things in-game
 	AISettings           ai;                 ///< what may the AI do?
@@ -277,10 +277,18 @@
 	StationSettings      station;            ///< settings related to station management
 };
 
-/** The current settings. */
-extern Settings _settings;
+/** All settings that are only important for the local client. */
+struct ClientSettings {
+	GUISettings          gui;                ///< settings related to the GUI
+};
 
-/** The settings values that are used for new games and/or modified in config file */
-extern Settings _settings_newgame;
+/** The current settings for this game. */
+extern ClientSettings _settings_client;
+
+/** The current settings for this game. */
+extern GameSettings _settings_game;
+
+/** The settings values that are used for new games and/or modified in config file. */
+extern GameSettings _settings_newgame;
 
 #endif /* SETTINGS_TYPE_H */
--- a/src/ship_cmd.cpp	Thu May 29 12:52:24 2008 +0000
+++ b/src/ship_cmd.cpp	Thu May 29 15:56:32 2008 +0000
@@ -107,7 +107,7 @@
 
 static const Depot* FindClosestShipDepot(const Vehicle* v)
 {
-	if (_settings.pf.pathfinder_for_ships == VPF_NPF) { /* NPF is used */
+	if (_settings_game.pf.pathfinder_for_ships == VPF_NPF) { /* NPF is used */
 		Trackdir trackdir = GetVehicleTrackdir(v);
 		NPFFoundTargetData ftd = NPFRouteToDepotTrialError(v->tile, trackdir, false, TRANSPORT_WATER, 0, v->owner, INVALID_RAILTYPES);
 
@@ -138,7 +138,7 @@
 
 static void CheckIfShipNeedsService(Vehicle *v)
 {
-	if (_settings.vehicle.servint_ships == 0 || !v->NeedsAutomaticServicing()) return;
+	if (_settings_game.vehicle.servint_ships == 0 || !v->NeedsAutomaticServicing()) return;
 	if (v->IsInDepot()) {
 		VehicleServiceInDepot(v);
 		return;
@@ -197,7 +197,7 @@
 		InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
 
 		if (!PlayVehicleSound(v, VSE_BREAKDOWN)) {
-			SndPlayVehicleFx((_settings.game_creation.landscape != LT_TOYLAND) ?
+			SndPlayVehicleFx((_settings_game.game_creation.landscape != LT_TOYLAND) ?
 				SND_10_TRAIN_BREAKDOWN : SND_3A_COMEDY_BREAKDOWN_2, v);
 		}
 
@@ -321,7 +321,7 @@
 	/*updates statusbar only if speed have changed to save CPU time */
 	if (spd != v->cur_speed) {
 		v->cur_speed = spd;
-		if (_settings.gui.vehicle_speed)
+		if (_settings_client.gui.vehicle_speed)
 			InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
 	}
 
@@ -460,7 +460,7 @@
 {
 	assert(IsValidDiagDirection(enterdir));
 
-	switch (_settings.pf.pathfinder_for_ships) {
+	switch (_settings_game.pf.pathfinder_for_ships) {
 		case VPF_YAPF: { /* YAPF */
 			Trackdir trackdir = YapfChooseShipTrack(v, tile, enterdir, tracks);
 			if (trackdir != INVALID_TRACKDIR) return TrackdirToTrack(trackdir);
@@ -760,7 +760,7 @@
 
 	unit_num = HasBit(p2, 0) ? 0 : GetFreeUnitNumber(VEH_SHIP);
 
-	if (!Vehicle::AllocateList(NULL, 1) || unit_num > _settings.vehicle.max_ships)
+	if (!Vehicle::AllocateList(NULL, 1) || unit_num > _settings_game.vehicle.max_ships)
 		return_cmd_error(STR_00E1_TOO_MANY_VEHICLES_IN_GAME);
 
 	if (flags & DC_EXEC) {
@@ -804,7 +804,7 @@
 		v->name = NULL;
 		v->u.ship.state = TRACK_BIT_DEPOT;
 
-		v->service_interval = _settings.vehicle.servint_ships;
+		v->service_interval = _settings_game.vehicle.servint_ships;
 		v->date_of_last_service = _date;
 		v->build_year = _cur_year;
 		v->cur_image = 0x0E5E;
--- a/src/signs.cpp	Thu May 29 12:52:24 2008 +0000
+++ b/src/signs.cpp	Thu May 29 15:56:32 2008 +0000
@@ -24,7 +24,6 @@
 #include "table/strings.h"
 
 SignID _new_sign_id;
-uint _total_signs;
 bool _sign_sort_dirty;
 
 /* Initialize the sign-pool */
@@ -115,7 +114,6 @@
 		InvalidateWindow(WC_SIGN_LIST, 0);
 		_sign_sort_dirty = true;
 		_new_sign_id = si->index;
-		_total_signs++;
 	}
 
 	return CommandCost();
@@ -162,7 +160,6 @@
 
 			InvalidateWindow(WC_SIGN_LIST, 0);
 			_sign_sort_dirty = true;
-			_total_signs--;
 		}
 	}
 
@@ -202,7 +199,6 @@
  */
 void InitializeSigns()
 {
-	_total_signs = 0;
 	_Sign_pool.CleanPool();
 	_Sign_pool.AddBlockToPool();
 }
@@ -241,13 +237,10 @@
  */
 static void Load_SIGN()
 {
-	_total_signs = 0;
 	int index;
 	while ((index = SlIterateArray()) != -1) {
 		Sign *si = new (index) Sign();
 		SlObject(si, _sign_desc);
-
-		_total_signs++;
 	}
 
 	_sign_sort_dirty = true;
--- a/src/signs_base.h	Thu May 29 12:52:24 2008 +0000
+++ b/src/signs_base.h	Thu May 29 15:56:32 2008 +0000
@@ -40,12 +40,6 @@
 	return GetSignPoolSize() - 1;
 }
 
-static inline uint GetNumSigns()
-{
-	extern uint _total_signs;
-	return _total_signs;
-}
-
 static inline bool IsValidSignID(uint index)
 {
 	return index < GetSignPoolSize() && GetSign(index)->IsValid();
--- a/src/smallmap_gui.cpp	Thu May 29 12:52:24 2008 +0000
+++ b/src/smallmap_gui.cpp	Thu May 29 15:56:32 2008 +0000
@@ -459,7 +459,7 @@
 
 		case MP_TREES:
 			if (GetTreeGround(tile) == TREE_GROUND_SNOW_DESERT) {
-				bits = (_settings.game_creation.landscape == LT_ARCTIC) ? MKCOLOR(0x98575798) : MKCOLOR(0xC25757C2);
+				bits = (_settings_game.game_creation.landscape == LT_ARCTIC) ? MKCOLOR(0x98575798) : MKCOLOR(0xC25757C2);
 			} else {
 				bits = MKCOLOR(0x54575754);
 			}
@@ -574,6 +574,7 @@
 	int32 scroll_x;
 	int32 scroll_y;
 	int32 subscroll;
+	uint8 refresh;
 
 public:
 	/**
@@ -1019,7 +1020,7 @@
 	virtual void OnTick()
 	{
 		/* update the window every now and then */
-		if ((++this->vscroll.pos & 0x1F) == 0) this->SetDirty();
+		if ((++this->refresh & 0x1F) == 0) this->SetDirty();
 	}
 
 	virtual void OnScroll(Point delta)
--- a/src/sortlist_type.h	Thu May 29 12:52:24 2008 +0000
+++ b/src/sortlist_type.h	Thu May 29 15:56:32 2008 +0000
@@ -5,12 +5,16 @@
 #ifndef SORTLIST_TYPE_H
 #define SORTLIST_TYPE_H
 
+#include "misc/smallvec.h"
+#include "date_type.h"
+
 enum SortListFlags {
-	VL_NONE    = 0,      ///< no sort
-	VL_DESC    = 1 << 0, ///< sort descending or ascending
-	VL_RESORT  = 1 << 1, ///< instruct the code to resort the list in the next loop
-	VL_REBUILD = 1 << 2, ///< create sort-listing to use for qsort and friends
-	VL_END     = 1 << 3,
+	VL_NONE       = 0,      ///< no sort
+	VL_DESC       = 1 << 0, ///< sort descending or ascending
+	VL_RESORT     = 1 << 1, ///< instruct the code to resort the list in the next loop
+	VL_REBUILD    = 1 << 2, ///< rebuild the sort list
+	VL_FIRST_SORT = 1 << 3, ///< sort with qsort first
+	VL_END        = 1 << 4,
 };
 DECLARE_ENUM_AS_BIT_SET(SortListFlags);
 
@@ -20,12 +24,274 @@
 };
 
 template <typename T>
-struct GUIList {
-	T* sort_list;        ///< The items to sort.
-	SortListFlags flags; ///< used to control sorting/resorting/etc.
-	uint16 list_length;  ///< length of the list being sorted
-	uint16 resort_timer; ///< resort list after a given amount of ticks if set
-	byte sort_type;      ///< what criteria to sort on
+class GUIList : public SmallVector<T, 32> {
+public:
+	typedef int CDECL SortFunction(const T*, const T*);
+
+public: // Temporary: public for conversion only
+	SortFunction* const *func_list; ///< The sort criteria functions
+	SortListFlags flags;            ///< used to control sorting/resorting/etc.
+	uint8 sort_type;                ///< what criteria to sort on
+	uint16 resort_timer;            ///< resort list after a given amount of ticks if set
+
+	/**
+	 * Check if the list is sortable
+	 *
+	 * @return true if we can sort the list
+	 */
+	bool IsSortable() const
+	{
+		return (this->data != NULL && this->items >= 2);
+	}
+
+	/**
+	 * Reset the resort timer
+	 */
+	void ResetResortTimer()
+	{
+		/* Resort every 10 days */
+		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),
+		flags(VL_FIRST_SORT),
+		sort_type(0),
+		resort_timer(1)
+	{};
+
+	/**
+	 * Get the sorttype of the list
+	 *
+	 * @return The current sorttype
+	 */
+	uint8 SortType() const
+	{
+		return this->sort_type;
+	}
+
+	/**
+	 * Set the sorttype of the list
+	 *
+	 * @param n_type the new sort type
+	 */
+	void SetSortType(uint8 n_type)
+	{
+		if (this->sort_type != n_type) {
+			SETBITS(this->flags, VL_RESORT | VL_FIRST_SORT);
+			this->sort_type = n_type;
+		}
+	}
+
+	/**
+	 * Export current sort conditions
+	 *
+	 * @return the current sort conditions
+	 */
+	Listing GetListing() const
+	{
+		Listing l;
+		l.order = HASBITS(this->flags, VL_DESC);
+		l.criteria = this->sort_type;
+
+		return l;
+	}
+
+	/**
+	 * Import sort conditions
+	 *
+	 * @param l The sport conditions we want to use
+	 */
+	void SetListing(Listing l)
+	{
+		if (l.order) {
+			SETBITS(this->flags, VL_DESC);
+		} else {
+			CLRBITS(this->flags, VL_DESC);
+		}
+		this->sort_type = l.criteria;
+
+		SETBITS(this->flags, VL_FIRST_SORT);
+	}
+
+	/**
+	 * Check if a resort is needed next loop
+	 *  If used the resort timer will decrease every call
+	 *  till 0. If 0 reached the resort bit will be set and
+	 *  the timer will be reset.
+	 *
+	 * @return true if resort bit is set for next loop
+	 */
+	bool NeedResort()
+	{
+		if (--this->resort_timer == 0) {
+			SETBITS(this->flags, VL_RESORT);
+			this->ResetResortTimer();
+			return true;
+		}
+		return false;
+	}
+
+	/**
+	 * Force a resort next Sort call
+	 *  Reset the resort timer if used too.
+	 */
+	void ForceResort()
+	{
+		SETBITS(this->flags, VL_RESORT);
+	}
+
+	/**
+	 * Check if the sort order is descending
+	 *
+	 * @return true if the sort order is descending
+	 */
+	bool IsDescSortOrder() const
+	{
+		return HASBITS(this->flags, VL_DESC);
+	}
+
+	/**
+	 * Toogle the sort order
+	 *  Since that is the worst condition for the sort function
+	 *  reverse the list here.
+	 */
+	FORCEINLINE void ToggleSortOrder()
+	{
+		this->flags ^= VL_DESC;
+
+		if (this->IsSortable()) this->Reverse();
+	}
+
+	/**
+	 * 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.
+	 *
+	 * @param compare The function to compare two list items
+	 * @return true if the list sequence has been altered
+	 * */
+	FORCEINLINE bool Sort(SortFunction *compare)
+	{
+		/* Do not sort if the resort bit is not set */
+		if (!HASBITS(this->flags, VL_RESORT)) return false;
+
+		CLRBITS(this->flags, VL_RESORT);
+
+		this->ResetResortTimer();
+
+		/* Do not sort when the list is not sortable */
+		if (!this->IsSortable()) return false;
+
+		const bool desc = HASBITS(this->flags, VL_DESC);
+
+		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();
+			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--;
+				}
+			}
+		}
+		return true;
+	}
+
+	/**
+	 * Hand the array of sort function pointers to the sort list
+	 *
+	 * @param n_funcs The pointer to the first sort func
+	 */
+	void SetSortFuncs(SortFunction* const* n_funcs)
+	{
+		this->func_list = n_funcs;
+	}
+
+	/**
+	 * Overload of Sort()
+	 * Overloaded to reduce external code
+	 *
+	 * @return true if the list sequence has been altered
+	 */
+	bool Sort()
+	{
+		assert(this->func_list != NULL);
+		return this->Sort(this->func_list[this->sort_type]);
+	}
+
+	/**
+	 * Check if a rebuild is needed
+	 * @return true if a rebuild is needed
+	 */
+	bool NeedRebuild() const
+	{
+		return HASBITS(this->flags, VL_REBUILD);
+	}
+
+	/**
+	 * Force that a rebuild is needed
+	 */
+	void ForceRebuild()
+	{
+		SETBITS(this->flags, VL_REBUILD);
+	}
+
+	/**
+	 * Notify the sortlist that the rebuild is done
+	 *
+	 * @note This forces a resort
+	 */
+	void RebuildDone()
+	{
+		CLRBITS(this->flags, VL_REBUILD);
+		SETBITS(this->flags, VL_RESORT);
+	}
 };
 
 #endif /* SORTLIST_TYPE_H */
--- a/src/sound.cpp	Thu May 29 12:52:24 2008 +0000
+++ b/src/sound.cpp	Thu May 29 15:56:32 2008 +0000
@@ -29,7 +29,7 @@
 	uint i;
 
 	FioOpenFile(SOUND_SLOT, filename);
-	uint pos = FioGetPos();
+	size_t pos = FioGetPos();
 	uint count = FioReadDword() / 8;
 
 	/* Simple check for the correct number of original sounds. */
--- a/src/sound_type.h	Thu May 29 12:52:24 2008 +0000
+++ b/src/sound_type.h	Thu May 29 15:56:32 2008 +0000
@@ -20,8 +20,8 @@
 
 struct FileEntry {
 	uint8 file_slot;
-	uint32 file_offset;
-	uint32 file_size;
+	size_t file_offset;
+	size_t file_size;
 	uint16 rate;
 	uint8 bits_per_sample;
 	uint8 channels;
--- a/src/spritecache.cpp	Thu May 29 12:52:24 2008 +0000
+++ b/src/spritecache.cpp	Thu May 29 15:56:32 2008 +0000
@@ -25,7 +25,7 @@
 struct SpriteCache {
 	void *ptr;
 	uint32 id;
-	uint32 file_pos;
+	size_t file_pos;
 	uint16 file_slot;
 	int16 lru;
 };
@@ -123,7 +123,7 @@
 static void* ReadSprite(SpriteCache *sc, SpriteID id, bool real_sprite)
 {
 	uint8 file_slot = sc->file_slot;
-	uint32 file_pos = sc->file_pos;
+	size_t file_pos = sc->file_pos;
 
 	DEBUG(sprite, 9, "Load sprite %d", id);
 
@@ -241,7 +241,7 @@
 bool LoadNextSprite(int load_index, byte file_slot, uint file_sprite_id)
 {
 	SpriteCache *sc;
-	uint32 file_pos = FioGetPos();
+	size_t file_pos = FioGetPos();
 
 	if (!ReadSpriteHeaderSkipData()) return false;
 
@@ -279,9 +279,9 @@
 	return (MemBlock*)((byte*)block + (block->size & ~S_FREE_MASK));
 }
 
-static uint32 GetSpriteCacheUsage()
+static size_t GetSpriteCacheUsage()
 {
-	uint32 tot_size = 0;
+	size_t tot_size = 0;
 	MemBlock* s;
 
 	for (s = _spritecache_ptr; s->size != 0; s = NextBlock(s)) {
--- a/src/spriteloader/grf.cpp	Thu May 29 12:52:24 2008 +0000
+++ b/src/spriteloader/grf.cpp	Thu May 29 15:56:32 2008 +0000
@@ -9,7 +9,7 @@
 #include "../core/alloc_func.hpp"
 #include "grf.hpp"
 
-bool SpriteLoaderGrf::LoadSprite(SpriteLoader::Sprite *sprite, uint8 file_slot, uint32 file_pos)
+bool SpriteLoaderGrf::LoadSprite(SpriteLoader::Sprite *sprite, uint8 file_slot, size_t file_pos)
 {
 	/* Open the right file and go to the correct position */
 	FioSeekToFile(file_slot, file_pos);
--- a/src/spriteloader/grf.hpp	Thu May 29 12:52:24 2008 +0000
+++ b/src/spriteloader/grf.hpp	Thu May 29 15:56:32 2008 +0000
@@ -12,7 +12,7 @@
 	/**
 	 * Load a sprite from the disk and return a sprite struct which is the same for all loaders.
 	 */
-	bool LoadSprite(SpriteLoader::Sprite *sprite, uint8 file_slot, uint32 file_pos);
+	bool LoadSprite(SpriteLoader::Sprite *sprite, uint8 file_slot, size_t file_pos);
 };
 
 #endif /* SPRITELOADER_GRF_HPP */
--- a/src/spriteloader/png.cpp	Thu May 29 12:52:24 2008 +0000
+++ b/src/spriteloader/png.cpp	Thu May 29 15:56:32 2008 +0000
@@ -170,11 +170,11 @@
 	return true;
 }
 
-bool SpriteLoaderPNG::LoadSprite(SpriteLoader::Sprite *sprite, uint8 file_slot, uint32 file_pos)
+bool SpriteLoaderPNG::LoadSprite(SpriteLoader::Sprite *sprite, uint8 file_slot, size_t file_pos)
 {
 	const char *filename = FioGetFilename(file_slot);
-	if (!LoadPNG(sprite, filename, file_pos, false)) return false;
-	if (!LoadPNG(sprite, filename, file_pos, true)) return false;
+	if (!LoadPNG(sprite, filename, (uint32)file_pos, false)) return false;
+	if (!LoadPNG(sprite, filename, (uint32)file_pos, true)) return false;
 	return true;
 }
 
--- a/src/spriteloader/png.hpp	Thu May 29 12:52:24 2008 +0000
+++ b/src/spriteloader/png.hpp	Thu May 29 15:56:32 2008 +0000
@@ -12,7 +12,7 @@
 	/**
 	 * Load a sprite from the disk and return a sprite struct which is the same for all loaders.
 	 */
-	bool LoadSprite(SpriteLoader::Sprite *sprite, uint8 file_slot, uint32 file_pos);
+	bool LoadSprite(SpriteLoader::Sprite *sprite, uint8 file_slot, size_t file_pos);
 };
 
 #endif /* SPRITELOADER_PNG_HPP */
--- a/src/spriteloader/spriteloader.hpp	Thu May 29 12:52:24 2008 +0000
+++ b/src/spriteloader/spriteloader.hpp	Thu May 29 15:56:32 2008 +0000
@@ -26,7 +26,7 @@
 	/**
 	 * Load a sprite from the disk and return a sprite struct which is the same for all loaders.
 	 */
-	virtual bool LoadSprite(SpriteLoader::Sprite *sprite, uint8 file_slot, uint32 file_pos) = 0;
+	virtual bool LoadSprite(SpriteLoader::Sprite *sprite, uint8 file_slot, size_t file_pos) = 0;
 
 	virtual ~SpriteLoader() { }
 };
--- a/src/station.cpp	Thu May 29 12:52:24 2008 +0000
+++ b/src/station.cpp	Thu May 29 15:56:32 2008 +0000
@@ -285,7 +285,7 @@
 		/* check new rect dimensions against preset max */
 		int w = new_rect.right - new_rect.left + 1;
 		int h = new_rect.bottom - new_rect.top + 1;
-		if (mode != ADD_FORCE && (w > _settings.station.station_spread || h > _settings.station.station_spread)) {
+		if (mode != ADD_FORCE && (w > _settings_game.station.station_spread || h > _settings_game.station.station_spread)) {
 			assert(mode != ADD_TRY);
 			_error_message = STR_306C_STATION_TOO_SPREAD_OUT;
 			return false;
--- a/src/station_cmd.cpp	Thu May 29 12:52:24 2008 +0000
+++ b/src/station_cmd.cpp	Thu May 29 15:56:32 2008 +0000
@@ -296,7 +296,7 @@
 				CountMapSquareAround(tile, CMSATree) >= 8 ||
 				CountMapSquareAround(tile, CMSAForest) >= 2)
 			) {
-		return _settings.game_creation.landscape == LT_TROPIC ? STR_SV_STNAME_FOREST : STR_SV_STNAME_WOODS;
+		return _settings_game.game_creation.landscape == LT_TROPIC ? STR_SV_STNAME_FOREST : STR_SV_STNAME_WOODS;
 	}
 
 	/* check elevation compared to town */
@@ -563,7 +563,7 @@
 			TileXY(rect.left, rect.bottom),
 			rect.right - rect.left   + 1,
 			rect.top   - rect.bottom + 1,
-			_settings.station.modified_catchment ? FindCatchmentRadius(st) : (uint)CA_UNMODIFIED
+			_settings_game.station.modified_catchment ? FindCatchmentRadius(st) : (uint)CA_UNMODIFIED
 		);
 	} else {
 		memset(accepts, 0, sizeof(accepts));
@@ -692,7 +692,7 @@
 		 *     b) the build_on_slopes switch is disabled
 		 */
 		if (IsSteepSlope(tileh) ||
-				((!_settings.construction.build_on_slopes) && tileh != SLOPE_FLAT)) {
+				((!_settings_game.construction.build_on_slopes) && tileh != SLOPE_FLAT)) {
 			return_cmd_error(STR_0007_FLAT_LAND_REQUIRED);
 		}
 
@@ -750,7 +750,7 @@
 	uint w = fin[1];
 	uint h = fin[2];
 
-	if (_settings.station.nonuniform_stations) {
+	if (_settings_game.station.nonuniform_stations) {
 		/* determine new size of train station region.. */
 		int x = min(TileX(st->train_tile), TileX(tile));
 		int y = min(TileY(st->train_tile), TileY(tile));
@@ -794,7 +794,7 @@
 		}
 	}
 	/* make sure the final size is not too big. */
-	if (curw > _settings.station.station_spread || curh > _settings.station.station_spread) {
+	if (curw > _settings_game.station.station_spread || curh > _settings_game.station.station_spread) {
 		_error_message = STR_306C_STATION_TOO_SPREAD_OUT;
 		return false;
 	}
@@ -883,7 +883,7 @@
 		w_org = numtracks;
 	}
 
-	if (h_org > _settings.station.station_spread || w_org > _settings.station.station_spread) return CMD_ERROR;
+	if (h_org > _settings_game.station.station_spread || w_org > _settings_game.station.station_spread) return CMD_ERROR;
 
 	/* these values are those that will be stored in train_tile and station_platforms */
 	uint finalvalues[3];
@@ -896,14 +896,14 @@
 	/* If DC_EXEC is in flag, do not want to pass it to CheckFlatLandBelow, because of a nice bug
 	 * for detail info, see:
 	 * https://sourceforge.net/tracker/index.php?func=detail&aid=1029064&group_id=103924&atid=636365 */
-	CommandCost ret = CheckFlatLandBelow(tile_org, w_org, h_org, flags & ~DC_EXEC, 5 << axis, _settings.station.nonuniform_stations ? &est : NULL);
+	CommandCost ret = CheckFlatLandBelow(tile_org, w_org, h_org, flags & ~DC_EXEC, 5 << axis, _settings_game.station.nonuniform_stations ? &est : NULL);
 	if (CmdFailed(ret)) return ret;
 	CommandCost cost(EXPENSES_CONSTRUCTION, ret.GetCost() + (numtracks * _price.train_station_track + _price.train_station_length) * plat_len);
 
 	Station *st = NULL;
 	bool check_surrounding = true;
 
-	if (_settings.station.adjacent_stations) {
+	if (_settings_game.station.adjacent_stations) {
 		if (est != INVALID_STATION) {
 			if (HasBit(p1, 24)) {
 				/* You can't build an adjacent station over the top of one that
@@ -938,7 +938,7 @@
 
 		if (st->train_tile != 0) {
 			/* check if we want to expanding an already existing station? */
-			if (!_settings.station.join_stations)
+			if (!_settings_game.station.join_stations)
 				return_cmd_error(STR_3005_TOO_CLOSE_TO_ANOTHER_RAILROAD);
 			if (!CanExpandRailroadStation(st, finalvalues, axis))
 				return CMD_ERROR;
@@ -993,7 +993,7 @@
 		/* Now really clear the land below the station
 		 * It should never return CMD_ERROR.. but you never know ;)
 		 * (a bit strange function name for it, but it really does clear the land, when DC_EXEC is in flags) */
-		ret = CheckFlatLandBelow(tile_org, w_org, h_org, flags, 5 << axis, _settings.station.nonuniform_stations ? &est : NULL);
+		ret = CheckFlatLandBelow(tile_org, w_org, h_org, flags, 5 << axis, _settings_game.station.nonuniform_stations ? &est : NULL);
 		if (CmdFailed(ret)) return ret;
 
 		st->train_tile = finalvalues[0];
@@ -1162,7 +1162,7 @@
 		/* Do not allow removing from stations if non-uniform stations are not enabled
 		 * The check must be here to give correct error message
 		 */
-		if (!_settings.station.nonuniform_stations) return_cmd_error(STR_NONUNIFORM_STATIONS_DISALLOWED);
+		if (!_settings_game.station.nonuniform_stations) return_cmd_error(STR_NONUNIFORM_STATIONS_DISALLOWED);
 
 		/* If we reached here, the tile is valid so increase the quantity of tiles we will remove */
 		quantity++;
@@ -1207,7 +1207,7 @@
 static CommandCost RemoveRailroadStation(Station *st, TileIndex tile, uint32 flags)
 {
 	/* if there is flooding and non-uniform stations are enabled, remove platforms tile by tile */
-	if (_current_player == OWNER_WATER && _settings.station.nonuniform_stations) {
+	if (_current_player == OWNER_WATER && _settings_game.station.nonuniform_stations) {
 		return DoCommand(tile, 0, 0, DC_EXEC, CMD_REMOVE_FROM_RAILROAD_STATION);
 	}
 
@@ -1326,7 +1326,7 @@
 			Owner road_owner = GetRoadOwner(tile, ROADTYPE_ROAD);
 			if (road_owner == OWNER_TOWN) {
 				town_owned_road = true;
-				if (!_settings.construction.road_stop_on_town_road) return_cmd_error(STR_DRIVE_THROUGH_ERROR_ON_TOWN_ROAD);
+				if (!_settings_game.construction.road_stop_on_town_road) return_cmd_error(STR_DRIVE_THROUGH_ERROR_ON_TOWN_ROAD);
 			} else {
 				if (road_owner != OWNER_NONE && !CheckOwnership(road_owner)) return CMD_ERROR;
 			}
@@ -1350,7 +1350,7 @@
 
 	Station *st = NULL;
 
-	if (!_settings.station.adjacent_stations || !HasBit(p2, 5)) {
+	if (!_settings_game.station.adjacent_stations || !HasBit(p2, 5)) {
 		st = GetStationAround(tile, 1, 1, INVALID_STATION);
 		if (st == CHECK_STATIONS_ERR) return CMD_ERROR;
 	}
@@ -1681,18 +1681,15 @@
 	 * adding the town_council_tolerance 4 times, as a way to graduate, depending of the tolerance.
 	 * Basically, it says that the less tolerant a town is, the bigger the distance before
 	 * an actual decrease can be granted */
-	uint8 town_tolerance_distance = 8 + (_settings.difficulty.town_council_tolerance * 4);
-
-	/* The airport is in the "inner" distance where there is no noise reduction */
-	if (distance < town_tolerance_distance) return afc->noise_level;
+	uint8 town_tolerance_distance = 8 + (_settings_game.difficulty.town_council_tolerance * 4);
 
 	/* now, we want to have the distance segmented using the distance judged bareable by town
 	 * This will give us the coefficient of reduction the distance provides. */
-	uint noise_reduction = min(afc->noise_level, distance / town_tolerance_distance);
-
-	/* If the noise reduction equals the airport noise itself, don't give it for free. Use it all minus 1.
+	uint noise_reduction = distance / town_tolerance_distance;
+
+	/* If the noise reduction equals the airport noise itself, don't give it for free.
 	 * Otherwise, simply reduce the airport's level. */
-	return max(1U, noise_reduction == afc->noise_level ? afc->noise_level - 1 : afc->noise_level - noise_reduction);
+	return noise_reduction >= afc->noise_level ? 1 : afc->noise_level - noise_reduction;
 }
 
 /** Place an Airport.
@@ -1718,7 +1715,7 @@
 	int h = afc->size_y;
 	Station *st = NULL;
 
-	if (w > _settings.station.station_spread || h > _settings.station.station_spread) {
+	if (w > _settings_game.station.station_spread || h > _settings_game.station.station_spread) {
 		_error_message = STR_306C_STATION_TOO_SPREAD_OUT;
 		return CMD_ERROR;
 	}
@@ -1732,7 +1729,7 @@
 	/* Check if local auth would allow a new airport */
 	bool authority_refused;
 
-	if (_settings.economy.station_noise_level) {
+	if (_settings_game.economy.station_noise_level) {
 		/* do not allow to build a new airport if this raise the town noise over the maximum allowed by town */
 		authority_refused = (t->noise_reached + newnoise_level) > t->MaxTownNoise();
 	} else {
@@ -1749,7 +1746,7 @@
 		return_cmd_error(STR_2035_LOCAL_AUTHORITY_REFUSES);
 	}
 
-	if (!_settings.station.adjacent_stations || !HasBit(p2, 0)) {
+	if (!_settings_game.station.adjacent_stations || !HasBit(p2, 0)) {
 		st = GetStationAround(tile, w, h, INVALID_STATION);
 		if (st == CHECK_STATIONS_ERR) return CMD_ERROR;
 	} else {
@@ -1824,7 +1821,7 @@
 		InvalidateWindowData(WC_STATION_LIST, st->owner, 0);
 		InvalidateWindowWidget(WC_STATION_VIEW, st->index, SVW_PLANES);
 
-		if (_settings.economy.station_noise_level) {
+		if (_settings_game.economy.station_noise_level) {
 			InvalidateWindow(WC_TOWN_VIEW, st->town->index);
 		}
 	}
@@ -1881,7 +1878,7 @@
 
 		InvalidateWindowWidget(WC_STATION_VIEW, st->index, SVW_PLANES);
 
-		if (_settings.economy.station_noise_level) {
+		if (_settings_game.economy.station_noise_level) {
 			InvalidateWindow(WC_TOWN_VIEW, st->town->index);
 		}
 
@@ -2044,7 +2041,7 @@
 	/* middle */
 	Station *st = NULL;
 
-	if (!_settings.station.adjacent_stations || !HasBit(p1, 0)) {
+	if (!_settings_game.station.adjacent_stations || !HasBit(p1, 0)) {
 		st = GetStationAround(
 				tile + ToTileIndexDiff(_dock_tileoffs_chkaround[direction]),
 				_dock_w_chk[direction], _dock_h_chk[direction], INVALID_STATION);
@@ -2774,7 +2771,7 @@
 	int w_prod; // width and height of the "producer" of the cargo
 	int h_prod;
 	int max_rad;
-	if (_settings.station.modified_catchment) {
+	if (_settings_game.station.modified_catchment) {
 		w_prod = w;
 		h_prod = h;
 		w += 2 * MAX_CATCHMENT;
@@ -2797,7 +2794,7 @@
 		if (st->IsBuoy()) continue; // bouys don't accept cargo
 
 
-		if (_settings.station.modified_catchment) {
+		if (_settings_game.station.modified_catchment) {
 			/* min and max coordinates of the producer relative */
 			const int x_min_prod = max_rad + 1;
 			const int x_max_prod = max_rad + w_prod;
@@ -2851,7 +2848,7 @@
 
 		if (st->goods[type].rating == 0) continue; // Lowest possible rating, better not to give cargo anymore
 
-		if (_settings.order.selectgoods && st->goods[type].last_speed == 0) continue; // Selectively servicing stations, and not this one
+		if (_settings_game.order.selectgoods && st->goods[type].last_speed == 0) continue; // Selectively servicing stations, and not this one
 
 		if (IsCargoInClass(type, CC_PASSENGERS)) {
 			if (st->facilities == FACIL_TRUCK_STOP) continue; // passengers are never served by just a truck stop
@@ -3076,7 +3073,7 @@
 
 static CommandCost TerraformTile_Station(TileIndex tile, uint32 flags, uint z_new, Slope tileh_new)
 {
-	if (_settings.construction.build_on_slopes && AutoslopeEnabled()) {
+	if (_settings_game.construction.build_on_slopes && AutoslopeEnabled()) {
 		/* TODO: If you implement newgrf callback 149 'land slope check', you have to decide what to do with it here.
 		 *       TTDP does not call it.
 		 */
--- a/src/station_gui.cpp	Thu May 29 12:52:24 2008 +0000
+++ b/src/station_gui.cpp	Thu May 29 15:56:32 2008 +0000
@@ -30,13 +30,6 @@
 #include "table/strings.h"
 #include "table/sprites.h"
 
-typedef int CDECL StationSortListingTypeFunction(const void*, const void*);
-
-static StationSortListingTypeFunction StationNameSorter;
-static StationSortListingTypeFunction StationTypeSorter;
-static StationSortListingTypeFunction StationWaitingSorter;
-static StationSortListingTypeFunction StationRatingMaxSorter;
-
 bool _station_show_coverage;
 
 /**
@@ -86,174 +79,134 @@
 	if (rating != 0) GfxFillRect(x + 1, y, x + rating, y, 0xD0);
 }
 
-const StringID _station_sort_listing[] = {
-	STR_SORT_BY_DROPDOWN_NAME,
-	STR_SORT_BY_FACILITY,
-	STR_SORT_BY_WAITING,
-	STR_SORT_BY_RATING_MAX,
-	INVALID_STRING_ID
-};
-
-static char _bufcache[64];
-static const Station *_last_station;
-static int _internal_sort_order;
-
-static int CDECL StationNameSorter(const void *a, const void *b)
-{
-	const Station *st1 = *(const Station**)a;
-	const Station *st2 = *(const Station**)b;
-	char buf1[64];
-
-	SetDParam(0, st1->index);
-	GetString(buf1, STR_STATION, lastof(buf1));
-
-	if (st2 != _last_station) {
-		_last_station = st2;
-		SetDParam(0, st2->index);
-		GetString(_bufcache, STR_STATION, lastof(_bufcache));
-	}
-
-	int r = strcmp(buf1, _bufcache); // sort by name
-	return (_internal_sort_order & 1) ? -r : r;
-}
-
-static int CDECL StationTypeSorter(const void *a, const void *b)
-{
-	const Station *st1 = *(const Station**)a;
-	const Station *st2 = *(const Station**)b;
-	return (_internal_sort_order & 1) ? st2->facilities - st1->facilities : st1->facilities - st2->facilities;
-}
-
-static const uint32 _cargo_filter_max = UINT32_MAX;
-static uint32 _cargo_filter = _cargo_filter_max;
-
-static int CDECL StationWaitingSorter(const void *a, const void *b)
-{
-	const Station *st1 = *(const Station**)a;
-	const Station *st2 = *(const Station**)b;
-	Money sum1 = 0, sum2 = 0;
-
-	for (CargoID j = 0; j < NUM_CARGO; j++) {
-		if (!HasBit(_cargo_filter, j)) continue;
-		if (!st1->goods[j].cargo.Empty()) sum1 += GetTransportedGoodsIncome(st1->goods[j].cargo.Count(), 20, 50, j);
-		if (!st2->goods[j].cargo.Empty()) sum2 += GetTransportedGoodsIncome(st2->goods[j].cargo.Count(), 20, 50, j);
-	}
-
-	return (_internal_sort_order & 1) ? ClampToI32(sum2 - sum1) : ClampToI32(sum1 - sum2);
-}
-
-/**
- * qsort-compatible version of sorting two stations by maximum rating
- * @param a   First object to be sorted, must be of type (const Station *)
- * @param b   Second object to be sorted, must be of type (const Station *)
- * @return    The sort order
- * @retval >0 a should come before b in the list
- * @retval <0 b should come before a in the list
- */
-static int CDECL StationRatingMaxSorter(const void *a, const void *b)
-{
-	const Station *st1 = *(const Station**)a;
-	const Station *st2 = *(const Station**)b;
-	byte maxr1 = 0;
-	byte maxr2 = 0;
-
-	for (CargoID j = 0; j < NUM_CARGO; j++) {
-		if (HasBit(st1->goods[j].acceptance_pickup, GoodsEntry::PICKUP)) maxr1 = max(maxr1, st1->goods[j].rating);
-		if (HasBit(st2->goods[j].acceptance_pickup, GoodsEntry::PICKUP)) maxr2 = max(maxr2, st2->goods[j].rating);
-	}
-
-	return (_internal_sort_order & 1) ? maxr2 - maxr1 : maxr1 - maxr2;
-}
-
 typedef GUIList<const Station*> GUIStationList;
 
 /**
- * Rebuild station list if the VL_REBUILD flag is set
- *
- * @param sl pointer to plstations_d (station list and flags)
- * @param owner player whose stations are to be in list
- * @param facilities types of stations of interest
- * @param cargo_filter bitmap of cargo types to include
- * @param include_empty whether we should include stations without waiting cargo
- */
-static void BuildStationsList(GUIStationList *sl, PlayerID owner, byte facilities, uint32 cargo_filter, bool include_empty)
-{
-	uint n = 0;
-	const Station *st;
-
-	if (!(sl->flags & VL_REBUILD)) return;
-
-	/* Create array for sorting */
-	const Station **station_sort = MallocT<const Station*>(GetMaxStationIndex() + 1);
-
-	DEBUG(misc, 3, "Building station list for player %d", owner);
-
-	FOR_ALL_STATIONS(st) {
-		if (st->owner == owner || (st->owner == OWNER_NONE && !st->IsBuoy() && HasStationInUse(st->index, owner))) {
-			if (facilities & st->facilities) { //only stations with selected facilities
-				int num_waiting_cargo = 0;
-				for (CargoID j = 0; j < NUM_CARGO; j++) {
-					if (!st->goods[j].cargo.Empty()) {
-						num_waiting_cargo++; //count number of waiting cargo
-						if (HasBit(cargo_filter, j)) {
-							station_sort[n++] = st;
-							break;
-						}
-					}
-				}
-				/* stations without waiting cargo */
-				if (num_waiting_cargo == 0 && include_empty) {
-					station_sort[n++] = st;
-				}
-			}
-		}
-	}
-
-	free((void*)sl->sort_list);
-	sl->sort_list = MallocT<const Station*>(n);
-	sl->list_length = n;
-
-	for (uint i = 0; i < n; ++i) sl->sort_list[i] = station_sort[i];
-
-	sl->flags &= ~VL_REBUILD;
-	sl->flags |= VL_RESORT;
-	free((void*)station_sort);
-}
-
-
-/**
- * Sort station list if the VL_RESORT flag is set
- *
- * @param sl pointer to plstations_d (station list and flags)
- */
-static void SortStationsList(GUIStationList *sl)
-{
-	static StationSortListingTypeFunction *const _station_sorter[] = {
-		&StationNameSorter,
-		&StationTypeSorter,
-		&StationWaitingSorter,
-		&StationRatingMaxSorter
-	};
-
-	if (!(sl->flags & VL_RESORT)) return;
-
-	_internal_sort_order = sl->flags & VL_DESC;
-	_last_station = NULL; // used for "cache" in namesorting
-	qsort((void*)sl->sort_list, sl->list_length, sizeof(sl->sort_list[0]), _station_sorter[sl->sort_type]);
-
-	sl->resort_timer = DAY_TICKS * PERIODIC_RESORT_DAYS;
-	sl->flags &= ~VL_RESORT;
-}
-
-/**
  * The list of stations per player.
  */
-struct PlayerStationsWindow : public Window, public GUIStationList
+class PlayerStationsWindow : public Window
 {
-	static Listing station_sort;
-	static byte facilities;
-	static bool include_empty;
+protected:
+	/* Runtime saved values */
+	static Listing last_sorting;
+	static byte facilities;               // types of stations of interest
+	static bool include_empty;            // whether we should include stations without waiting cargo
+	static const uint32 cargo_filter_max;
+	static uint32 cargo_filter;           // bitmap of cargo types to include
+	static const Station *last_station;
 
+	/* Constants for sorting stations */
+	static const StringID sorter_names[];
+	static GUIStationList::SortFunction *const sorter_funcs[];
+
+	GUIStationList stations;
+
+
+	/**
+	 * (Re)Build station list
+	 *
+	 * @param owner player whose stations are to be in list
+	 */
+	void BuildStationsList(const PlayerID owner)
+	{
+		if (!this->stations.NeedRebuild()) return;
+
+		DEBUG(misc, 3, "Building station list for player %d", owner);
+
+		this->stations.Clear();
+
+		const Station *st;
+		FOR_ALL_STATIONS(st) {
+			if (st->owner == owner || (st->owner == OWNER_NONE && !st->IsBuoy() && HasStationInUse(st->index, owner))) {
+				if (this->facilities & st->facilities) { // only stations with selected facilities
+					int num_waiting_cargo = 0;
+					for (CargoID j = 0; j < NUM_CARGO; j++) {
+						if (!st->goods[j].cargo.Empty()) {
+							num_waiting_cargo++; // count number of waiting cargo
+							if (HasBit(this->cargo_filter, j)) {
+								*this->stations.Append() = st;
+								break;
+							}
+						}
+					}
+					/* stations without waiting cargo */
+					if (num_waiting_cargo == 0 && this->include_empty) {
+						*this->stations.Append() = st;
+					}
+				}
+			}
+		}
+
+		this->stations.Compact();
+		this->stations.RebuildDone();
+	}
+
+	/** Sort stations by their name */
+	static int CDECL StationNameSorter(const Station* const *a, const Station* const *b)
+	{
+		static char buf_cache[64];
+		char buf[64];
+
+		SetDParam(0, (*a)->index);
+		GetString(buf, STR_STATION, lastof(buf));
+
+		if (*b != last_station) {
+			last_station = *b;
+			SetDParam(0, (*b)->index);
+			GetString(buf_cache, STR_STATION, lastof(buf_cache));
+		}
+
+		return strcmp(buf, buf_cache);
+	}
+
+	/** Sort stations by their type */
+	static int CDECL StationTypeSorter(const Station* const *a, const Station* const *b)
+	{
+		return (*a)->facilities - (*b)->facilities;
+	}
+
+	/** Sort stations by their waiting cargo */
+	static int CDECL StationWaitingSorter(const Station* const *a, const Station* const *b)
+	{
+		Money sum1 = 0;
+		Money sum2 = 0;
+
+		for (CargoID j = 0; j < NUM_CARGO; j++) {
+			if (!HasBit(cargo_filter, j)) continue;
+			if (!(*a)->goods[j].cargo.Empty()) sum1 += GetTransportedGoodsIncome((*a)->goods[j].cargo.Count(), 20, 50, j);
+			if (!(*b)->goods[j].cargo.Empty()) sum2 += GetTransportedGoodsIncome((*b)->goods[j].cargo.Count(), 20, 50, j);
+		}
+
+		return ClampToI32(sum1 - sum2);
+	}
+
+	/** Sort stations by their rating */
+	static int CDECL StationRatingMaxSorter(const Station* const *a, const Station* const *b)
+	{
+		byte maxr1 = 0;
+		byte maxr2 = 0;
+
+		for (CargoID j = 0; j < NUM_CARGO; j++) {
+			if (HasBit((*a)->goods[j].acceptance_pickup, GoodsEntry::PICKUP)) maxr1 = max(maxr1, (*a)->goods[j].rating);
+			if (HasBit((*b)->goods[j].acceptance_pickup, GoodsEntry::PICKUP)) maxr2 = max(maxr2, (*b)->goods[j].rating);
+		}
+
+		return maxr1 - maxr2;
+	}
+
+	/** Sort the stations list */
+	void SortStationsList()
+	{
+		if (!this->stations.Sort()) return;
+
+		/* Reset name sorter sort cache */
+		this->last_station = NULL;
+
+		/* Set the modified widget dirty */
+		this->InvalidateWidget(SLW_LIST);
+	}
+
+public:
 	PlayerStationsWindow(const WindowDesc *desc, WindowNumber window_number) : Window(desc, window_number)
 	{
 		this->caption_color = (byte)this->window_number;
@@ -286,7 +239,7 @@
 			wi->data     = 0;
 			wi->tooltips = STR_USE_CTRL_TO_SELECT_MORE;
 
-			if (HasBit(_cargo_filter, c)) this->LowerWidget(SLW_CARGOSTART + i);
+			if (HasBit(this->cargo_filter, c)) this->LowerWidget(SLW_CARGOSTART + i);
 			i++;
 		}
 
@@ -302,46 +255,48 @@
 			this->resize.width = this->width;
 		}
 
-		if (_cargo_filter == _cargo_filter_max) _cargo_filter = _cargo_mask;
+		if (this->cargo_filter == this->cargo_filter_max) this->cargo_filter = _cargo_mask;
 
 		for (uint i = 0; i < 5; i++) {
-			if (HasBit(facilities, i)) this->LowerWidget(i + SLW_TRAIN);
+			if (HasBit(this->facilities, i)) this->LowerWidget(i + SLW_TRAIN);
 		}
-		this->SetWidgetLoweredState(SLW_FACILALL, facilities == (FACIL_TRAIN | FACIL_TRUCK_STOP | FACIL_BUS_STOP | FACIL_AIRPORT | FACIL_DOCK));
-		this->SetWidgetLoweredState(SLW_CARGOALL, _cargo_filter == _cargo_mask && include_empty);
-		this->SetWidgetLoweredState(SLW_NOCARGOWAITING, include_empty);
+		this->SetWidgetLoweredState(SLW_FACILALL, this->facilities == (FACIL_TRAIN | FACIL_TRUCK_STOP | FACIL_BUS_STOP | FACIL_AIRPORT | FACIL_DOCK));
+		this->SetWidgetLoweredState(SLW_CARGOALL, this->cargo_filter == _cargo_mask && this->include_empty);
+		this->SetWidgetLoweredState(SLW_NOCARGOWAITING, this->include_empty);
 
-		this->sort_list = NULL;
-		this->flags = VL_REBUILD;
-		this->sort_type = station_sort.criteria;
-		if (station_sort.order) this->flags |= VL_DESC;
+		this->stations.SetListing(this->last_sorting);
+		this->stations.SetSortFuncs(this->sorter_funcs);
+		this->stations.ForceRebuild();
+		this->stations.NeedResort();
+		this->SortStationsList();
 
-		/* set up resort timer */
-		this->resort_timer = DAY_TICKS * PERIODIC_RESORT_DAYS;
+		this->widget[SLW_SORTDROPBTN].data = this->sorter_names[this->stations.SortType()];
 
 		this->FindWindowPlacementAndResize(desc);
 	}
 
+	~PlayerStationsWindow()
+	{
+		this->last_sorting = this->stations.GetListing();
+	}
+
 	virtual void OnPaint()
 	{
-		PlayerID owner = (PlayerID)this->window_number;
+		const PlayerID owner = (PlayerID)this->window_number;
 
-		BuildStationsList(this, owner, facilities, _cargo_filter, include_empty);
-		SortStationsList(this);
+		this->BuildStationsList(owner);
+		this->SortStationsList();
 
-		SetVScrollCount(this, this->list_length);
+		SetVScrollCount(this, this->stations.Length());
 
 		/* draw widgets, with player's name in the caption */
 		SetDParam(0, owner);
 		SetDParam(1, this->vscroll.count);
 
-		/* Set text of sort by dropdown */
-		this->widget[SLW_SORTDROPBTN].data = _station_sort_listing[this->sort_type];
-
 		this->DrawWidgets();
 
 		/* draw arrow pointing up/down for ascending/descending sorting */
-		this->DrawSortButtonState(SLW_SORTBY, this->flags & VL_DESC ? SBS_DOWN : SBS_UP);
+		this->DrawSortButtonState(SLW_SORTBY, this->stations.IsDescSortOrder() ? SBS_DOWN : SBS_UP);
 
 		int cg_ofst;
 		int x = 89;
@@ -353,7 +308,7 @@
 			const CargoSpec *cs = GetCargo(c);
 			if (!cs->IsValid()) continue;
 
-			cg_ofst = HasBit(_cargo_filter, c) ? 2 : 1;
+			cg_ofst = HasBit(this->cargo_filter, c) ? 2 : 1;
 			GfxFillRect(x + cg_ofst, y + cg_ofst, x + cg_ofst + 10 , y + cg_ofst + 7, cs->rating_colour);
 			DrawStringCentered(x + 6 + cg_ofst, y + cg_ofst, cs->abbrev, TC_BLACK);
 			x += 14;
@@ -375,11 +330,11 @@
 			return;
 		}
 
-		int max = min(this->vscroll.pos + this->vscroll.cap, this->list_length);
+		int max = min(this->vscroll.pos + this->vscroll.cap, this->stations.Length());
 		y = 40; // start of the list-widget
 
 		for (int i = this->vscroll.pos; i < max; ++i) { // do until max number of stations of owner
-			const Station *st = this->sort_list[i];
+			const Station *st = this->stations[i];
 			int x;
 
 			assert(st->xy != 0);
@@ -413,9 +368,9 @@
 
 				id_v += this->vscroll.pos;
 
-				if (id_v >= this->list_length) return; // click out of list bound
+				if (id_v >= this->stations.Length()) return; // click out of list bound
 
-				const Station *st = this->sort_list[id_v];
+				const Station *st = this->stations[id_v];
 				/* do not check HasStationInUse - it is slow and may be invalid */
 				assert(st->owner == (PlayerID)this->window_number || (st->owner == OWNER_NONE && !st->IsBuoy()));
 
@@ -433,18 +388,18 @@
 			case SLW_AIRPLANE:
 			case SLW_SHIP:
 				if (_ctrl_pressed) {
-					ToggleBit(facilities, widget - SLW_TRAIN);
+					ToggleBit(this->facilities, widget - SLW_TRAIN);
 					this->ToggleWidgetLoweredState(widget);
 				} else {
 					uint i;
-					FOR_EACH_SET_BIT(i, facilities) {
+					FOR_EACH_SET_BIT(i, this->facilities) {
 						this->RaiseWidget(i + SLW_TRAIN);
 					}
-					SetBit(facilities, widget - SLW_TRAIN);
+					SetBit(this->facilities, widget - SLW_TRAIN);
 					this->LowerWidget(widget);
 				}
-				this->SetWidgetLoweredState(SLW_FACILALL, facilities == (FACIL_TRAIN | FACIL_TRUCK_STOP | FACIL_BUS_STOP | FACIL_AIRPORT | FACIL_DOCK));
-				this->flags |= VL_REBUILD;
+				this->SetWidgetLoweredState(SLW_FACILALL, this->facilities == (FACIL_TRAIN | FACIL_TRUCK_STOP | FACIL_BUS_STOP | FACIL_AIRPORT | FACIL_DOCK));
+				this->stations.ForceRebuild();
 				this->SetDirty();
 				break;
 
@@ -454,8 +409,8 @@
 				}
 				this->LowerWidget(SLW_FACILALL);
 
-				facilities = FACIL_TRAIN | FACIL_TRUCK_STOP | FACIL_BUS_STOP | FACIL_AIRPORT | FACIL_DOCK;
-				this->flags |= VL_REBUILD;
+				this->facilities = FACIL_TRAIN | FACIL_TRUCK_STOP | FACIL_BUS_STOP | FACIL_AIRPORT | FACIL_DOCK;
+				this->stations.ForceRebuild();
 				this->SetDirty();
 				break;
 
@@ -469,42 +424,40 @@
 				this->LowerWidget(SLW_NOCARGOWAITING);
 				this->LowerWidget(SLW_CARGOALL);
 
-				_cargo_filter = _cargo_mask;
-				include_empty = true;
-				this->flags |= VL_REBUILD;
+				this->cargo_filter = _cargo_mask;
+				this->include_empty = true;
+				this->stations.ForceRebuild();
 				this->SetDirty();
 				break;
 			}
 
 			case SLW_SORTBY: // flip sorting method asc/desc
-				this->flags ^= VL_DESC; //DESC-flag
-				station_sort.order = HasBit(this->flags, 0);
-				this->flags |= VL_RESORT;
+				this->stations.ToggleSortOrder();
 				this->flags4 |= 5 << WF_TIMEOUT_SHL;
 				this->LowerWidget(SLW_SORTBY);
 				this->SetDirty();
 				break;
 
 			case SLW_SORTDROPBTN: // select sorting criteria dropdown menu
-				ShowDropDownMenu(this, _station_sort_listing, this->sort_type, SLW_SORTDROPBTN, 0, 0);
+				ShowDropDownMenu(this, this->sorter_names, this->stations.SortType(), SLW_SORTDROPBTN, 0, 0);
 				break;
 
 			case SLW_NOCARGOWAITING:
 				if (_ctrl_pressed) {
-					include_empty = !include_empty;
+					this->include_empty = !this->include_empty;
 					this->ToggleWidgetLoweredState(SLW_NOCARGOWAITING);
 				} else {
 					for (uint i = SLW_CARGOSTART; i < this->widget_count; i++) {
 						this->RaiseWidget(i);
 					}
 
-					_cargo_filter = 0;
-					include_empty = true;
+					this->cargo_filter = 0;
+					this->include_empty = true;
 
 					this->LowerWidget(SLW_NOCARGOWAITING);
 				}
-				this->flags |= VL_REBUILD;
-				this->SetWidgetLoweredState(SLW_CARGOALL, _cargo_filter == _cargo_mask && include_empty);
+				this->SetWidgetLoweredState(SLW_CARGOALL, this->cargo_filter == _cargo_mask && this->include_empty);
+				this->stations.ForceRebuild();
 				this->SetDirty();
 				break;
 
@@ -520,7 +473,7 @@
 					}
 
 					if (_ctrl_pressed) {
-						ToggleBit(_cargo_filter, c);
+						ToggleBit(this->cargo_filter, c);
 						this->ToggleWidgetLoweredState(widget);
 					} else {
 						for (uint i = SLW_CARGOSTART; i < this->widget_count; i++) {
@@ -528,14 +481,14 @@
 						}
 						this->RaiseWidget(SLW_NOCARGOWAITING);
 
-						_cargo_filter = 0;
-						include_empty = false;
+						this->cargo_filter = 0;
+						this->include_empty = false;
 
-						SetBit(_cargo_filter, c);
+						SetBit(this->cargo_filter, c);
 						this->LowerWidget(widget);
 					}
-					this->flags |= VL_REBUILD;
-					this->SetWidgetLoweredState(SLW_CARGOALL, _cargo_filter == _cargo_mask && include_empty);
+					this->SetWidgetLoweredState(SLW_CARGOALL, this->cargo_filter == _cargo_mask && this->include_empty);
+					this->stations.ForceRebuild();
 					this->SetDirty();
 				}
 				break;
@@ -544,22 +497,21 @@
 
 	virtual void OnDropdownSelect(int widget, int index)
 	{
-		if (this->sort_type != index) {
-			/* value has changed -> resort */
-			this->sort_type = index;
-			station_sort.criteria = this->sort_type;
-			this->flags |= VL_RESORT;
+		if (this->stations.SortType() != index) {
+			this->stations.SetSortType(index);
+
+			/* Display the current sort variant */
+			this->widget[SLW_SORTDROPBTN].data = this->sorter_names[this->stations.SortType()];
+
+			this->SetDirty();
 		}
-		this->SetDirty();
 	}
 
 	virtual void OnTick()
 	{
 		if (_pause_game != 0) return;
-		if (--this->resort_timer == 0) {
+		if (this->stations.NeedResort()) {
 			DEBUG(misc, 3, "Periodic rebuild station list player %d", this->window_number);
-			this->resort_timer = DAY_TICKS * PERIODIC_RESORT_DAYS;
-			this->flags |= VL_REBUILD;
 			this->SetDirty();
 		}
 	}
@@ -577,13 +529,37 @@
 
 	virtual void OnInvalidateData(int data)
 	{
-		this->flags |= (data == 0 ? VL_REBUILD : VL_RESORT);
+		if (data == 0) {
+			this->stations.ForceRebuild();
+		} else {
+			this->stations.ForceResort();
+		}
 	}
 };
 
-Listing PlayerStationsWindow::station_sort = {0, 0};
+Listing PlayerStationsWindow::last_sorting = {false, 0};
 byte PlayerStationsWindow::facilities = FACIL_TRAIN | FACIL_TRUCK_STOP | FACIL_BUS_STOP | FACIL_AIRPORT | FACIL_DOCK;
 bool PlayerStationsWindow::include_empty = true;
+const uint32 PlayerStationsWindow::cargo_filter_max = UINT32_MAX;
+uint32 PlayerStationsWindow::cargo_filter = UINT32_MAX;
+const Station *PlayerStationsWindow::last_station = NULL;
+
+/* Availible station sorting functions */
+GUIStationList::SortFunction *const PlayerStationsWindow::sorter_funcs[] = {
+	&StationNameSorter,
+	&StationTypeSorter,
+	&StationWaitingSorter,
+	&StationRatingMaxSorter
+};
+
+/* Names of the sorting functions */
+const StringID PlayerStationsWindow::sorter_names[] = {
+	STR_SORT_BY_DROPDOWN_NAME,
+	STR_SORT_BY_FACILITY,
+	STR_SORT_BY_WAITING,
+	STR_SORT_BY_RATING_MAX,
+	INVALID_STRING_ID
+};
 
 
 static const Widget _player_stations_widgets[] = {
@@ -745,7 +721,7 @@
 				cargolist.push_back(CargoData(i, INVALID_STATION, st->goods[i].cargo.Count()));
 
 				/* Set the row for this cargo entry for the expand/hide button */
-				this->cargo_rows[i] = cargolist.size();
+				this->cargo_rows[i] = (uint16)cargolist.size();
 
 				/* Add an entry for each distinct cargo source. */
 				const CargoList::List *packets = st->goods[i].cargo.Packets();
@@ -775,7 +751,7 @@
 				}
 			}
 		}
-		SetVScrollCount(this, cargolist.size() + 1); // update scrollbar
+		SetVScrollCount(this, (int)cargolist.size() + 1); // update scrollbar
 
 		/* disable some buttons */
 		this->SetWidgetDisabledState(SVW_RENAME,   st->owner != _local_player);
--- a/src/station_type.h	Thu May 29 12:52:24 2008 +0000
+++ b/src/station_type.h	Thu May 29 15:56:32 2008 +0000
@@ -57,7 +57,7 @@
 	CA_TRAIN           =  4,
 	CA_DOCK            =  5,
 
-	CA_UNMODIFIED      =  4, ///< Used when _settings.station.modified_catchment is false
+	CA_UNMODIFIED      =  4, ///< Used when _settings_game.station.modified_catchment is false
 
 	MAX_CATCHMENT      = 10, ///< Airports have a catchment up to this number.
 };
--- a/src/statusbar_gui.cpp	Thu May 29 12:52:24 2008 +0000
+++ b/src/statusbar_gui.cpp	Thu May 29 15:56:32 2008 +0000
@@ -82,7 +82,7 @@
 
 		this->DrawWidgets();
 		SetDParam(0, _date);
-		DrawStringCentered(70, 1, (_pause_game || _settings.gui.status_long_date) ? STR_00AF : STR_00AE, TC_FROMSTRING);
+		DrawStringCentered(70, 1, (_pause_game || _settings_client.gui.status_long_date) ? STR_00AF : STR_00AE, TC_FROMSTRING);
 
 		if (p != NULL) {
 			/* Draw player money */
--- a/src/stdafx.h	Thu May 29 12:52:24 2008 +0000
+++ b/src/stdafx.h	Thu May 29 15:56:32 2008 +0000
@@ -201,6 +201,11 @@
 		typedef _W64 unsigned int UINT_PTR, *PUINT_PTR;
 	#endif /* WIN32 && !_WIN64 && !WIN64 */
 
+	#if defined(_WIN64) || defined(WIN64)
+		#define fseek _fseeki64
+	#endif /* _WIN64 || WIN64 */
+
+
 	#define GCC_PACK
 
 	/* This is needed to zlib uses the stdcall calling convention on visual studio */
--- a/src/string_func.h	Thu May 29 12:52:24 2008 +0000
+++ b/src/string_func.h	Thu May 29 15:56:32 2008 +0000
@@ -81,7 +81,7 @@
  * @param c Unicode character.
  * @return Length of UTF-8 encoding for character.
  */
-static inline size_t Utf8CharLen(WChar c)
+static inline int8 Utf8CharLen(WChar c)
 {
 	if (c < 0x80)       return 1;
 	if (c < 0x800)      return 2;
@@ -100,7 +100,7 @@
  * @param c char to query length of
  * @return requested size
  */
-static inline size_t Utf8EncodedCharLen(char c)
+static inline int8 Utf8EncodedCharLen(char c)
 {
 	if (GB(c, 3, 5) == 0x1E) return 4;
 	if (GB(c, 4, 4) == 0x0E) return 3;
--- a/src/strings.cpp	Thu May 29 12:52:24 2008 +0000
+++ b/src/strings.cpp	Thu May 29 15:56:32 2008 +0000
@@ -546,7 +546,7 @@
  */
 uint ConvertSpeedToDisplaySpeed(uint speed)
 {
- return (speed * units[_settings.gui.units].s_m) >> units[_settings.gui.units].s_s;
+ return (speed * units[_settings_client.gui.units].s_m) >> units[_settings_client.gui.units].s_s;
 }
 
 /**
@@ -556,7 +556,7 @@
  */
 uint ConvertDisplaySpeedToSpeed(uint speed)
 {
-	return ((speed << units[_settings.gui.units].s_s) + units[_settings.gui.units].s_m / 2) / units[_settings.gui.units].s_m;
+	return ((speed << units[_settings_client.gui.units].s_s) + units[_settings_client.gui.units].s_m / 2) / units[_settings_client.gui.units].s_m;
 }
 
 static char* FormatString(char* buff, const char* str, const int64* argv, uint casei, const char* last)
@@ -602,9 +602,9 @@
 
 			case SCC_VELOCITY: {// {VELOCITY}
 				int64 args[1];
-				assert(_settings.gui.units < lengthof(units));
+				assert(_settings_client.gui.units < lengthof(units));
 				args[0] = ConvertSpeedToDisplaySpeed(GetInt32(&argv));
-				buff = FormatString(buff, GetStringPtr(units[_settings.gui.units].velocity), args, modifier >> 24, last);
+				buff = FormatString(buff, GetStringPtr(units[_settings_client.gui.units].velocity), args, modifier >> 24, last);
 				modifier = 0;
 				break;
 			}
@@ -625,18 +625,18 @@
 				switch (cargo_str) {
 					case STR_TONS: {
 						int64 args[1];
-						assert(_settings.gui.units < lengthof(units));
-						args[0] = GetInt32(&argv) * units[_settings.gui.units].w_m >> units[_settings.gui.units].w_s;
-						buff = FormatString(buff, GetStringPtr(units[_settings.gui.units].l_weight), args, modifier >> 24, last);
+						assert(_settings_client.gui.units < lengthof(units));
+						args[0] = GetInt32(&argv) * units[_settings_client.gui.units].w_m >> units[_settings_client.gui.units].w_s;
+						buff = FormatString(buff, GetStringPtr(units[_settings_client.gui.units].l_weight), args, modifier >> 24, last);
 						modifier = 0;
 						break;
 					}
 
 					case STR_LITERS: {
 						int64 args[1];
-						assert(_settings.gui.units < lengthof(units));
-						args[0] = GetInt32(&argv) * units[_settings.gui.units].v_m >> units[_settings.gui.units].v_s;
-						buff = FormatString(buff, GetStringPtr(units[_settings.gui.units].l_volume), args, modifier >> 24, last);
+						assert(_settings_client.gui.units < lengthof(units));
+						args[0] = GetInt32(&argv) * units[_settings_client.gui.units].v_m >> units[_settings_client.gui.units].v_s;
+						buff = FormatString(buff, GetStringPtr(units[_settings_client.gui.units].l_volume), args, modifier >> 24, last);
 						modifier = 0;
 						break;
 					}
@@ -718,9 +718,9 @@
 
 			case SCC_VOLUME: { // {VOLUME}
 				int64 args[1];
-				assert(_settings.gui.units < lengthof(units));
-				args[0] = GetInt32(&argv) * units[_settings.gui.units].v_m >> units[_settings.gui.units].v_s;
-				buff = FormatString(buff, GetStringPtr(units[_settings.gui.units].l_volume), args, modifier >> 24, last);
+				assert(_settings_client.gui.units < lengthof(units));
+				args[0] = GetInt32(&argv) * units[_settings_client.gui.units].v_m >> units[_settings_client.gui.units].v_s;
+				buff = FormatString(buff, GetStringPtr(units[_settings_client.gui.units].l_volume), args, modifier >> 24, last);
 				modifier = 0;
 				break;
 			}
@@ -763,45 +763,45 @@
 
 			case SCC_POWER: { // {POWER}
 				int64 args[1];
-				assert(_settings.gui.units < lengthof(units));
-				args[0] = GetInt32(&argv) * units[_settings.gui.units].p_m >> units[_settings.gui.units].p_s;
-				buff = FormatString(buff, GetStringPtr(units[_settings.gui.units].power), args, modifier >> 24, last);
+				assert(_settings_client.gui.units < lengthof(units));
+				args[0] = GetInt32(&argv) * units[_settings_client.gui.units].p_m >> units[_settings_client.gui.units].p_s;
+				buff = FormatString(buff, GetStringPtr(units[_settings_client.gui.units].power), args, modifier >> 24, last);
 				modifier = 0;
 				break;
 			}
 
 			case SCC_VOLUME_SHORT: { // {VOLUME_S}
 				int64 args[1];
-				assert(_settings.gui.units < lengthof(units));
-				args[0] = GetInt32(&argv) * units[_settings.gui.units].v_m >> units[_settings.gui.units].v_s;
-				buff = FormatString(buff, GetStringPtr(units[_settings.gui.units].s_volume), args, modifier >> 24, last);
+				assert(_settings_client.gui.units < lengthof(units));
+				args[0] = GetInt32(&argv) * units[_settings_client.gui.units].v_m >> units[_settings_client.gui.units].v_s;
+				buff = FormatString(buff, GetStringPtr(units[_settings_client.gui.units].s_volume), args, modifier >> 24, last);
 				modifier = 0;
 				break;
 			}
 
 			case SCC_WEIGHT: { // {WEIGHT}
 				int64 args[1];
-				assert(_settings.gui.units < lengthof(units));
-				args[0] = GetInt32(&argv) * units[_settings.gui.units].w_m >> units[_settings.gui.units].w_s;
-				buff = FormatString(buff, GetStringPtr(units[_settings.gui.units].l_weight), args, modifier >> 24, last);
+				assert(_settings_client.gui.units < lengthof(units));
+				args[0] = GetInt32(&argv) * units[_settings_client.gui.units].w_m >> units[_settings_client.gui.units].w_s;
+				buff = FormatString(buff, GetStringPtr(units[_settings_client.gui.units].l_weight), args, modifier >> 24, last);
 				modifier = 0;
 				break;
 			}
 
 			case SCC_WEIGHT_SHORT: { // {WEIGHT_S}
 				int64 args[1];
-				assert(_settings.gui.units < lengthof(units));
-				args[0] = GetInt32(&argv) * units[_settings.gui.units].w_m >> units[_settings.gui.units].w_s;
-				buff = FormatString(buff, GetStringPtr(units[_settings.gui.units].s_weight), args, modifier >> 24, last);
+				assert(_settings_client.gui.units < lengthof(units));
+				args[0] = GetInt32(&argv) * units[_settings_client.gui.units].w_m >> units[_settings_client.gui.units].w_s;
+				buff = FormatString(buff, GetStringPtr(units[_settings_client.gui.units].s_weight), args, modifier >> 24, last);
 				modifier = 0;
 				break;
 			}
 
 			case SCC_FORCE: { // {FORCE}
 				int64 args[1];
-				assert(_settings.gui.units < lengthof(units));
-				args[0] = GetInt32(&argv) * units[_settings.gui.units].f_m >> units[_settings.gui.units].f_s;
-				buff = FormatString(buff, GetStringPtr(units[_settings.gui.units].force), args, modifier >> 24, last);
+				assert(_settings_client.gui.units < lengthof(units));
+				args[0] = GetInt32(&argv) * units[_settings_client.gui.units].f_m >> units[_settings_client.gui.units].f_s;
+				buff = FormatString(buff, GetStringPtr(units[_settings_client.gui.units].force), args, modifier >> 24, last);
 				modifier = 0;
 				break;
 			}
@@ -1137,7 +1137,7 @@
 	const char* const* base;
 	uint num;
 
-	if (_settings.game_creation.landscape == LT_TOYLAND) {
+	if (_settings_game.game_creation.landscape == LT_TOYLAND) {
 		base = _silly_surname_list;
 		num  = lengthof(_silly_surname_list);
 	} else {
@@ -1167,7 +1167,7 @@
 		buff = strecpy(buff, initial, last);
 	}
 
-	if (_settings.game_creation.landscape == LT_TOYLAND) {
+	if (_settings_game.game_creation.landscape == LT_TOYLAND) {
 		base = _silly_surname_list;
 		num  = lengthof(_silly_surname_list);
 	} else {
--- a/src/terraform_gui.cpp	Thu May 29 12:52:24 2008 +0000
+++ b/src/terraform_gui.cpp	Thu May 29 15:56:32 2008 +0000
@@ -550,7 +550,7 @@
 
 static void EditorTerraformClick_DesertLightHouse(Window *w)
 {
-	HandlePlacePushButton(w, ETTW_PLACE_DESERT_LIGHTHOUSE, SPR_CURSOR_LIGHTHOUSE, VHM_RECT, (_settings.game_creation.landscape == LT_TROPIC) ? PlaceProc_DesertArea : PlaceProc_LightHouse);
+	HandlePlacePushButton(w, ETTW_PLACE_DESERT_LIGHTHOUSE, SPR_CURSOR_LIGHTHOUSE, VHM_RECT, (_settings_game.game_creation.landscape == LT_TROPIC) ? PlaceProc_DesertArea : PlaceProc_LightHouse);
 }
 
 static void EditorTerraformClick_Transmitter(Window *w)
@@ -615,7 +615,7 @@
 struct ScenarioEditorLandscapeGenerationWindow : Window {
 	ScenarioEditorLandscapeGenerationWindow(const WindowDesc *desc, WindowNumber window_number) : Window(desc, window_number)
 	{
-		this->widget[ETTW_PLACE_DESERT_LIGHTHOUSE].tooltips = (_settings.game_creation.landscape == LT_TROPIC) ? STR_028F_DEFINE_DESERT_AREA : STR_028D_PLACE_LIGHTHOUSE;
+		this->widget[ETTW_PLACE_DESERT_LIGHTHOUSE].tooltips = (_settings_game.game_creation.landscape == LT_TROPIC) ? STR_028F_DEFINE_DESERT_AREA : STR_028D_PLACE_LIGHTHOUSE;
 		this->FindWindowPlacementAndResize(desc);
 	}
 
--- a/src/texteff.cpp	Thu May 29 12:52:24 2008 +0000
+++ b/src/texteff.cpp	Thu May 29 15:56:32 2008 +0000
@@ -392,7 +392,7 @@
 						dpi->top  <= te->bottom &&
 						dpi->left + dpi->width  > te->x &&
 						dpi->top  + dpi->height > te->y) {
-					if (te->mode == TE_RISING || (_settings.gui.loading_indicators && !IsTransparencySet(TO_LOADING))) {
+					if (te->mode == TE_RISING || (_settings_client.gui.loading_indicators && !IsTransparencySet(TO_LOADING))) {
 						AddStringToDraw(te->x, te->y, te->string_id, te->params_1, te->params_2);
 					}
 				}
@@ -407,7 +407,7 @@
 						dpi->top  <= te->bottom * 2 - te->y &&
 						dpi->left + dpi->width  > te->x &&
 						dpi->top  + dpi->height > te->y) {
-					if (te->mode == TE_RISING || (_settings.gui.loading_indicators && !IsTransparencySet(TO_LOADING))) {
+					if (te->mode == TE_RISING || (_settings_client.gui.loading_indicators && !IsTransparencySet(TO_LOADING))) {
 						AddStringToDraw(te->x, te->y, (StringID)(te->string_id - 1), te->params_1, te->params_2);
 					}
 				}
--- a/src/tgp.cpp	Thu May 29 12:52:24 2008 +0000
+++ b/src/tgp.cpp	Thu May 29 15:56:32 2008 +0000
@@ -211,10 +211,10 @@
 	{1500, 1000, 1200, 1000,  500,   32,    20,    0,    0,    0,    0,    0},
 };
 
-/** Desired water percentage (100% == 1024) - indexed by _settings.difficulty.quantity_sea_lakes */
+/** Desired water percentage (100% == 1024) - indexed by _settings_game.difficulty.quantity_sea_lakes */
 static const amplitude_t _water_percent[4] = {20, 80, 250, 400};
 
-/** Desired maximum height - indexed by _settings.difficulty.terrain_type */
+/** Desired maximum height - indexed by _settings_game.difficulty.terrain_type */
 static const int8 _max_height[4] = {
 	6,       ///< Very flat
 	9,       ///< Flat
@@ -342,7 +342,7 @@
 	do {
 		log_frequency = iteration_round - log_frequency_min;
 		if (log_frequency >= 0) {
-			amplitude = _amplitudes_by_smoothness_and_frequency[_settings.game_creation.tgen_smoothness][log_frequency];
+			amplitude = _amplitudes_by_smoothness_and_frequency[_settings_game.game_creation.tgen_smoothness][log_frequency];
 		} else {
 			amplitude = 0;
 		}
@@ -402,7 +402,7 @@
 		/* Transform height into 0..1 space */
 		fheight = (double)(*h - h_min) / (double)(h_max - h_min);
 		/* Apply sine transform depending on landscape type */
-		switch(_settings.game_creation.landscape) {
+		switch(_settings_game.game_creation.landscape) {
 			case LT_TOYLAND:
 			case LT_TEMPERATE:
 				/* Move and scale 0..1 into -1..+1 */
@@ -531,7 +531,7 @@
  */
 static void HeightMapCoastLines()
 {
-	int smallest_size = min(_settings.game_creation.map_x, _settings.game_creation.map_y);
+	int smallest_size = min(_settings_game.game_creation.map_x, _settings_game.game_creation.map_y);
 	const int margin = 4;
 	uint y, x;
 	double max_x;
@@ -661,9 +661,9 @@
  *  - height histogram redistribution by sine wave transform */
 static void HeightMapNormalize()
 {
-	const amplitude_t water_percent = _water_percent[_settings.difficulty.quantity_sea_lakes];
-	const height_t h_max_new = I2H(_max_height[_settings.difficulty.terrain_type]);
-	const height_t roughness = 7 + 3 * _settings.game_creation.tgen_smoothness;
+	const amplitude_t water_percent = _water_percent[_settings_game.difficulty.quantity_sea_lakes];
+	const height_t h_max_new = I2H(_max_height[_settings_game.difficulty.terrain_type]);
+	const height_t roughness = 7 + 3 * _settings_game.game_creation.tgen_smoothness;
 
 	HeightMapAdjustWaterLevel(water_percent, h_max_new);
 
@@ -692,7 +692,7 @@
  */
 static double int_noise(const long x, const long y, const int prime)
 {
-	long n = x + y * prime + _settings.game_creation.generation_seed;
+	long n = x + y * prime + _settings_game.game_creation.generation_seed;
 
 	n = (n << 13) ^ n;
 
--- a/src/timetable_cmd.cpp	Thu May 29 12:52:24 2008 +0000
+++ b/src/timetable_cmd.cpp	Thu May 29 15:56:32 2008 +0000
@@ -54,7 +54,7 @@
  */
 CommandCost CmdChangeTimetable(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
 {
-	if (!_settings.order.timetabling) return CMD_ERROR;
+	if (!_settings_game.order.timetabling) return CMD_ERROR;
 
 	VehicleID veh = GB(p1, 0, 16);
 	if (!IsValidVehicleID(veh)) return CMD_ERROR;
@@ -90,7 +90,7 @@
  */
 CommandCost CmdSetVehicleOnTime(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
 {
-	if (!_settings.order.timetabling) return CMD_ERROR;
+	if (!_settings_game.order.timetabling) return CMD_ERROR;
 
 	VehicleID veh = GB(p1, 0, 16);
 	if (!IsValidVehicleID(veh)) return CMD_ERROR;
@@ -116,7 +116,7 @@
  */
 CommandCost CmdAutofillTimetable(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
 {
-	if (!_settings.order.timetabling) return CMD_ERROR;
+	if (!_settings_game.order.timetabling) return CMD_ERROR;
 
 	VehicleID veh = GB(p1, 0, 16);
 	if (!IsValidVehicleID(veh)) return CMD_ERROR;
@@ -157,7 +157,7 @@
 
 	v->current_order_time = 0;
 
-	if (!_settings.order.timetabling) return;
+	if (!_settings_game.order.timetabling) return;
 
 	/* Make sure the timetable only starts when the vehicle reaches the first
 	 * order, not when travelling from the depot to the first station. */
--- a/src/timetable_gui.cpp	Thu May 29 12:52:24 2008 +0000
+++ b/src/timetable_gui.cpp	Thu May 29 15:56:32 2008 +0000
@@ -38,7 +38,7 @@
 
 void SetTimetableParams(int param1, int param2, uint32 time)
 {
-	if (_settings.gui.timetable_in_ticks) {
+	if (_settings_client.gui.timetable_in_ticks) {
 		SetDParam(param1, STR_TIMETABLE_TICKS);
 		SetDParam(param2, time);
 	} else {
@@ -172,7 +172,7 @@
 		}
 		y += 10;
 
-		if (v->lateness_counter == 0 || (!_settings.gui.timetable_in_ticks && v->lateness_counter / DAY_TICKS == 0)) {
+		if (v->lateness_counter == 0 || (!_settings_client.gui.timetable_in_ticks && v->lateness_counter / DAY_TICKS == 0)) {
 			DrawString(2, y, STR_TIMETABLE_STATUS_ON_TIME, TC_BLACK);
 		} else {
 			SetTimetableParams(0, 1, abs(v->lateness_counter));
@@ -222,7 +222,7 @@
 
 				if (order != NULL) {
 					uint time = (selected % 2 == 1) ? order->travel_time : order->wait_time;
-					if (!_settings.gui.timetable_in_ticks) time /= DAY_TICKS;
+					if (!_settings_client.gui.timetable_in_ticks) time /= DAY_TICKS;
 
 					if (time != 0) {
 						SetDParam(0, time);
@@ -259,7 +259,7 @@
 		uint32 p1 = PackTimetableArgs(v, this->sel_index);
 
 		uint64 time = StrEmpty(str) ? 0 : strtoul(str, NULL, 10);
-		if (!_settings.gui.timetable_in_ticks) time *= DAY_TICKS;
+		if (!_settings_client.gui.timetable_in_ticks) time *= DAY_TICKS;
 
 		uint32 p2 = minu(time, MAX_UVALUE(uint16));
 
--- a/src/town.h	Thu May 29 12:52:24 2008 +0000
+++ b/src/town.h	Thu May 29 15:56:32 2008 +0000
@@ -197,7 +197,7 @@
 	inline uint16 MaxTownNoise() const {
 		if (this->population == 0) return 0; // no population? no noise
 
-		return ((this->population / _settings.economy.town_noise_population[_settings.difficulty.town_council_tolerance]) + 3);
+		return ((this->population / _settings_game.economy.town_noise_population[_settings_game.difficulty.town_council_tolerance]) + 3);
 	}
 };
 
@@ -207,7 +207,7 @@
  */
 inline TownLayout Town::GetActiveLayout() const
 {
-	return (_settings.economy.town_layout == TL_RANDOM) ? this->layout : _settings.economy.town_layout;
+	return (_settings_game.economy.town_layout == TL_RANDOM) ? this->layout : _settings_game.economy.town_layout;
 }
 
 struct HouseSpec {
@@ -345,10 +345,6 @@
 #define FOR_ALL_TOWNS_FROM(t, start) for (t = GetTown(start); t != NULL; t = (t->index + 1U < GetTownPoolSize()) ? GetTown(t->index + 1U) : NULL) if (t->IsValid())
 #define FOR_ALL_TOWNS(t) FOR_ALL_TOWNS_FROM(t, 0)
 
-extern bool _town_sort_dirty;
-extern byte _town_sort_order;
-extern const Town **_town_sort;
-
 extern Town *_cleared_town;
 extern int _cleared_town_rating;
 
--- a/src/town_cmd.cpp	Thu May 29 12:52:24 2008 +0000
+++ b/src/town_cmd.cpp	Thu May 29 15:56:32 2008 +0000
@@ -55,10 +55,6 @@
 uint _total_towns;
 HouseSpec _house_specs[HOUSE_MAX];
 
-bool _town_sort_dirty;
-byte _town_sort_order;
-const Town **_town_sort;
-
 Town *_cleared_town;
 int _cleared_town_rating;
 
@@ -82,7 +78,7 @@
 	/* Delete town authority window
 	 * and remove from list of sorted towns */
 	DeleteWindowById(WC_TOWN_VIEW, this->index);
-	_town_sort_dirty = true;
+	InvalidateWindowData(WC_TOWN_DIRECTORY, 0, 0);
 	_total_towns--;
 
 	/* Delete all industries belonging to the town */
@@ -324,7 +320,7 @@
 	SetDParam(0, t->index);
 	SetDParam(1, t->population);
 	UpdateViewportSignPos(&t->sign, pt.x, pt.y - 24,
-		_settings.gui.population_in_label ? STR_TOWN_LABEL_POP : STR_TOWN_LABEL);
+		_settings_client.gui.population_in_label ? STR_TOWN_LABEL_POP : STR_TOWN_LABEL);
 	MarkTownSignDirty(t);
 }
 
@@ -348,7 +344,7 @@
 	InvalidateWindow(WC_TOWN_VIEW, t->index);
 	UpdateTownVirtCoord(t);
 
-	if (_town_sort_order & 2) _town_sort_dirty = true;
+	InvalidateWindowData(WC_TOWN_DIRECTORY, 0, 1);
 }
 
 /**
@@ -596,7 +592,7 @@
 		if (callback != CALLBACK_FAILED) {
 			if (accepts[0] != CT_INVALID) ac[accepts[0]] = GB(callback, 0, 4);
 			if (accepts[1] != CT_INVALID) ac[accepts[1]] = GB(callback, 4, 4);
-			if (_settings.game_creation.landscape != LT_TEMPERATE && HasBit(callback, 12)) {
+			if (_settings_game.game_creation.landscape != LT_TEMPERATE && HasBit(callback, 12)) {
 				/* The 'S' bit indicates food instead of goods */
 				ac[CT_FOOD] = GB(callback, 8, 4);
 			} else {
@@ -1255,7 +1251,7 @@
 	/* Let the town be a ghost town
 	 * The player wanted it in such a way. Thus there he has it. ;)
 	 * Never reached in editor mode. */
-	if (_settings.economy.town_layout == TL_NO_ROADS && _generating_world) {
+	if (_settings_game.economy.town_layout == TL_NO_ROADS && _generating_world) {
 		return false;
 	}
 
@@ -1367,9 +1363,9 @@
 	 * the other towns may take considerable amount of time (10000 is
 	 * too much). */
 	int tries = 1000;
-	bool grf = (_settings.game_creation.town_name >= _nb_orig_names);
-	uint32 grfid = grf ? GetGRFTownNameId(_settings.game_creation.town_name - _nb_orig_names) : 0;
-	uint16 townnametype = grf ? GetGRFTownNameType(_settings.game_creation.town_name - _nb_orig_names) : SPECSTR_TOWNNAME_START + _settings.game_creation.town_name;
+	bool grf = (_settings_game.game_creation.town_name >= _nb_orig_names);
+	uint32 grfid = grf ? GetGRFTownNameId(_settings_game.game_creation.town_name - _nb_orig_names) : 0;
+	uint16 townnametype = grf ? GetGRFTownNameType(_settings_game.game_creation.town_name - _nb_orig_names) : SPECSTR_TOWNNAME_START + _settings_game.game_creation.town_name;
 
 	assert(townnameparts != NULL);
 
@@ -1453,19 +1449,19 @@
 	t->exclusive_counter = 0;
 	t->statues = 0;
 
-	if (_settings.game_creation.town_name < _nb_orig_names) {
+	if (_settings_game.game_creation.town_name < _nb_orig_names) {
 		/* Original town name */
 		t->townnamegrfid = 0;
-		t->townnametype = SPECSTR_TOWNNAME_START + _settings.game_creation.town_name;
+		t->townnametype = SPECSTR_TOWNNAME_START + _settings_game.game_creation.town_name;
 	} else {
 		/* Newgrf town name */
-		t->townnamegrfid = GetGRFTownNameId(_settings.game_creation.town_name  - _nb_orig_names);
-		t->townnametype  = GetGRFTownNameType(_settings.game_creation.town_name - _nb_orig_names);
+		t->townnamegrfid = GetGRFTownNameId(_settings_game.game_creation.town_name  - _nb_orig_names);
+		t->townnametype  = GetGRFTownNameType(_settings_game.game_creation.town_name - _nb_orig_names);
 	}
 	t->townnameparts = townnameparts;
 
 	UpdateTownVirtCoord(t);
-	_town_sort_dirty = true;
+	InvalidateWindowData(WC_TOWN_DIRECTORY, 0, 0);
 
 	t->InitializeLayout();
 
@@ -1485,7 +1481,7 @@
 			break;
 
 		case TSM_CITY:
-			x *= _settings.economy.initial_city_size;
+			x *= _settings_game.economy.initial_city_size;
 			t->larger_town = true;
 			break;
 	}
@@ -1585,8 +1581,8 @@
 bool GenerateTowns()
 {
 	uint num = 0;
-	uint n = ScaleByMapSize(_num_initial_towns[_settings.difficulty.number_towns] + (Random() & 7));
-	uint num_cities = _settings.economy.larger_towns == 0 ? 0 : n / _settings.economy.larger_towns;
+	uint n = ScaleByMapSize(_num_initial_towns[_settings_game.difficulty.number_towns] + (Random() & 7));
+	uint num_cities = _settings_game.economy.larger_towns == 0 ? 0 : n / _settings_game.economy.larger_towns;
 
 	SetGeneratingWorldProgress(GWP_TOWN, n);
 
@@ -1594,7 +1590,7 @@
 		IncreaseGeneratingWorldProgress(GWP_TOWN);
 		/* try 20 times to create a random-sized town for the first loop. */
 		TownSizeMode mode = num_cities > 0 ? TSM_CITY : TSM_RANDOM;
-		if (CreateRandomTown(20, mode, _settings.economy.initial_city_size) != NULL) num++;
+		if (CreateRandomTown(20, mode, _settings_game.economy.initial_city_size) != NULL) num++;
 		if (num_cities > 0) num_cities--;
 	} while (--n);
 
@@ -1879,8 +1875,8 @@
 	HouseZonesBits rad = GetTownRadiusGroup(t, tile);
 
 	/* Above snow? */
-	int land = _settings.game_creation.landscape;
-	if (land == LT_ARCTIC && z >= _settings.game_creation.snow_line) land = -1;
+	int land = _settings_game.game_creation.landscape;
+	if (land == LT_ARCTIC && z >= _settings_game.game_creation.snow_line) land = -1;
 
 	uint bitmask = (1 << rad) + (1 << (land + 12));
 
@@ -2099,7 +2095,7 @@
 		t->name = strdup(_cmd_text);
 
 		UpdateTownVirtCoord(t);
-		_town_sort_dirty = true;
+		InvalidateWindowData(WC_TOWN_DIRECTORY, 0, 1);
 		UpdateAllStationVirtCoord();
 		UpdateAllWaypointSigns();
 		MarkWholeScreenDirty();
@@ -2219,7 +2215,7 @@
 static void TownActionBuyRights(Town *t)
 {
 	/* Check if it's allowed to by the rights */
-	if (!_settings.economy.exclusive_rights) return;
+	if (!_settings_game.economy.exclusive_rights) return;
 
 	t->exclusive_counter = 12;
 	t->exclusivity = _current_player;
@@ -2333,7 +2329,7 @@
 	}
 
 	ClrBit(t->flags12, TOWN_IS_FUNDED);
-	if (_settings.economy.town_growth_rate == 0 && t->fund_buildings_months == 0) return;
+	if (_settings_game.economy.town_growth_rate == 0 && t->fund_buildings_months == 0) return;
 
 	/** Towns are processed every TOWN_GROWTH_FREQUENCY ticks, and this is the
 	 * number of times towns are processed before a new building is built. */
@@ -2352,17 +2348,17 @@
 		if (n == 0 && !Chance16(1, 12)) return;
 	}
 
-	if (_settings.game_creation.landscape == LT_ARCTIC) {
+	if (_settings_game.game_creation.landscape == LT_ARCTIC) {
 		if (TilePixelHeight(t->xy) >= GetSnowLine() && t->act_food == 0 && t->population > 90)
 			return;
-	} else if (_settings.game_creation.landscape == LT_TROPIC) {
+	} else if (_settings_game.game_creation.landscape == LT_TROPIC) {
 		if (GetTropicZone(t->xy) == TROPICZONE_DESERT && (t->act_food == 0 || t->act_water == 0) && t->population > 60)
 			return;
 	}
 
 	/* Use the normal growth rate values if new buildings have been funded in
 	 * this town and the growth rate is set to none. */
-	uint growth_multiplier = _settings.economy.town_growth_rate != 0 ? _settings.economy.town_growth_rate - 1 : 1;
+	uint growth_multiplier = _settings_game.economy.town_growth_rate != 0 ? _settings_game.economy.town_growth_rate - 1 : 1;
 
 	m >>= growth_multiplier;
 	if (t->larger_town) m /= 2;
@@ -2405,7 +2401,7 @@
 {
 	if (!IsValidPlayer(_current_player)) return true;
 
-	Town *t = ClosestTownFromTile(tile, _settings.economy.dist_local_authority);
+	Town *t = ClosestTownFromTile(tile, _settings_game.economy.dist_local_authority);
 	if (t == NULL) return true;
 
 	if (t->ratings[_current_player] > RATING_VERYPOOR) return true;
@@ -2524,7 +2520,7 @@
 	 * owned by a town no removal if rating is lower than ... depends now on
 	 * difficulty setting. Minimum town rating selected by difficulty level
 	 */
-	int modemod = _default_rating_settings[_settings.difficulty.town_council_tolerance][type];
+	int modemod = _default_rating_settings[_settings_game.difficulty.town_council_tolerance][type];
 
 	if (GetRating(t) < 16 + modemod && !(flags & DC_NO_TOWN_RATING)) {
 		SetDParam(0, t->index);
@@ -2565,7 +2561,6 @@
 	_cur_town_ctr = 0;
 	_cur_town_iter = 0;
 	_total_towns = 0;
-	_town_sort_dirty = true;
 }
 
 static CommandCost TerraformTile_Town(TileIndex tile, uint32 flags, uint z_new, Slope tileh_new)
@@ -2736,8 +2731,6 @@
 
 void AfterLoadTown()
 {
-	_town_sort_dirty = true;
-
 	Town *t;
 	FOR_ALL_TOWNS(t) t->InitializeLayout();
 }
--- a/src/town_gui.cpp	Thu May 29 12:52:24 2008 +0000
+++ b/src/town_gui.cpp	Thu May 29 15:56:32 2008 +0000
@@ -24,10 +24,13 @@
 #include "settings_type.h"
 #include "tilehighlight_func.h"
 #include "string_func.h"
+#include "sortlist_type.h"
 
 #include "table/sprites.h"
 #include "table/strings.h"
 
+typedef GUIList<const Town*> GUITownList;
+
 extern bool GenerateTowns();
 static int _scengen_town_size = 1; // depress medium-sized towns per default
 
@@ -76,7 +79,7 @@
 	TownActions buttons = TACT_NONE;
 
 	/* Spectators and unwanted have no options */
-	if (pid != PLAYER_SPECTATOR && !(_settings.economy.bribe && t->unwanted[pid])) {
+	if (pid != PLAYER_SPECTATOR && !(_settings_game.economy.bribe && t->unwanted[pid])) {
 
 		/* Things worth more than this are not shown */
 		Money avail = GetPlayer(pid)->player_money + _price.station_value * 200;
@@ -88,11 +91,11 @@
 			const TownActions cur = (TownActions)(1 << i);
 
 			/* Is the player not able to bribe ? */
-			if (cur == TACT_BRIBE && (!_settings.economy.bribe || t->ratings[pid] >= RATING_BRIBE_MAXIMUM))
+			if (cur == TACT_BRIBE && (!_settings_game.economy.bribe || t->ratings[pid] >= RATING_BRIBE_MAXIMUM))
 				continue;
 
 			/* Is the player not able to buy exclusive rights ? */
-			if (cur == TACT_BUY_RIGHTS && !_settings.economy.exclusive_rights)
+			if (cur == TACT_BUY_RIGHTS && !_settings_game.economy.exclusive_rights)
 				continue;
 
 			/* Is the player not able to build a statue ? */
@@ -313,7 +316,7 @@
 		}
 
 		/* Space required for showing noise level information */
-		if (_settings.economy.station_noise_level) {
+		if (_settings_game.economy.station_noise_level) {
 			ResizeWindowForWidget(this, TVW_INFOPANEL, 0, 10);
 		}
 
@@ -343,7 +346,7 @@
 		this->DrawViewport();
 
 		/* only show the town noise, if the noise option is activated. */
-		if (_settings.economy.station_noise_level) {
+		if (_settings_game.economy.station_noise_level) {
 			SetDParam(0, this->town->noise_reached);
 			SetDParam(1, this->town->MaxTownNoise());
 			DrawString(2, 137, STR_NOISE_IN_TOWN, 0);
@@ -385,7 +388,7 @@
 		/* Called when setting station noise have changed, in order to resize the window */
 		this->SetDirty(); // refresh display for current size. This will allow to avoid glitches when downgrading
 
-		if (_settings.economy.station_noise_level) { // adjust depending
+		if (_settings_game.economy.station_noise_level) { // adjust depending
 			if (this->height == 150) { // window is smaller, needs to be bigger
 				ResizeWindowForWidget(this, TVW_INFOPANEL, 0, 10);
 			}
@@ -448,64 +451,6 @@
 };
 
 
-/* used to get a sorted list of the towns */
-static uint _num_town_sort;
-
-static char _bufcache[64];
-static const Town* _last_town;
-
-static int CDECL TownNameSorter(const void *a, const void *b)
-{
-	const Town* ta = *(const Town**)a;
-	const Town* tb = *(const Town**)b;
-	char buf1[64];
-	int r;
-
-	SetDParam(0, ta->index);
-	GetString(buf1, STR_TOWN, lastof(buf1));
-
-	/* If 'b' is the same town as in the last round, use the cached value
-	 *  We do this to speed stuff up ('b' is called with the same value a lot of
-	 *  times after eachother) */
-	if (tb != _last_town) {
-		_last_town = tb;
-		SetDParam(0, tb->index);
-		GetString(_bufcache, STR_TOWN, lastof(_bufcache));
-	}
-
-	r = strcmp(buf1, _bufcache);
-	if (_town_sort_order & 1) r = -r;
-	return r;
-}
-
-static int CDECL TownPopSorter(const void *a, const void *b)
-{
-	const Town* ta = *(const Town**)a;
-	const Town* tb = *(const Town**)b;
-	int r = ta->population - tb->population;
-	if (_town_sort_order & 1) r = -r;
-	return r;
-}
-
-static void MakeSortedTownList()
-{
-	const Town* t;
-	uint n = 0;
-
-	/* Create array for sorting */
-	_town_sort = ReallocT(_town_sort, GetMaxTownIndex() + 1);
-
-	FOR_ALL_TOWNS(t) _town_sort[n++] = t;
-
-	_num_town_sort = n;
-
-	_last_town = NULL; // used for "cache"
-	qsort((void*)_town_sort, n, sizeof(_town_sort[0]), _town_sort_order & 2 ? TownPopSorter : TownNameSorter);
-
-	DEBUG(misc, 3, "Resorting towns list");
-}
-
-
 struct TownDirectoryWindow : public Window {
 private:
 	enum TownDirectoryWidget {
@@ -514,6 +459,65 @@
 		TDW_CENTERTOWN,
 	};
 
+	/* Runtime saved values */
+	static Listing last_sorting;
+	static const Town *last_town;
+
+	/* Constants for sorting towns */
+	static GUITownList::SortFunction * const sorter_funcs[];
+
+	GUITownList towns;
+
+	void BuildTownList()
+	{
+		if (!this->towns.NeedRebuild()) return;
+
+		this->towns.Clear();
+
+		const Town *t;
+		FOR_ALL_TOWNS(t) {
+			*this->towns.Append() = t;
+		}
+
+		this->towns.Compact();
+		this->towns.RebuildDone();
+	}
+
+	void SortTownList()
+	{
+		last_town = NULL;
+		this->towns.Sort();
+	}
+
+	/** Sort by town name */
+	static int CDECL TownNameSorter(const Town * const *a, const Town * const *b)
+	{
+		static char buf_cache[64];
+		const Town *ta = *a;
+		const Town *tb = *b;
+		char buf[64];
+
+		SetDParam(0, ta->index);
+		GetString(buf, STR_TOWN, lastof(buf));
+
+		/* If 'b' is the same town as in the last round, use the cached value
+		 * We do this to speed stuff up ('b' is called with the same value a lot of
+		 * times after eachother) */
+		if (tb != last_town) {
+			last_town = tb;
+			SetDParam(0, tb->index);
+			GetString(buf_cache, STR_TOWN, lastof(buf_cache));
+		}
+
+		return strcmp(buf, buf_cache);
+	}
+
+	/** Sort by population */
+	static int CDECL TownPopulationSorter(const Town * const *a, const Town * const *b)
+	{
+		return (*a)->population - (*b)->population;
+	}
+
 public:
 	TownDirectoryWindow(const WindowDesc *desc) : Window(desc, 0)
 	{
@@ -521,28 +525,35 @@
 		this->resize.step_height = 10;
 		this->resize.height = this->height - 10 * 6; // minimum of 10 items in the list, each item 10 high
 
+		this->towns.SetListing(this->last_sorting);
+		this->towns.SetSortFuncs(this->sorter_funcs);
+		this->towns.ForceRebuild();
+
 		this->FindWindowPlacementAndResize(desc);
 	}
 
+	~TownDirectoryWindow()
+	{
+		this->last_sorting = this->towns.GetListing();
+	}
+
 	virtual void OnPaint()
 	{
-		if (_town_sort_dirty) {
-			_town_sort_dirty = false;
-			MakeSortedTownList();
-		}
+		this->BuildTownList();
+		this->SortTownList();
 
-		SetVScrollCount(this, _num_town_sort);
+		SetVScrollCount(this, this->towns.Length());
 
 		this->DrawWidgets();
-		this->DrawSortButtonState((_town_sort_order <= 1) ? TDW_SORTNAME : TDW_SORTPOPULATION, _town_sort_order & 1 ? SBS_DOWN : SBS_UP);
+		this->DrawSortButtonState(this->towns.sort_type == 0 ? TDW_SORTNAME : TDW_SORTPOPULATION, this->towns.IsDescSortOrder() ? SBS_DOWN : SBS_UP);
 
 		{
 			int n = 0;
 			uint16 i = this->vscroll.pos;
 			int y = 28;
 
-			while (i < _num_town_sort) {
-				const Town* t = _town_sort[i];
+			while (i < this->towns.Length()) {
+				const Town *t = this->towns[i];
 
 				assert(t->xy);
 
@@ -564,29 +575,33 @@
 	{
 		switch (widget) {
 			case TDW_SORTNAME: /* Sort by Name ascending/descending */
-				_town_sort_order = (_town_sort_order == 0) ? 1 : 0;
-				_town_sort_dirty = true;
+				if (this->towns.SortType() == 0) {
+					this->towns.ToggleSortOrder();
+				} else {
+					this->towns.SetSortType(0);
+				}
 				this->SetDirty();
 				break;
 
 			case TDW_SORTPOPULATION: /* Sort by Population ascending/descending */
-				_town_sort_order = (_town_sort_order == 2) ? 3 : 2;
-				_town_sort_dirty = true;
+				if (this->towns.SortType() == 1) {
+					this->towns.ToggleSortOrder();
+				} else {
+					this->towns.SetSortType(1);
+				}
 				this->SetDirty();
 				break;
 
 			case TDW_CENTERTOWN: { /* Click on Town Matrix */
-				const Town* t;
-
 				uint16 id_v = (pt.y - 28) / 10;
 
 				if (id_v >= this->vscroll.cap) return; // click out of bounds
 
 				id_v += this->vscroll.pos;
 
-				if (id_v >= _num_town_sort) return; // click out of town bounds
+				if (id_v >= this->towns.Length()) return; // click out of town bounds
 
-				t = _town_sort[id_v];
+				const Town *t = this->towns[id_v];
 				assert(t->xy);
 				if (_ctrl_pressed) {
 					ShowExtraViewPortWindow(t->xy);
@@ -607,6 +622,24 @@
 	{
 		this->vscroll.cap += delta.y / 10;
 	}
+
+	virtual void OnInvalidateData(int data)
+	{
+		if (data == 0) {
+			this->towns.ForceRebuild();
+		} else {
+			this->towns.ForceResort();
+		}
+	}
+};
+
+Listing TownDirectoryWindow::last_sorting = {false, 0};
+const Town *TownDirectoryWindow::last_town = NULL;
+
+/* Available town directory sorting functions */
+GUITownList::SortFunction * const TownDirectoryWindow::sorter_funcs[] = {
+	&TownNameSorter,
+	&TownPopulationSorter,
 };
 
 static const WindowDesc _town_directory_desc = {
--- a/src/train_cmd.cpp	Thu May 29 12:52:24 2008 +0000
+++ b/src/train_cmd.cpp	Thu May 29 15:56:32 2008 +0000
@@ -93,7 +93,7 @@
 byte FreightWagonMult(CargoID cargo)
 {
 	if (!GetCargo(cargo)->is_freight) return 1;
-	return _settings.vehicle.freight_trains;
+	return _settings_game.vehicle.freight_trains;
 }
 
 
@@ -279,7 +279,7 @@
 			}
 
 			/* max speed is the minimum of the speed limits of all vehicles in the consist */
-			if ((rvi_u->railveh_type != RAILVEH_WAGON || _settings.vehicle.wagon_speed_limits) && !UsesWagonOverride(u)) {
+			if ((rvi_u->railveh_type != RAILVEH_WAGON || _settings_game.vehicle.wagon_speed_limits) && !UsesWagonOverride(u)) {
 				uint16 speed = GetVehicleProperty(u, 0x09, rvi_u->max_speed);
 				if (speed != 0) max_speed = min(speed, max_speed);
 			}
@@ -727,7 +727,7 @@
 		Vehicle *v = vl[0];
 
 		UnitID unit_num = HasBit(p2, 0) ? 0 : GetFreeUnitNumber(VEH_TRAIN);
-		if (unit_num > _settings.vehicle.max_trains)
+		if (unit_num > _settings_game.vehicle.max_trains)
 			return_cmd_error(STR_00E1_TOO_MANY_VEHICLES_IN_GAME);
 
 		if (flags & DC_EXEC) {
@@ -766,7 +766,7 @@
 			v->u.rail.railtype = rvi->railtype;
 			_new_vehicle_id = v->index;
 
-			v->service_interval = _settings.vehicle.servint_trains;
+			v->service_interval = _settings_game.vehicle.servint_trains;
 			v->date_of_last_service = _date;
 			v->build_year = _cur_year;
 			v->cur_image = 0xAC2;
@@ -1002,7 +1002,7 @@
 	if (HasBit(p2, 0) && src_head == dst_head) return CommandCost();
 
 	{
-		int max_len = _settings.vehicle.mammoth_trains ? 100 : 10;
+		int max_len = _settings_game.vehicle.mammoth_trains ? 100 : 10;
 
 		/* check if all vehicles in the source train are stopped inside a depot. */
 		int src_len = CheckTrainStoppedInDepot(src_head);
@@ -1045,7 +1045,7 @@
 	/* moving a loco to a new line?, then we need to assign a unitnumber. */
 	if (dst == NULL && !IsFrontEngine(src) && IsTrainEngine(src)) {
 		UnitID unit_num = GetFreeUnitNumber(VEH_TRAIN);
-		if (unit_num > _settings.vehicle.max_trains)
+		if (unit_num > _settings_game.vehicle.max_trains)
 			return_cmd_error(STR_00E1_TOO_MANY_VEHICLES_IN_GAME);
 
 		if (flags & DC_EXEC) src->unitnumber = unit_num;
@@ -1545,7 +1545,7 @@
 	int old = v->u.rail.last_speed;
 	if (spd != old) {
 		v->u.rail.last_speed = spd;
-		if (_settings.gui.vehicle_speed || (old == 0) != (spd == 0)) {
+		if (_settings_client.gui.vehicle_speed || (old == 0) != (spd == 0)) {
 			InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
 		}
 	}
@@ -1884,7 +1884,7 @@
 		if (v->vehstatus & VS_CRASHED || v->breakdown_ctr != 0) return CMD_ERROR;
 
 		if (flags & DC_EXEC) {
-			if (_settings.vehicle.realistic_acceleration && v->cur_speed != 0) {
+			if (_settings_game.vehicle.realistic_acceleration && v->cur_speed != 0) {
 				ToggleBit(v->u.rail.flags, VRF_REVERSING);
 			} else {
 				v->cur_speed = 0;
@@ -2059,7 +2059,7 @@
 		return tfdd;
 	}
 
-	switch (_settings.pf.pathfinder_for_trains) {
+	switch (_settings_game.pf.pathfinder_for_trains) {
 		case VPF_YAPF: { /* YAPF */
 			bool found = YapfFindNearestRailDepotTwoWay(v, max_distance, NPF_INFINITE_PENALTY, &tfdd.tile, &tfdd.reverse);
 			tfdd.best_length = found ? max_distance / 2 : UINT_MAX; // some fake distance or NOT_FOUND
@@ -2370,7 +2370,7 @@
 	/* quick return in case only one possible track is available */
 	if (KillFirstBit(tracks) == TRACK_BIT_NONE) return FindFirstTrack(tracks);
 
-	switch (_settings.pf.pathfinder_for_trains) {
+	switch (_settings_game.pf.pathfinder_for_trains) {
 		case VPF_YAPF: { /* YAPF */
 			Trackdir trackdir = YapfChooseRailTrack(v, tile, enterdir, tracks, &path_not_found);
 			if (trackdir != INVALID_TRACKDIR) {
@@ -2447,7 +2447,7 @@
 			/* it is first time the problem occurred, set the "path not found" flag */
 			SetBit(v->u.rail.flags, VRF_NO_PATH_TO_DESTINATION);
 			/* and notify user about the event */
-			if (_settings.gui.lost_train_warn && v->owner == _local_player) {
+			if (_settings_client.gui.lost_train_warn && v->owner == _local_player) {
 				SetDParam(0, v->unitnumber);
 				AddNewsItem(
 					STR_TRAIN_IS_LOST,
@@ -2476,7 +2476,7 @@
 
 static bool CheckReverseTrain(Vehicle *v)
 {
-	if (_settings.difficulty.line_reverse_mode != 0 ||
+	if (_settings_game.difficulty.line_reverse_mode != 0 ||
 			v->u.rail.track == TRACK_BIT_DEPOT || v->u.rail.track == TRACK_BIT_WORMHOLE ||
 			!(v->direction & 1)) {
 		return false;
@@ -2489,7 +2489,7 @@
 
 	assert(v->u.rail.track);
 
-	switch (_settings.pf.pathfinder_for_trains) {
+	switch (_settings_game.pf.pathfinder_for_trains) {
 		case VPF_YAPF: /* YAPF */
 			reverse_best = YapfCheckReverseTrain(v);
 			break;
@@ -2609,13 +2609,13 @@
 	uint accel;
 
 	if (v->vehstatus & VS_STOPPED || HasBit(v->u.rail.flags, VRF_REVERSING)) {
-		if (_settings.vehicle.realistic_acceleration) {
+		if (_settings_game.vehicle.realistic_acceleration) {
 			accel = GetTrainAcceleration(v, AM_BRAKE) * 2;
 		} else {
 			accel = v->acceleration * -2;
 		}
 	} else {
-		if (_settings.vehicle.realistic_acceleration) {
+		if (_settings_game.vehicle.realistic_acceleration) {
 			accel = GetTrainAcceleration(v, AM_ACCEL);
 		} else {
 			accel = v->acceleration;
@@ -2756,7 +2756,7 @@
 /** Modify the speed of the vehicle due to a turn */
 static inline void AffectSpeedByDirChange(Vehicle *v, Direction new_dir)
 {
-	if (_settings.vehicle.realistic_acceleration) return;
+	if (_settings_game.vehicle.realistic_acceleration) return;
 
 	DirDiff diff = DirDifference(v->direction, new_dir);
 	if (diff == DIRDIFF_SAME) return;
@@ -2768,7 +2768,7 @@
 /** Modify the speed of the vehicle due to a change in altitude */
 static inline void AffectSpeedByZChange(Vehicle *v, byte old_z)
 {
-	if (old_z == v->z_pos || _settings.vehicle.realistic_acceleration) return;
+	if (old_z == v->z_pos || _settings_game.vehicle.realistic_acceleration) return;
 
 	const RailtypeSlowdownParams *rsp = &_railtype_slowdown[v->u.rail.railtype];
 
@@ -2974,7 +2974,7 @@
 				TrackBits red_signals = TrackdirBitsToTrackBits(TrackStatusToRedSignals(ts) & reachable_trackdirs);
 
 				TrackBits bits = TrackdirBitsToTrackBits(trackdirbits);
-				if (_settings.pf.pathfinder_for_trains != VPF_NTP && _settings.pf.forbid_90_deg && prev == NULL) {
+				if (_settings_game.pf.pathfinder_for_trains != VPF_NTP && _settings_game.pf.forbid_90_deg && prev == NULL) {
 					/* We allow wagons to make 90 deg turns, because forbid_90_deg
 					 * can be switched on halfway a turn */
 					bits &= ~TrackCrossesTracks(FindFirstTrack(v->u.rail.track));
@@ -3002,12 +3002,12 @@
 							v->cur_speed = 0;
 							v->subspeed = 0;
 							v->progress = 255 - 100;
-							if (++v->load_unload_time_rem < _settings.pf.wait_oneway_signal * 20) return;
+							if (++v->load_unload_time_rem < _settings_game.pf.wait_oneway_signal * 20) return;
 						} else if (HasSignalOnTrackdir(gp.new_tile, i)) {
 							v->cur_speed = 0;
 							v->subspeed = 0;
 							v->progress = 255 - 10;
-							if (++v->load_unload_time_rem < _settings.pf.wait_twoway_signal * 73) {
+							if (++v->load_unload_time_rem < _settings_game.pf.wait_twoway_signal * 73) {
 								TileIndex o_tile = gp.new_tile + TileOffsByDiagDir(enterdir);
 								Direction rdir = ReverseDir(dir);
 
@@ -3249,7 +3249,7 @@
 		InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
 
 		if (!PlayVehicleSound(v, VSE_BREAKDOWN)) {
-			SndPlayVehicleFx((_settings.game_creation.landscape != LT_TOYLAND) ?
+			SndPlayVehicleFx((_settings_game.game_creation.landscape != LT_TOYLAND) ?
 				SND_10_TRAIN_BREAKDOWN : SND_3A_COMEDY_BREAKDOWN_2, v);
 		}
 
@@ -3409,7 +3409,7 @@
 
 	/* mask unreachable track bits if we are forbidden to do 90deg turns */
 	TrackBits bits = TrackdirBitsToTrackBits(trackdirbits);
-	if (_settings.pf.pathfinder_for_trains != VPF_NTP && _settings.pf.forbid_90_deg) {
+	if (_settings_game.pf.pathfinder_for_trains != VPF_NTP && _settings_game.pf.forbid_90_deg) {
 		bits &= ~TrackCrossesTracks(FindFirstTrack(v->u.rail.track));
 	}
 
@@ -3542,7 +3542,7 @@
 {
 	static const uint MAX_ACCEPTABLE_DEPOT_DIST = 16;
 
-	if (_settings.vehicle.servint_trains == 0 || !v->NeedsAutomaticServicing()) return;
+	if (_settings_game.vehicle.servint_trains == 0 || !v->NeedsAutomaticServicing()) return;
 	if (v->IsInDepot()) {
 		VehicleServiceInDepot(v);
 		return;
@@ -3618,7 +3618,7 @@
 		if (v->type == VEH_TRAIN && IsFrontEngine(v)) {
 			/* show warning if train is not generating enough income last 2 years (corresponds to a red icon in the vehicle list) */
 			if (v->age >= 730 && v->GetDisplayProfitThisYear() < 0) {
-				if (_settings.gui.train_income_warn && v->owner == _local_player) {
+				if (_settings_client.gui.train_income_warn && v->owner == _local_player) {
 					SetDParam(1, v->GetDisplayProfitThisYear());
 					SetDParam(0, v->unitnumber);
 					AddNewsItem(
--- a/src/train_gui.cpp	Thu May 29 12:52:24 2008 +0000
+++ b/src/train_gui.cpp	Thu May 29 15:56:32 2008 +0000
@@ -124,7 +124,7 @@
 			SetDParam(0, v->cargo_type);
 			SetDParam(1, v->cargo.Count());
 			SetDParam(2, v->cargo.Source());
-			SetDParam(3, _settings.vehicle.freight_trains);
+			SetDParam(3, _settings_game.vehicle.freight_trains);
 			str = FreightWagonMult(v->cargo_type) > 1 ? STR_FROM_MULT : STR_8813_FROM;
 		}
 		DrawString(x, y, str, TC_FROMSTRING);
@@ -150,7 +150,7 @@
 	if (v->cargo_cap != 0) {
 		SetDParam(0, v->cargo_type);
 		SetDParam(1, v->cargo_cap);
-		SetDParam(2, _settings.vehicle.freight_trains);
+		SetDParam(2, _settings_game.vehicle.freight_trains);
 		DrawString(x, y, FreightWagonMult(v->cargo_type) > 1 ? STR_CAPACITY_MULT : STR_013F_CAPACITY, TC_FROMSTRING);
 	}
 }
@@ -249,7 +249,7 @@
 				SetDParam(1, act_cargo[i]); // {CARGO} #2
 				SetDParam(2, i);            // {SHORTCARGO} #1
 				SetDParam(3, max_cargo[i]); // {SHORTCARGO} #2
-				SetDParam(4, _settings.vehicle.freight_trains);
+				SetDParam(4, _settings_game.vehicle.freight_trains);
 				DrawString(x, y + 2, FreightWagonMult(i) > 1 ? STR_TOTAL_CAPACITY_MULT : STR_TOTAL_CAPACITY, TC_FROMSTRING);
 			}
 		}
--- a/src/tree_cmd.cpp	Thu May 29 12:52:24 2008 +0000
+++ b/src/tree_cmd.cpp	Thu May 29 15:56:32 2008 +0000
@@ -112,7 +112,7 @@
  */
 static TreeType GetRandomTreeType(TileIndex tile, uint seed)
 {
-	switch (_settings.game_creation.landscape) {
+	switch (_settings_game.game_creation.landscape) {
 		case LT_TEMPERATE:
 			return (TreeType)(seed * TREE_COUNT_TEMPERATE / 256 + TREE_TEMPERATE);
 
@@ -249,7 +249,7 @@
 
 		if (CanPlantTreesOnTile(tile, true)) {
 			PlaceTree(tile, r);
-			if (_settings.game_creation.tree_placer != TP_IMPROVED) continue;
+			if (_settings_game.game_creation.tree_placer != TP_IMPROVED) continue;
 
 			/* Place a number of trees based on the tile height.
 			 *  This gives a cool effect of multiple trees close together.
@@ -259,7 +259,7 @@
 			j = GetTileZ(tile) / TILE_HEIGHT * 2;
 			while (j--) {
 				/* Above snowline more trees! */
-				if (_settings.game_creation.landscape == LT_ARCTIC && ht > GetSnowLine()) {
+				if (_settings_game.game_creation.landscape == LT_ARCTIC && ht > GetSnowLine()) {
 					PlaceTreeAtSameHeight(tile, ht);
 					PlaceTreeAtSameHeight(tile, ht);
 				};
@@ -270,7 +270,7 @@
 	} while (--i);
 
 	/* place extra trees at rainforest area */
-	if (_settings.game_creation.landscape == LT_TROPIC) {
+	if (_settings_game.game_creation.landscape == LT_TROPIC) {
 		i = ScaleByMapSize(15000);
 
 		do {
@@ -296,18 +296,18 @@
 {
 	uint i, total;
 
-	if (_settings.game_creation.tree_placer == TP_NONE) return;
+	if (_settings_game.game_creation.tree_placer == TP_NONE) return;
 
-	if (_settings.game_creation.landscape != LT_TOYLAND) PlaceMoreTrees();
+	if (_settings_game.game_creation.landscape != LT_TOYLAND) PlaceMoreTrees();
 
-	switch (_settings.game_creation.tree_placer) {
-		case TP_ORIGINAL: i = _settings.game_creation.landscape == LT_ARCTIC ? 15 : 6; break;
-		case TP_IMPROVED: i = _settings.game_creation.landscape == LT_ARCTIC ?  4 : 2; break;
+	switch (_settings_game.game_creation.tree_placer) {
+		case TP_ORIGINAL: i = _settings_game.game_creation.landscape == LT_ARCTIC ? 15 : 6; break;
+		case TP_IMPROVED: i = _settings_game.game_creation.landscape == LT_ARCTIC ?  4 : 2; break;
 		default: NOT_REACHED(); return;
 	}
 
 	total = ScaleByMapSize(1000);
-	if (_settings.game_creation.landscape == LT_TROPIC) total += ScaleByMapSize(15000);
+	if (_settings_game.game_creation.landscape == LT_TROPIC) total += ScaleByMapSize(15000);
 	total *= i;
 	SetGeneratingWorldProgress(GWP_TREE, total);
 
@@ -332,7 +332,7 @@
 
 	if (p2 >= MapSize()) return CMD_ERROR;
 	/* Check the tree type. It can be random or some valid value within the current climate */
-	if (p1 != (uint)-1 && p1 - _tree_base_by_landscape[_settings.game_creation.landscape] >= _tree_count_by_landscape[_settings.game_creation.landscape]) return CMD_ERROR;
+	if (p1 != (uint)-1 && p1 - _tree_base_by_landscape[_settings_game.game_creation.landscape] >= _tree_count_by_landscape[_settings_game.game_creation.landscape]) return CMD_ERROR;
 
 	// make sure sx,sy are smaller than ex,ey
 	ex = TileX(tile);
@@ -390,7 +390,7 @@
 					}
 
 					if (_game_mode != GM_EDITOR && IsValidPlayer(_current_player)) {
-						Town *t = ClosestTownFromTile(tile, _settings.economy.dist_local_authority);
+						Town *t = ClosestTownFromTile(tile, _settings_game.economy.dist_local_authority);
 						if (t != NULL) ChangeTownRating(t, RATING_TREE_UP_STEP, RATING_TREE_MAXIMUM);
 					}
 
@@ -533,7 +533,7 @@
 	uint num;
 
 	if (IsValidPlayer(_current_player)) {
-		Town *t = ClosestTownFromTile(tile, _settings.economy.dist_local_authority);
+		Town *t = ClosestTownFromTile(tile, _settings_game.economy.dist_local_authority);
 		if (t != NULL) ChangeTownRating(t, RATING_TREE_DOWN_STEP, RATING_TREE_MINIMUM);
 	}
 
@@ -626,7 +626,7 @@
 	if (GetTreeGround(tile) == TREE_GROUND_SHORE) {
 		TileLoop_Water(tile);
 	} else {
-		switch (_settings.game_creation.landscape) {
+		switch (_settings_game.game_creation.landscape) {
 			case LT_TROPIC: TileLoopTreesDesert(tile); break;
 			case LT_ARCTIC: TileLoopTreesAlps(tile);   break;
 		}
@@ -652,7 +652,7 @@
 
 	switch (GetTreeGrowth(tile)) {
 		case 3: /* regular sized tree */
-			if (_settings.game_creation.landscape == LT_TROPIC &&
+			if (_settings_game.game_creation.landscape == LT_TROPIC &&
 					GetTreeType(tile) != TREE_CACTUS &&
 					GetTropicZone(tile) == TROPICZONE_DESERT) {
 				AddTreeGrowth(tile, 1);
@@ -704,7 +704,7 @@
 					case TREE_GROUND_GRASS: MakeClear(tile, CLEAR_GRASS, GetTreeDensity(tile)); break;
 					case TREE_GROUND_ROUGH: MakeClear(tile, CLEAR_ROUGH, 3); break;
 					default: // snow or desert
-						MakeClear(tile, _settings.game_creation.landscape == LT_TROPIC ? CLEAR_DESERT : CLEAR_SNOW, GetTreeDensity(tile));
+						MakeClear(tile, _settings_game.game_creation.landscape == LT_TROPIC ? CLEAR_DESERT : CLEAR_SNOW, GetTreeDensity(tile));
 						break;
 				}
 			}
@@ -725,7 +725,7 @@
 	TreeType tree;
 
 	/* place a tree at a random rainforest spot */
-	if (_settings.game_creation.landscape == LT_TROPIC &&
+	if (_settings_game.game_creation.landscape == LT_TROPIC &&
 			(r = Random(), tile = RandomTileSeed(r), GetTropicZone(tile) == TROPICZONE_RAINFOREST) &&
 			CanPlantTreesOnTile(tile, false) &&
 			(tree = GetRandomTreeType(tile, GB(r, 24, 8))) != TREE_INVALID) {
--- a/src/tree_gui.cpp	Thu May 29 12:52:24 2008 +0000
+++ b/src/tree_gui.cpp	Thu May 29 15:56:32 2008 +0000
@@ -74,8 +74,8 @@
 
 		this->DrawWidgets();
 
-		int i = this->base = _tree_base_by_landscape[_settings.game_creation.landscape];
-		int count = this->count = _tree_count_by_landscape[_settings.game_creation.landscape];
+		int i = this->base = _tree_base_by_landscape[_settings_game.game_creation.landscape];
+		int count = this->count = _tree_count_by_landscape[_settings_game.game_creation.landscape];
 
 		int x = 18;
 		int y = 54;
--- a/src/tunnelbridge_cmd.cpp	Thu May 29 12:52:24 2008 +0000
+++ b/src/tunnelbridge_cmd.cpp	Thu May 29 15:56:32 2008 +0000
@@ -169,7 +169,7 @@
 	if (b->avail_year > _cur_year) return false;
 
 	max = b->max_length;
-	if (max >= 16 && _settings.construction.longbridges) max = 100;
+	if (max >= 16 && _settings_game.construction.longbridges) max = 100;
 
 	return b->min_length <= bridge_len && bridge_len <= max;
 }
@@ -311,7 +311,7 @@
 	} else {
 		/* Build a new bridge. */
 
-		bool allow_on_slopes = _settings.construction.build_on_slopes;
+		bool allow_on_slopes = _settings_game.construction.build_on_slopes;
 
 		/* Try and clear the start landscape */
 		ret = DoCommand(tile_start, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
@@ -576,7 +576,7 @@
 	/* Obviously if the bridge/tunnel belongs to us, or no-one, we can remove it */
 	if (CheckTileOwnership(tile) || IsTileOwner(tile, OWNER_NONE)) return true;
 	/* Otherwise we can only remove town-owned stuff with extra patch-settings, or cheat */
-	if (IsTileOwner(tile, OWNER_TOWN) && (_settings.construction.extra_dynamite || _cheats.magic_bulldozer.value)) return true;
+	if (IsTileOwner(tile, OWNER_TOWN) && (_settings_game.construction.extra_dynamite || _cheats.magic_bulldozer.value)) return true;
 	return false;
 }
 
@@ -1123,7 +1123,7 @@
 
 			DrawGroundSpriteAt(image, pal, x, y, z);
 		}
-	} else if (_settings.gui.bridge_pillars) {
+	} else if (_settings_client.gui.bridge_pillars) {
 		/* draw pillars below for high bridges */
 		DrawBridgePillars(psid, ti, axis, type, x, y, z);
 	}
@@ -1200,7 +1200,7 @@
 static void TileLoop_TunnelBridge(TileIndex tile)
 {
 	bool snow_or_desert = HasTunnelBridgeSnowOrDesert(tile);
-	switch (_settings.game_creation.landscape) {
+	switch (_settings_game.game_creation.landscape) {
 		case LT_ARCTIC:
 			if (snow_or_desert != (GetTileZ(tile) > GetSnowLine())) {
 				SetTunnelBridgeSnowOrDesert(tile, !snow_or_desert);
@@ -1388,7 +1388,7 @@
 
 static CommandCost TerraformTile_TunnelBridge(TileIndex tile, uint32 flags, uint z_new, Slope tileh_new)
 {
-	if (_settings.construction.build_on_slopes && AutoslopeEnabled() && IsBridge(tile)) {
+	if (_settings_game.construction.build_on_slopes && AutoslopeEnabled() && IsBridge(tile)) {
 		DiagDirection direction = GetTunnelBridgeDirection(tile);
 		Axis axis = DiagDirToAxis(direction);
 		CommandCost res;
--- a/src/unmovable_cmd.cpp	Thu May 29 12:52:24 2008 +0000
+++ b/src/unmovable_cmd.cpp	Thu May 29 15:56:32 2008 +0000
@@ -375,11 +375,11 @@
 
 void GenerateUnmovables()
 {
-	if (_settings.game_creation.landscape == LT_TOYLAND) return;
+	if (_settings_game.game_creation.landscape == LT_TOYLAND) return;
 
 	/* add radio tower */
 	int radiotowser_to_build = ScaleByMapSize(15); // maximum number of radio towers on the map
-	int lighthouses_to_build = _settings.game_creation.landscape == LT_TROPIC ? 0 : ScaleByMapSize1D((Random() & 3) + 7);
+	int lighthouses_to_build = _settings_game.game_creation.landscape == LT_TROPIC ? 0 : ScaleByMapSize1D((Random() & 3) + 7);
 	SetGeneratingWorldProgress(GWP_UNMOVABLE, radiotowser_to_build + lighthouses_to_build);
 
 	for (uint i = ScaleByMapSize(1000); i != 0; i--) {
@@ -395,7 +395,7 @@
 		}
 	}
 
-	if (_settings.game_creation.landscape == LT_TROPIC) return;
+	if (_settings_game.game_creation.landscape == LT_TROPIC) return;
 
 	/* add lighthouses */
 	uint maxx = MapMaxX();
--- a/src/vehicle.cpp	Thu May 29 12:52:24 2008 +0000
+++ b/src/vehicle.cpp	Thu May 29 15:56:32 2008 +0000
@@ -52,6 +52,7 @@
 #include "effectvehicle_base.h"
 #include "ai/ai.h"
 #include "core/alloc_func.hpp"
+#include "vehiclelist.h"
 
 #include "table/sprites.h"
 #include "table/strings.h"
@@ -128,20 +129,20 @@
 {
 	if (this->vehstatus & (VS_STOPPED | VS_CRASHED)) return false;
 
-	if (_settings.order.no_servicing_if_no_breakdowns && _settings.difficulty.vehicle_breakdowns == 0) {
+	if (_settings_game.order.no_servicing_if_no_breakdowns && _settings_game.difficulty.vehicle_breakdowns == 0) {
 		/* Vehicles set for autoreplacing needs to go to a depot even if breakdowns are turned off.
 		 * Note: If servicing is enabled, we postpone replacement till next service. */
 		return EngineHasReplacementForPlayer(GetPlayer(this->owner), this->engine_type, this->group_id);
 	}
 
-	return _settings.vehicle.servint_ispercent ?
+	return _settings_game.vehicle.servint_ispercent ?
 		(this->reliability < GetEngine(this->engine_type)->reliability * (100 - this->service_interval) / 100) :
 		(this->date_of_last_service + this->service_interval < _date);
 }
 
 bool Vehicle::NeedsAutomaticServicing() const
 {
-	if (_settings.order.gotodepot && VehicleHasDepotOrders(this)) return false;
+	if (_settings_game.order.gotodepot && VehicleHasDepotOrders(this)) return false;
 	if (this->current_order.IsType(OT_LOADING))            return false;
 	if (this->current_order.IsType(OT_GOTO_DEPOT) && this->current_order.GetDepotOrderType() != ODTFB_SERVICE) return false;
 	return NeedsServicing();
@@ -914,7 +915,7 @@
 	if ((rel_old >> 8) != (rel >> 8)) InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
 
 	if (v->breakdown_ctr != 0 || v->vehstatus & VS_STOPPED ||
-			_settings.difficulty.vehicle_breakdowns < 1 ||
+			_settings_game.difficulty.vehicle_breakdowns < 1 ||
 			v->cur_speed < 5 || _game_mode == GM_MENU) {
 		return;
 	}
@@ -931,7 +932,7 @@
 	if (v->type == VEH_SHIP) rel += 0x6666;
 
 	/* reduced breakdowns? */
-	if (_settings.difficulty.vehicle_breakdowns == 1) rel += 0x6666;
+	if (_settings_game.difficulty.vehicle_breakdowns == 1) rel += 0x6666;
 
 	/* check if to break down */
 	if (_breakdown_chance[(uint)min(rel, 0xffff) >> 10] <= v->breakdown_chance) {
@@ -1293,166 +1294,6 @@
 }
 
 /**
- * Generate a list of vehicles inside a depot.
- * @param type    Type of vehicle
- * @param tile    The tile the depot is located on
- * @param engines Pointer to list to add vehicles to
- * @param wagons  Pointer to list to add wagons to (can be NULL)
- */
-void BuildDepotVehicleList(VehicleType type, TileIndex tile, VehicleList *engines, VehicleList *wagons)
-{
-	engines->Clear();
-	if (wagons != NULL && wagons != engines) wagons->Clear();
-
-	const Vehicle *v;
-	FOR_ALL_VEHICLES(v) {
-		/* General tests for all vehicle types */
-		if (v->type != type) continue;
-		if (v->tile != tile) continue;
-
-		switch (type) {
-			case VEH_TRAIN:
-				if (v->u.rail.track != TRACK_BIT_DEPOT) continue;
-				if (wagons != NULL && IsFreeWagon(v)) {
-					*wagons->Append() = v;
-					continue;
-				}
-				break;
-
-			default:
-				if (!v->IsInDepot()) continue;
-				break;
-		}
-
-		if (!v->IsPrimaryVehicle()) continue;
-
-		*engines->Append() = v;
-	}
-
-	/* Ensure the lists are not wasting too much space. If the lists are fresh
-	 * (i.e. built within a command) then this will actually do nothing. */
-	engines->Compact();
-	if (wagons != NULL && wagons != engines) wagons->Compact();
-}
-
-/**
- * @param sort_list list to store the list in. Either NULL or the length length_of_array tells
- * @param length_of_array informs the length allocated for sort_list. This is not the same as the number of vehicles in the list. Needs to be 0 when sort_list is NULL
- * @param type type of vehicle
- * @param owner PlayerID of owner to generate a list for
- * @param index This parameter has different meanings depending on window_type
- *    <ul>
- *      <li>VLW_STATION_LIST:  index of station to generate a list for</li>
- *      <li>VLW_SHARED_ORDERS: index of order to generate a list for<li>
- *      <li>VLW_STANDARD: not used<li>
- *      <li>VLW_DEPOT_LIST: TileIndex of the depot/hangar to make the list for</li>
- *      <li>VLW_GROUP_LIST: index of group to generate a list for</li>
- *    </ul>
- * @param window_type tells what kind of window the list is for. Use the VLW flags in vehicle_gui.h
- * @return the number of vehicles added to the list
- */
-uint GenerateVehicleSortList(const Vehicle ***sort_list, uint16 *length_of_array, VehicleType type, PlayerID owner, uint32 index, uint16 window_type)
-{
-	VehicleList list;
-	GenerateVehicleSortList(&list, type, owner, index, window_type);
-
-	if (list.Length() > 0) {
-		*sort_list = ReallocT(*sort_list, list.Length());
-		memcpy(*sort_list, list.Begin(), sizeof(list.Begin()) * list.Length());
-	}
-
-	return list.Length();
-}
-
-/**
- * Generate a list of vehicles based on window type.
- * @param list        Pointer to list to add vehicles to
- * @param type        Type of vehicle
- * @param owner       Player to generate list for
- * @param index       This parameter has different meanings depending on window_type
- *    <ul>
- *      <li>VLW_STATION_LIST:  index of station to generate a list for</li>
- *      <li>VLW_SHARED_ORDERS: index of order to generate a list for<li>
- *      <li>VLW_STANDARD: not used<li>
- *      <li>VLW_DEPOT_LIST: TileIndex of the depot/hangar to make the list for</li>
- *      <li>VLW_GROUP_LIST: index of group to generate a list for</li>
- *    </ul>
- * @param window_type The type of window the list is for, using the VLW_ flags in vehicle_gui.h
- */
-void GenerateVehicleSortList(VehicleList *list, VehicleType type, PlayerID owner, uint32 index, uint16 window_type)
-{
-	list->Clear();
-
-	const Vehicle *v;
-
-	switch (window_type) {
-		case VLW_STATION_LIST:
-			FOR_ALL_VEHICLES(v) {
-				if (v->type == type && v->IsPrimaryVehicle()) {
-					const Order *order;
-
-					FOR_VEHICLE_ORDERS(v, order) {
-						if (order->IsType(OT_GOTO_STATION) && order->GetDestination() == index) {
-							*list->Append() = v;
-							break;
-						}
-					}
-				}
-			}
-			break;
-
-		case VLW_SHARED_ORDERS:
-			FOR_ALL_VEHICLES(v) {
-				/* Find a vehicle with the order in question */
-				if (v->orders != NULL && v->orders->index == index) {
-					/* Add all vehicles from this vehicle's shared order list */
-					for (v = GetFirstVehicleFromSharedList(v); v != NULL; v = v->next_shared) {
-						*list->Append() = v;
-					}
-					break;
-				}
-			}
-			break;
-
-		case VLW_STANDARD:
-			FOR_ALL_VEHICLES(v) {
-				if (v->type == type && v->owner == owner && v->IsPrimaryVehicle()) {
-					*list->Append() = v;
-				}
-			}
-			break;
-
-		case VLW_DEPOT_LIST:
-			FOR_ALL_VEHICLES(v) {
-				if (v->type == type && v->IsPrimaryVehicle()) {
-					const Order *order;
-
-					FOR_VEHICLE_ORDERS(v, order) {
-						if (order->IsType(OT_GOTO_DEPOT) && order->GetDestination() == index) {
-							*list->Append() = v;
-							break;
-						}
-					}
-				}
-			}
-			break;
-
-		case VLW_GROUP_LIST:
-			FOR_ALL_VEHICLES(v) {
-				if (v->type == type && v->IsPrimaryVehicle() &&
-						v->owner == owner && v->group_id == index) {
-					*list->Append() = v;
-				}
-			}
-			break;
-
-		default: NOT_REACHED(); break;
-	}
-
-	list->Compact();
-}
-
-/**
  * Send all vehicles of type to depots
  * @param type type of vehicle
  * @param flags the flags used for DoCommand()
@@ -1857,10 +1698,10 @@
 	static UnitID gmax = 0;
 
 	switch (type) {
-		case VEH_TRAIN:    max = _settings.vehicle.max_trains; break;
-		case VEH_ROAD:     max = _settings.vehicle.max_roadveh; break;
-		case VEH_SHIP:     max = _settings.vehicle.max_ships; break;
-		case VEH_AIRCRAFT: max = _settings.vehicle.max_aircraft; break;
+		case VEH_TRAIN:    max = _settings_game.vehicle.max_trains; break;
+		case VEH_ROAD:     max = _settings_game.vehicle.max_roadveh; break;
+		case VEH_SHIP:     max = _settings_game.vehicle.max_ships; break;
+		case VEH_AIRCRAFT: max = _settings_game.vehicle.max_aircraft; break;
 		default: NOT_REACHED();
 	}
 
@@ -1910,14 +1751,14 @@
 	assert(IsPlayerBuildableVehicleType(type));
 
 	if (!IsValidPlayer(_current_player)) return false;
-	if (_settings.gui.always_build_infrastructure) return true;
+	if (_settings_client.gui.always_build_infrastructure) return true;
 
 	UnitID max;
 	switch (type) {
-		case VEH_TRAIN:    max = _settings.vehicle.max_trains; break;
-		case VEH_ROAD:     max = _settings.vehicle.max_roadveh; break;
-		case VEH_SHIP:     max = _settings.vehicle.max_ships; break;
-		case VEH_AIRCRAFT: max = _settings.vehicle.max_aircraft; break;
+		case VEH_TRAIN:    max = _settings_game.vehicle.max_trains; break;
+		case VEH_ROAD:     max = _settings_game.vehicle.max_roadveh; break;
+		case VEH_SHIP:     max = _settings_game.vehicle.max_ships; break;
+		case VEH_AIRCRAFT: max = _settings_game.vehicle.max_aircraft; break;
 		default: NOT_REACHED();
 	}
 
@@ -1949,7 +1790,7 @@
 
 	/* The default livery is always available for use, but its in_use flag determines
 	 * whether any _other_ liveries are in use. */
-	if (p->livery[LS_DEFAULT].in_use && (_settings.gui.liveries == 2 || (_settings.gui.liveries == 1 && player == _local_player))) {
+	if (p->livery[LS_DEFAULT].in_use && (_settings_client.gui.liveries == 2 || (_settings_client.gui.liveries == 1 && player == _local_player))) {
 		/* Determine the livery scheme to use */
 		switch (GetEngine(engine_type)->type) {
 			default: NOT_REACHED();
@@ -2516,7 +2357,7 @@
 
 			/* Not the first call for this tick, or still loading */
 			if (mode || !HasBit(this->vehicle_flags, VF_LOADING_FINISHED) ||
-					(_settings.order.timetabling && this->current_order_time < wait_time)) return;
+					(_settings_game.order.timetabling && this->current_order_time < wait_time)) return;
 
 			this->PlayLeaveStationSound();
 
--- a/src/vehicle_func.h	Thu May 29 12:52:24 2008 +0000
+++ b/src/vehicle_func.h	Thu May 29 15:56:32 2008 +0000
@@ -69,10 +69,6 @@
 void TrainPowerChanged(Vehicle *v);
 Money GetTrainRunningCost(const Vehicle *v);
 
-/* Old style list kept for migration */
-uint GenerateVehicleSortList(const Vehicle*** sort_list, uint16 *length_of_array, VehicleType type, PlayerID owner, uint32 index, uint16 window_type);
-void GenerateVehicleSortList(VehicleList *list, VehicleType type, PlayerID owner, uint32 index, uint16 window_type);
-void BuildDepotVehicleList(VehicleType type, TileIndex tile, VehicleList *engine_list, VehicleList *wagon_list);
 CommandCost SendAllVehiclesToDepot(VehicleType type, uint32 flags, bool service, PlayerID owner, uint16 vlw_flag, uint32 id);
 void VehicleEnterDepot(Vehicle *v);
 
--- a/src/vehicle_gui.cpp	Thu May 29 12:52:24 2008 +0000
+++ b/src/vehicle_gui.cpp	Thu May 29 15:56:32 2008 +0000
@@ -36,6 +36,7 @@
 #include "widgets/dropdown_func.h"
 #include "order_func.h"
 #include "timetable.h"
+#include "vehiclelist.h"
 
 #include "table/sprites.h"
 #include "table/strings.h"
@@ -92,7 +93,7 @@
 
 	DEBUG(misc, 3, "Building vehicle list for player %d at station %d", owner, index);
 
-	vl->vehicles.list_length = GenerateVehicleSortList(&vl->vehicles.sort_list, &vl->vehicles.list_length, vl->vehicle_type, owner, index, window_type);
+	GenerateVehicleSortList(&vl->vehicles, vl->vehicle_type, owner, index, window_type);
 
 	vl->vehicles.flags &= ~VL_REBUILD;
 	vl->vehicles.flags |= VL_RESORT;
@@ -110,7 +111,7 @@
 	_last_vehicle[0] = _last_vehicle[1] = NULL;
 
 	_internal_sort_order = (vl->vehicles.flags & VL_DESC) != 0;
-	qsort((void*)vl->vehicles.sort_list, vl->vehicles.list_length, sizeof(vl->vehicles.sort_list[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;
@@ -121,7 +122,7 @@
 {
 	_internal_sort_order = 0;
 	if (list->Length() < 2) return;
-	qsort((void*)list->Begin(), list->Length(), sizeof(list->Begin()), _vehicle_sorter[0]);
+	qsort((void*)list->Begin(), list->Length(), sizeof(*list->Begin()), _vehicle_sorter[0]);
 }
 
 /** draw the vehicle profit button in the vehicle list window. */
@@ -806,8 +807,6 @@
 		PlayerID player = (PlayerID)GB(this->window_number, 0, 8);
 
 		this->vehicle_type = (VehicleType)GB(this->window_number, 11, 5);
-		this->vehicles.list_length = 0;
-		this->vehicles.sort_list = NULL;
 		this->caption_color = player;
 
 		/* Hide the widgets that we will not use in this window
@@ -925,7 +924,6 @@
 
 	~VehicleListWindow()
 	{
-		free((void*)this->vehicles.sort_list);
 	}
 
 	virtual void OnPaint()
@@ -940,12 +938,12 @@
 
 		BuildVehicleList(this, owner, index, window_type);
 		SortVehicleList(this);
-		SetVScrollCount(this, this->vehicles.list_length);
+		SetVScrollCount(this, this->vehicles.Length());
 
 		/* draw the widgets */
 		switch (window_type) {
 			case VLW_SHARED_ORDERS: /* Shared Orders */
-				if (this->vehicles.list_length == 0) {
+				if (this->vehicles.Length() == 0) {
 					/* We can't open this window without vehicles using this order
 					* and we should close the window when deleting the order      */
 					NOT_REACHED();
@@ -981,7 +979,7 @@
 			default: NOT_REACHED(); break;
 		}
 
-		this->SetWidgetsDisabledState(this->vehicles.list_length == 0,
+		this->SetWidgetsDisabledState(this->vehicles.Length() == 0,
 			VLW_WIDGET_MANAGE_VEHICLES_DROPDOWN,
 			VLW_WIDGET_STOP_ALL,
 			VLW_WIDGET_START_ALL,
@@ -994,9 +992,9 @@
 		/* draw arrow pointing up/down for ascending/descending sorting */
 		this->DrawSortButtonState(VLW_WIDGET_SORT_ORDER, this->vehicles.flags & VL_DESC ? SBS_DOWN : SBS_UP);
 
-		max = min(this->vscroll.pos + this->vscroll.cap, this->vehicles.list_length);
+		max = min(this->vscroll.pos + this->vscroll.cap, this->vehicles.Length());
 		for (i = this->vscroll.pos; i < max; ++i) {
-			const Vehicle *v = this->vehicles.sort_list[i];
+			const Vehicle *v = this->vehicles[i];
 			StringID str;
 
 			SetDParam(0, v->GetDisplayProfitThisYear());
@@ -1049,9 +1047,9 @@
 
 				id_v += this->vscroll.pos;
 
-				if (id_v >= this->vehicles.list_length) return; // click out of list bound
+				if (id_v >= this->vehicles.Length()) return; // click out of list bound
 
-				v = this->vehicles.sort_list[id_v];
+				v = this->vehicles[id_v];
 
 				ShowVehicleViewWindow(v);
 			} break;
@@ -1100,7 +1098,7 @@
 				}
 				break;
 			case VLW_WIDGET_MANAGE_VEHICLES_DROPDOWN:
-				assert(this->vehicles.list_length != 0);
+				assert(this->vehicles.Length() != 0);
 
 				switch (index) {
 					case 0: /* Replace window */
@@ -1220,12 +1218,12 @@
 
 void ShowVehicleListWindow(PlayerID player, VehicleType vehicle_type)
 {
-	/* If _settings.gui.advanced_vehicle_list > 1, display the Advanced list
-	 * if _settings.gui.advanced_vehicle_list == 1, display Advanced list only for local player
+	/* If _settings_client.gui.advanced_vehicle_list > 1, display the Advanced list
+	 * if _settings_client.gui.advanced_vehicle_list == 1, display Advanced list only for local player
 	 * if _ctrl_pressed, do the opposite action (Advanced list x Normal list)
 	 */
 
-	if ((_settings.gui.advanced_vehicle_list > (uint)(player != _local_player)) != _ctrl_pressed) {
+	if ((_settings_client.gui.advanced_vehicle_list > (uint)(player != _local_player)) != _ctrl_pressed) {
 		ShowPlayerGroup(player, vehicle_type);
 	} else {
 		ShowVehicleListWindowLocal(player, VLW_STANDARD, vehicle_type, 0);
@@ -1411,10 +1409,10 @@
 	{
 		switch (vehicle_type) {
 			default: NOT_REACHED();
-			case VEH_TRAIN:    return _settings.vehicle.servint_trains   != 0; break;
-			case VEH_ROAD:     return _settings.vehicle.servint_roadveh  != 0; break;
-			case VEH_SHIP:     return _settings.vehicle.servint_ships    != 0; break;
-			case VEH_AIRCRAFT: return _settings.vehicle.servint_aircraft != 0; break;
+			case VEH_TRAIN:    return _settings_game.vehicle.servint_trains   != 0; break;
+			case VEH_ROAD:     return _settings_game.vehicle.servint_roadveh  != 0; break;
+			case VEH_SHIP:     return _settings_game.vehicle.servint_ships    != 0; break;
+			case VEH_AIRCRAFT: return _settings_game.vehicle.servint_aircraft != 0; break;
 		}
 		return false; // kill a compiler warning
 	}
@@ -1486,7 +1484,7 @@
 				SetDParam(1, v->u.rail.cached_power);
 				SetDParam(0, v->u.rail.cached_weight);
 				SetDParam(3, v->u.rail.cached_max_te / 1000);
-				DrawString(2, 25, (_settings.vehicle.realistic_acceleration && v->u.rail.railtype != RAILTYPE_MAGLEV) ?
+				DrawString(2, 25, (_settings_game.vehicle.realistic_acceleration && v->u.rail.railtype != RAILTYPE_MAGLEV) ?
 					STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED_MAX_TE :
 					STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED, TC_FROMSTRING);
 				break;
@@ -1514,7 +1512,7 @@
 		/* Draw service interval text */
 		SetDParam(0, v->service_interval);
 		SetDParam(1, v->date_of_last_service);
-		DrawString(13, this->height - (v->type != VEH_TRAIN ? 11 : 23), _settings.vehicle.servint_ispercent ? STR_SERVICING_INTERVAL_PERCENT : STR_883C_SERVICING_INTERVAL_DAYS, TC_FROMSTRING);
+		DrawString(13, this->height - (v->type != VEH_TRAIN ? 11 : 23), _settings_game.vehicle.servint_ispercent ? STR_SERVICING_INTERVAL_PERCENT : STR_883C_SERVICING_INTERVAL_DAYS, TC_FROMSTRING);
 
 		switch (v->type) {
 			case VEH_TRAIN:
@@ -1953,7 +1951,7 @@
 					}
 				} else {
 					SetDParam(0, v->GetDisplaySpeed());
-					str = STR_TRAIN_STOPPING + _settings.gui.vehicle_speed;
+					str = STR_TRAIN_STOPPING + _settings_client.gui.vehicle_speed;
 				}
 			} else { // no train
 				str = STR_8861_STOPPED;
@@ -1963,7 +1961,7 @@
 				case OT_GOTO_STATION: {
 					SetDParam(0, v->current_order.GetDestination());
 					SetDParam(1, v->GetDisplaySpeed());
-					str = STR_HEADING_FOR_STATION + _settings.gui.vehicle_speed;
+					str = STR_HEADING_FOR_STATION + _settings_client.gui.vehicle_speed;
 				} break;
 
 				case OT_GOTO_DEPOT: {
@@ -1977,9 +1975,9 @@
 						SetDParam(1, v->GetDisplaySpeed());
 					}
 					if ((v->current_order.GetDepotActionType() & ODATFB_HALT) && !(v->current_order.GetDepotOrderType() & ODTFB_PART_OF_ORDERS)) {
-						str = _heading_for_depot_strings[v->type] + _settings.gui.vehicle_speed;
+						str = _heading_for_depot_strings[v->type] + _settings_client.gui.vehicle_speed;
 					} else {
-						str = _heading_for_depot_service_strings[v->type] + _settings.gui.vehicle_speed;
+						str = _heading_for_depot_service_strings[v->type] + _settings_client.gui.vehicle_speed;
 					}
 				} break;
 
@@ -1990,7 +1988,7 @@
 				case OT_GOTO_WAYPOINT: {
 					assert(v->type == VEH_TRAIN);
 					SetDParam(0, v->current_order.GetDestination());
-					str = STR_HEADING_FOR_WAYPOINT + _settings.gui.vehicle_speed;
+					str = STR_HEADING_FOR_WAYPOINT + _settings_client.gui.vehicle_speed;
 					SetDParam(1, v->GetDisplaySpeed());
 					break;
 				}
@@ -2004,7 +2002,7 @@
 
 				default:
 					if (v->num_orders == 0) {
-						str = STR_NO_ORDERS + _settings.gui.vehicle_speed;
+						str = STR_NO_ORDERS + _settings_client.gui.vehicle_speed;
 						SetDParam(0, v->GetDisplaySpeed());
 					} else {
 						str = STR_EMPTY;
--- a/src/vehicle_type.h	Thu May 29 12:52:24 2008 +0000
+++ b/src/vehicle_type.h	Thu May 29 15:56:32 2008 +0000
@@ -6,7 +6,6 @@
 #define VEHICLE_TYPE_H
 
 #include "core/enum_type.hpp"
-#include "misc/smallvec.h"
 
 typedef uint16 VehicleID;
 
@@ -57,6 +56,4 @@
 	DEPOT_COMMAND_MASK  = 0xF,
 };
 
-typedef SmallVector<const Vehicle*, 32> VehicleList;
-
 #endif /* VEHICLE_TYPE_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/vehiclelist.cpp	Thu May 29 15:56:32 2008 +0000
@@ -0,0 +1,144 @@
+/* $Id$ */
+
+/** @file vehicle.cpp Base implementations of all vehicles. */
+
+#include "stdafx.h"
+#include "openttd.h"
+#include "vehicle_type.h"
+#include "vehicle_func.h"
+#include "vehicle_base.h"
+#include "vehicle_gui.h"
+#include "core/alloc_func.hpp"
+#include "train.h"
+#include "vehiclelist.h"
+
+/**
+ * Generate a list of vehicles inside a depot.
+ * @param type    Type of vehicle
+ * @param tile    The tile the depot is located on
+ * @param engines Pointer to list to add vehicles to
+ * @param wagons  Pointer to list to add wagons to (can be NULL)
+ */
+void BuildDepotVehicleList(VehicleType type, TileIndex tile, VehicleList *engines, VehicleList *wagons)
+{
+	engines->Clear();
+	if (wagons != NULL && wagons != engines) wagons->Clear();
+
+	const Vehicle *v;
+	FOR_ALL_VEHICLES(v) {
+		/* General tests for all vehicle types */
+		if (v->type != type) continue;
+		if (v->tile != tile) continue;
+
+		switch (type) {
+			case VEH_TRAIN:
+				if (v->u.rail.track != TRACK_BIT_DEPOT) continue;
+				if (wagons != NULL && IsFreeWagon(v)) {
+					*wagons->Append() = v;
+					continue;
+				}
+				break;
+
+			default:
+				if (!v->IsInDepot()) continue;
+				break;
+		}
+
+		if (!v->IsPrimaryVehicle()) continue;
+
+		*engines->Append() = v;
+	}
+
+	/* Ensure the lists are not wasting too much space. If the lists are fresh
+	 * (i.e. built within a command) then this will actually do nothing. */
+	engines->Compact();
+	if (wagons != NULL && wagons != engines) wagons->Compact();
+}
+
+/**
+ * Generate a list of vehicles based on window type.
+ * @param list        Pointer to list to add vehicles to
+ * @param type        Type of vehicle
+ * @param owner       Player to generate list for
+ * @param index       This parameter has different meanings depending on window_type
+ *    <ul>
+ *      <li>VLW_STATION_LIST:  index of station to generate a list for</li>
+ *      <li>VLW_SHARED_ORDERS: index of order to generate a list for<li>
+ *      <li>VLW_STANDARD: not used<li>
+ *      <li>VLW_DEPOT_LIST: TileIndex of the depot/hangar to make the list for</li>
+ *      <li>VLW_GROUP_LIST: index of group to generate a list for</li>
+ *    </ul>
+ * @param window_type The type of window the list is for, using the VLW_ flags in vehicle_gui.h
+ */
+void GenerateVehicleSortList(VehicleList *list, VehicleType type, PlayerID owner, uint32 index, uint16 window_type)
+{
+	list->Clear();
+
+	const Vehicle *v;
+
+	switch (window_type) {
+		case VLW_STATION_LIST:
+			FOR_ALL_VEHICLES(v) {
+				if (v->type == type && v->IsPrimaryVehicle()) {
+					const Order *order;
+
+					FOR_VEHICLE_ORDERS(v, order) {
+						if (order->IsType(OT_GOTO_STATION) && order->GetDestination() == index) {
+							*list->Append() = v;
+							break;
+						}
+					}
+				}
+			}
+			break;
+
+		case VLW_SHARED_ORDERS:
+			FOR_ALL_VEHICLES(v) {
+				/* Find a vehicle with the order in question */
+				if (v->orders != NULL && v->orders->index == index) {
+					/* Add all vehicles from this vehicle's shared order list */
+					for (v = GetFirstVehicleFromSharedList(v); v != NULL; v = v->next_shared) {
+						*list->Append() = v;
+					}
+					break;
+				}
+			}
+			break;
+
+		case VLW_STANDARD:
+			FOR_ALL_VEHICLES(v) {
+				if (v->type == type && v->owner == owner && v->IsPrimaryVehicle()) {
+					*list->Append() = v;
+				}
+			}
+			break;
+
+		case VLW_DEPOT_LIST:
+			FOR_ALL_VEHICLES(v) {
+				if (v->type == type && v->IsPrimaryVehicle()) {
+					const Order *order;
+
+					FOR_VEHICLE_ORDERS(v, order) {
+						if (order->IsType(OT_GOTO_DEPOT) && order->GetDestination() == index) {
+							*list->Append() = v;
+							break;
+						}
+					}
+				}
+			}
+			break;
+
+		case VLW_GROUP_LIST:
+			FOR_ALL_VEHICLES(v) {
+				if (v->type == type && v->IsPrimaryVehicle() &&
+						v->owner == owner && v->group_id == index) {
+					*list->Append() = v;
+				}
+			}
+			break;
+
+		default: NOT_REACHED(); break;
+	}
+
+	list->Compact();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/vehiclelist.h	Thu May 29 15:56:32 2008 +0000
@@ -0,0 +1,15 @@
+/* $Id$ */
+
+/** @file vehiclelist.h Functions and type for generating vehicle lists. */
+
+#ifndef VEHICLELIST_H
+#define VEHICLELIST_H
+
+#include "misc/smallvec.h"
+
+typedef SmallVector<const Vehicle *, 32> VehicleList;
+
+void GenerateVehicleSortList(VehicleList *list, VehicleType type, PlayerID owner, uint32 index, uint16 window_type);
+void BuildDepotVehicleList(VehicleType type, TileIndex tile, VehicleList *engine_list, VehicleList *wagon_list);
+
+#endif /* VEHICLELIST_H */
--- a/src/video/cocoa/event.mm	Thu May 29 12:52:24 2008 +0000
+++ b/src/video/cocoa/event.mm	Thu May 29 15:56:32 2008 +0000
@@ -288,9 +288,9 @@
 	}
 
 	if (_current_mods & NSShiftKeyMask)     key |= WKC_SHIFT;
-	if (_current_mods & NSControlKeyMask)   key |= (_settings.gui.right_mouse_btn_emulation != RMBE_CONTROL ? WKC_CTRL : WKC_META);
+	if (_current_mods & NSControlKeyMask)   key |= (_settings_client.gui.right_mouse_btn_emulation != RMBE_CONTROL ? WKC_CTRL : WKC_META);
 	if (_current_mods & NSAlternateKeyMask) key |= WKC_ALT;
-	if (_current_mods & NSCommandKeyMask)   key |= (_settings.gui.right_mouse_btn_emulation != RMBE_CONTROL ? WKC_META : WKC_CTRL);
+	if (_current_mods & NSCommandKeyMask)   key |= (_settings_client.gui.right_mouse_btn_emulation != RMBE_CONTROL ? WKC_META : WKC_CTRL);
 
 	return key << 16;
 }
@@ -459,8 +459,8 @@
 		case NSLeftMouseDown:
 		{
 			uint32 keymask = 0;
-			if (_settings.gui.right_mouse_btn_emulation == RMBE_COMMAND) keymask |= NSCommandKeyMask;
-			if (_settings.gui.right_mouse_btn_emulation == RMBE_CONTROL) keymask |= NSControlKeyMask;
+			if (_settings_client.gui.right_mouse_btn_emulation == RMBE_COMMAND) keymask |= NSCommandKeyMask;
+			if (_settings_client.gui.right_mouse_btn_emulation == RMBE_CONTROL) keymask |= NSControlKeyMask;
 
 			pt = _cocoa_subdriver->GetMouseLocation(event);
 
@@ -602,8 +602,8 @@
 			} /* else: deltaY was 0.0 and we don't want to do anything */
 
 			/* Set the scroll count for scrollwheel scrolling */
-			_cursor.h_wheel -= (int)([ event deltaX ]* 5 * _settings.gui.scrollwheel_multiplier);
-			_cursor.v_wheel -= (int)([ event deltaY ]* 5 * _settings.gui.scrollwheel_multiplier);
+			_cursor.h_wheel -= (int)([ event deltaX ]* 5 * _settings_client.gui.scrollwheel_multiplier);
+			_cursor.v_wheel -= (int)([ event deltaY ]* 5 * _settings_client.gui.scrollwheel_multiplier);
 			break;
 
 		default:
@@ -671,7 +671,7 @@
 
 			bool old_ctrl_pressed = _ctrl_pressed;
 
-			_ctrl_pressed = !!(_current_mods & ( _settings.gui.right_mouse_btn_emulation != RMBE_CONTROL ? NSControlKeyMask : NSCommandKeyMask));
+			_ctrl_pressed = !!(_current_mods & ( _settings_client.gui.right_mouse_btn_emulation != RMBE_CONTROL ? NSControlKeyMask : NSCommandKeyMask));
 			_shift_pressed = !!(_current_mods & NSShiftKeyMask);
 
 			if (old_ctrl_pressed != _ctrl_pressed) HandleCtrlChanged();
--- a/src/viewport.cpp	Thu May 29 12:52:24 2008 +0000
+++ b/src/viewport.cpp	Thu May 29 15:56:32 2008 +0000
@@ -1020,7 +1020,7 @@
 						right  > t->sign.left &&
 						left   < t->sign.left + t->sign.width_1) {
 					AddStringToDraw(t->sign.left + 1, t->sign.top + 1,
-						_settings.gui.population_in_label ? STR_TOWN_LABEL_POP : STR_TOWN_LABEL,
+						_settings_client.gui.population_in_label ? STR_TOWN_LABEL_POP : STR_TOWN_LABEL,
 						t->index, t->population);
 				}
 			}
@@ -1036,7 +1036,7 @@
 						right  > t->sign.left &&
 						left   < t->sign.left + t->sign.width_1 * 2) {
 					AddStringToDraw(t->sign.left + 1, t->sign.top + 1,
-						_settings.gui.population_in_label ? STR_TOWN_LABEL_POP : STR_TOWN_LABEL,
+						_settings_client.gui.population_in_label ? STR_TOWN_LABEL_POP : STR_TOWN_LABEL,
 						t->index, t->population);
 				}
 			}
@@ -1591,7 +1591,7 @@
 		int delta_y = w->viewport->dest_scrollpos_y - w->viewport->scrollpos_y;
 
 		if (delta_x != 0 || delta_y != 0) {
-			if (_settings.gui.smooth_scroll) {
+			if (_settings_client.gui.smooth_scroll) {
 				int max_scroll = ScaleByMapSize1D(512);
 				/* Not at our desired positon yet... */
 				w->viewport->scrollpos_x += Clamp(delta_x / 4, -max_scroll, max_scroll);
@@ -2510,7 +2510,7 @@
 		}
 	}
 
-	if (_settings.gui.measure_tooltip) {
+	if (_settings_client.gui.measure_tooltip) {
 		TileIndex t0 = TileVirtXY(thd->selstart.x, thd->selstart.y);
 		TileIndex t1 = TileVirtXY(x, y);
 		uint distance = DistanceManhattan(t0, t1) + 1;
@@ -2590,7 +2590,7 @@
 			style = HT_DIR_X;
 
 calc_heightdiff_single_direction:;
-			if (_settings.gui.measure_tooltip) {
+			if (_settings_client.gui.measure_tooltip) {
 				TileIndex t0 = TileVirtXY(sx, sy);
 				TileIndex t1 = TileVirtXY(x, y);
 				uint distance = DistanceManhattan(t0, t1) + 1;
@@ -2618,7 +2618,7 @@
 			y = sy + Clamp(y - sy, -limit, limit);
 			} /* Fallthrough */
 		case VPM_X_AND_Y: { /* drag an X by Y area */
-			if (_settings.gui.measure_tooltip) {
+			if (_settings_client.gui.measure_tooltip) {
 				static const StringID measure_strings_area[] = {
 					STR_NULL, STR_NULL, STR_MEASURE_AREA, STR_MEASURE_AREA_HEIGHTDIFF
 				};
@@ -2756,3 +2756,33 @@
 {
 	SetObjectToPlace(SPR_CURSOR_MOUSE, PAL_NONE, VHM_NONE, WC_MAIN_WINDOW, 0);
 }
+
+
+void SaveViewportBeforeSaveGame()
+{
+	const Window *w = FindWindowById(WC_MAIN_WINDOW, 0);
+
+	if (w != NULL) {
+		_saved_scrollpos_x = w->viewport->scrollpos_x;
+		_saved_scrollpos_y = w->viewport->scrollpos_y;
+		_saved_scrollpos_zoom = w->viewport->zoom;
+	}
+}
+
+void ResetViewportAfterLoadGame()
+{
+	Window *w = FindWindowById(WC_MAIN_WINDOW, 0);
+
+	w->viewport->scrollpos_x = _saved_scrollpos_x;
+	w->viewport->scrollpos_y = _saved_scrollpos_y;
+	w->viewport->dest_scrollpos_x = _saved_scrollpos_x;
+	w->viewport->dest_scrollpos_y = _saved_scrollpos_y;
+
+	ViewPort *vp = w->viewport;
+	vp->zoom = min(_saved_scrollpos_zoom, ZOOM_LVL_MAX);
+	vp->virtual_width = ScaleByZoom(vp->width, vp->zoom);
+	vp->virtual_height = ScaleByZoom(vp->height, vp->zoom);
+
+	DoZoomInOutWindow(ZOOM_NONE, w); // update button status
+	MarkWholeScreenDirty();
+}
--- a/src/water_cmd.cpp	Thu May 29 12:52:24 2008 +0000
+++ b/src/water_cmd.cpp	Thu May 29 15:56:32 2008 +0000
@@ -771,7 +771,7 @@
 	}
 
 	/* if non-uniform stations are disabled, flood some train in this train station (if there is any) */
-	if (!_settings.station.nonuniform_stations && IsTileType(tile, MP_STATION) && GetStationType(tile) == STATION_RAIL) {
+	if (!_settings_game.station.nonuniform_stations && IsTileType(tile, MP_STATION) && GetStationType(tile) == STATION_RAIL) {
 		const Station *st = GetStationByTile(tile);
 
 		BEGIN_TILE_LOOP(t, st->trainst_w, st->trainst_h, st->train_tile)
--- a/src/waypoint.cpp	Thu May 29 12:52:24 2008 +0000
+++ b/src/waypoint.cpp	Thu May 29 15:56:32 2008 +0000
@@ -210,7 +210,7 @@
 
 	tileh = GetTileSlope(tile, NULL);
 	if (tileh != SLOPE_FLAT &&
-			(!_settings.construction.build_on_slopes || IsSteepSlope(tileh) || !(tileh & (0x3 << axis)) || !(tileh & ~(0x3 << axis)))) {
+			(!_settings_game.construction.build_on_slopes || IsSteepSlope(tileh) || !(tileh & (0x3 << axis)) || !(tileh & ~(0x3 << axis)))) {
 		return_cmd_error(STR_0007_FLAT_LAND_REQUIRED);
 	}
 
--- a/src/widgets/dropdown.cpp	Thu May 29 12:52:24 2008 +0000
+++ b/src/widgets/dropdown.cpp	Thu May 29 15:56:32 2008 +0000
@@ -74,6 +74,7 @@
 
 	DropdownWindow(int x, int y, int width, int height, const Widget *widget) : Window(x, y, width, height, WC_DROPDOWN_MENU, widget)
 	{
+		this->FindWindowPlacementAndResize(width, height);
 	}
 
 	~DropdownWindow()
@@ -273,7 +274,7 @@
 		} else {
 			/* ... and lastly if it won't, enable the scroll bar and fit the
 			 * list in below the widget */
-			int avg_height = list_height / list->size();
+			int avg_height = list_height / (int)list->size();
 			int rows = (screen_bottom - 4 - top) / avg_height;
 			height = rows * avg_height;
 			scroll = true;
@@ -305,8 +306,8 @@
 		dw->widget[0].right -= 12;
 
 		/* Capacity is the average number of items visible */
-		dw->vscroll.cap   = height * list->size() / list_height;
-		dw->vscroll.count = list->size();
+		dw->vscroll.cap   = height * (uint16)list->size() / list_height;
+		dw->vscroll.count = (uint16)list->size();
 	}
 
 	dw->desc_flags = WDF_DEF_WIDGET;
--- a/src/win32.cpp	Thu May 29 12:52:24 2008 +0000
+++ b/src/win32.cpp	Thu May 29 15:56:32 2008 +0000
@@ -1090,7 +1090,7 @@
 	const char *ptr;
 
 	WChar c;
-	size_t width, length;
+	uint16 width, length;
 
 	if (IsClipboardFormatAvailable(CF_UNICODETEXT)) {
 		OpenClipboard(NULL);
@@ -1122,7 +1122,7 @@
 	for (ptr = utf8_buf; (c = Utf8Consume(&ptr)) != '\0';) {
 		if (!IsPrintable(c)) break;
 
-		size_t len = Utf8CharLen(c);
+		byte len = Utf8CharLen(c);
 		if (tb->length + length >= tb->maxlength - len) break;
 
 		byte charwidth = GetCharacterWidth(FS_NORMAL, c);
--- a/src/window.cpp	Thu May 29 12:52:24 2008 +0000
+++ b/src/window.cpp	Thu May 29 15:56:32 2008 +0000
@@ -37,6 +37,7 @@
 Window *_z_windows[MAX_NUMBER_OF_WINDOWS];
 Window **_last_z_window; ///< always points to the next free space in the z-array
 
+byte _no_scroll;
 Point _cursorpos_drag_start;
 
 int _scrollbar_start_pos;
@@ -1021,6 +1022,7 @@
 	_last_z_window = _z_windows;
 	_mouseover_last_w = NULL;
 	_no_scroll = 0;
+	_scrolling_viewport = 0;
 }
 
 /**
@@ -1217,11 +1219,11 @@
 			int nx = x;
 			int ny = y;
 
-			if (_settings.gui.window_snap_radius != 0) {
+			if (_settings_client.gui.window_snap_radius != 0) {
 				Window* const *vz;
 
-				int hsnap = _settings.gui.window_snap_radius;
-				int vsnap = _settings.gui.window_snap_radius;
+				int hsnap = _settings_client.gui.window_snap_radius;
+				int vsnap = _settings_client.gui.window_snap_radius;
 				int delta;
 
 				FOR_ALL_WINDOWS(vz) {
@@ -1467,7 +1469,7 @@
 
 static bool HandleViewportScroll()
 {
-	bool scrollwheel_scrolling = _settings.gui.scrollwheel_scrolling == 1 && (_cursor.v_wheel != 0 || _cursor.h_wheel != 0);
+	bool scrollwheel_scrolling = _settings_client.gui.scrollwheel_scrolling == 1 && (_cursor.v_wheel != 0 || _cursor.h_wheel != 0);
 
 	if (!_scrolling_viewport) return true;
 
@@ -1487,7 +1489,7 @@
 	}
 
 	Point delta;
-	if (_settings.gui.reverse_scroll) {
+	if (_settings_client.gui.reverse_scroll) {
 		delta.x = -_cursor.delta.x;
 		delta.y = -_cursor.delta.y;
 	} else {
@@ -1667,7 +1669,7 @@
 		return;
 	}
 
-	if (_settings.gui.autoscroll && _game_mode != GM_MENU && !IsGeneratingWorld()) {
+	if (_settings_client.gui.autoscroll && _game_mode != GM_MENU && !IsGeneratingWorld()) {
 		int x = _cursor.pos.x;
 		int y = _cursor.pos.y;
 		Window *w = FindWindowFromPt(x, y);
@@ -1707,6 +1709,55 @@
 extern void UpdateTileSelection();
 extern bool VpHandlePlaceSizingDrag();
 
+static void ScrollMainViewport(int x, int y)
+{
+	if (_game_mode != GM_MENU) {
+		Window *w = FindWindowById(WC_MAIN_WINDOW, 0);
+		assert(w);
+
+		w->viewport->dest_scrollpos_x += ScaleByZoom(x, w->viewport->zoom);
+		w->viewport->dest_scrollpos_y += ScaleByZoom(y, w->viewport->zoom);
+	}
+}
+
+/**
+ * Describes all the different arrow key combinations the game allows
+ * when it is in scrolling mode.
+ * The real arrow keys are bitwise numbered as
+ * 1 = left
+ * 2 = up
+ * 4 = right
+ * 8 = down
+ */
+static const int8 scrollamt[16][2] = {
+	{ 0,  0}, ///<  no key specified
+	{-2,  0}, ///<  1 : left
+	{ 0, -2}, ///<  2 : up
+	{-2, -1}, ///<  3 : left  + up
+	{ 2,  0}, ///<  4 : right
+	{ 0,  0}, ///<  5 : left  + right = nothing
+	{ 2, -1}, ///<  6 : right + up
+	{ 0, -2}, ///<  7 : right + left  + up = up
+	{ 0  ,2}, ///<  8 : down
+	{-2  ,1}, ///<  9 : down  + left
+	{ 0,  0}, ///< 10 : down  + up    = nothing
+	{-2,  0}, ///< 11 : left  + up    +  down = left
+	{ 2,  1}, ///< 12 : down  + right
+	{ 0,  2}, ///< 13 : left  + right +  down = down
+	{ 2,  0}, ///< 14 : right + up    +  down = right
+	{ 0,  0}, ///< 15 : left  + up    +  right + down  = nothing
+};
+
+static bool HandleKeyScrolling()
+{
+	if (_dirkeys && !_no_scroll) {
+		int factor = _shift_pressed ? 50 : 10;
+		ScrollMainViewport(scrollamt[_dirkeys][0] * factor, scrollamt[_dirkeys][1] * factor);
+		return false;
+	}
+	return true;
+}
+
 void MouseLoop(MouseClick click, int mousewheel)
 {
 	DecreaseWindowCounters();
@@ -1718,8 +1769,9 @@
 	if (!HandleScrollbarScrolling()) return;
 	if (!HandleViewportScroll())     return;
 	if (!HandleMouseOver())          return;
+	if (!HandleKeyScrolling())       return;
 
-	bool scrollwheel_scrolling = _settings.gui.scrollwheel_scrolling == 1 && (_cursor.v_wheel != 0 || _cursor.h_wheel != 0);
+	bool scrollwheel_scrolling = _settings_client.gui.scrollwheel_scrolling == 1 && (_cursor.v_wheel != 0 || _cursor.h_wheel != 0);
 	if (click == MC_NONE && mousewheel == 0 && !scrollwheel_scrolling) return;
 
 	int x = _cursor.pos.x;
@@ -1734,7 +1786,7 @@
 	if (vp != NULL && (_game_mode == GM_MENU || IsGeneratingWorld())) return;
 
 	if (mousewheel != 0) {
-		if (_settings.gui.scrollwheel_scrolling == 0) {
+		if (_settings_client.gui.scrollwheel_scrolling == 0) {
 			/* Send mousewheel event to window */
 			w->OnMouseWheel(mousewheel);
 		}
@@ -1979,6 +2031,12 @@
  */
 void CallWindowTickEvent()
 {
+	if (_scroller_click_timeout > 3) {
+		_scroller_click_timeout -= 3;
+	} else {
+		_scroller_click_timeout = 0;
+	}
+
 	for (Window * const *wz = _last_z_window; wz != _z_windows;) {
 		(*--wz)->OnTick();
 	}
@@ -2059,7 +2117,7 @@
 		w = FindWindowById(WC_MAIN_TOOLBAR, 0);
 	}
 
-	switch (_settings.gui.toolbar_pos) {
+	switch (_settings_client.gui.toolbar_pos) {
 		case 1:  w->left = (_screen.width - w->width) / 2; break;
 		case 2:  w->left = _screen.width - w->width; break;
 		default: w->left = 0;
@@ -2068,6 +2126,30 @@
 	return w->left;
 }
 
+void SetVScrollCount(Window *w, int num)
+{
+	w->vscroll.count = num;
+	num -= w->vscroll.cap;
+	if (num < 0) num = 0;
+	if (num < w->vscroll.pos) w->vscroll.pos = num;
+}
+
+void SetVScroll2Count(Window *w, int num)
+{
+	w->vscroll2.count = num;
+	num -= w->vscroll2.cap;
+	if (num < 0) num = 0;
+	if (num < w->vscroll2.pos) w->vscroll2.pos = num;
+}
+
+void SetHScrollCount(Window *w, int num)
+{
+	w->hscroll.count = num;
+	num -= w->hscroll.cap;
+	if (num < 0) num = 0;
+	if (num < w->hscroll.pos) w->hscroll.pos = num;
+}
+
 /**
  * Relocate all windows to fit the new size of the game application screen
  * @param neww New width of the game application screen
--- a/src/window_gui.h	Thu May 29 12:52:24 2008 +0000
+++ b/src/window_gui.h	Thu May 29 15:56:32 2008 +0000
@@ -536,6 +536,21 @@
 extern Window **_last_z_window;
 #define FOR_ALL_WINDOWS(wz) for (wz = _z_windows; wz != _last_z_window; wz++)
 
+/**
+ * In certain windows you navigate with the arrow keys. Do not scroll the
+ * gameview when here. Bitencoded variable that only allows scrolling if all
+ * elements are zero
+ */
+enum {
+	SCROLL_CON  = 0,
+	SCROLL_EDIT = 1,
+	SCROLL_SAVE = 2,
+	SCROLL_CHAT = 4,
+};
+
+/** Disable scrolling of the main viewport when an input-window is active. */
+extern byte _no_scroll;
+
 extern Point _cursorpos_drag_start;
 
 extern int _scrollbar_start_pos;
@@ -562,6 +577,10 @@
 
 void ResizeWindowForWidget(Window *w, int widget, int delta_x, int delta_y);
 
+void SetVScrollCount(Window *w, int num);
+void SetVScroll2Count(Window *w, int num);
+void SetHScrollCount(Window *w, int num);
+
 
 /**
  * Sets the enabled/disabled status of a widget.
--- a/src/yapf/yapf_base.hpp	Thu May 29 12:52:24 2008 +0000
+++ b/src/yapf/yapf_base.hpp	Thu May 29 15:56:32 2008 +0000
@@ -53,7 +53,7 @@
 protected:
 	Node*                m_pBestDestNode;      ///< pointer to the destination node found at last round
 	Node*                m_pBestIntermediateNode; ///< here should be node closest to the destination if path not found
-	const YAPFSettings  *m_settings;           ///< current settings (_settings.yapf)
+	const YAPFSettings  *m_settings;           ///< current settings (_settings_game.yapf)
 	int                  m_max_search_nodes;   ///< maximum number of nodes we are allowed to visit before we give up
 	const Vehicle*       m_veh;                ///< vehicle that we are trying to drive
 
@@ -74,7 +74,7 @@
 	FORCEINLINE CYapfBaseT()
 		: m_pBestDestNode(NULL)
 		, m_pBestIntermediateNode(NULL)
-		, m_settings(&_settings.pf.yapf)
+		, m_settings(&_settings_game.pf.yapf)
 		, m_max_search_nodes(PfGetSettings().max_search_nodes)
 		, m_veh(NULL)
 		, m_stats_cost_calcs(0)
--- a/src/yapf/yapf_rail.cpp	Thu May 29 12:52:24 2008 +0000
+++ b/src/yapf/yapf_rail.cpp	Thu May 29 15:56:32 2008 +0000
@@ -254,7 +254,7 @@
 	PfnChooseRailTrack pfnChooseRailTrack = &CYapfRail1::stChooseRailTrack;
 
 	// check if non-default YAPF type needed
-	if (_settings.pf.forbid_90_deg) {
+	if (_settings_game.pf.forbid_90_deg) {
 		pfnChooseRailTrack = &CYapfRail2::stChooseRailTrack; // Trackdir, forbid 90-deg
 	}
 
@@ -311,7 +311,7 @@
 	PfnCheckReverseTrain pfnCheckReverseTrain = CYapfRail1::stCheckReverseTrain;
 
 	// check if non-default YAPF type needed
-	if (_settings.pf.forbid_90_deg) {
+	if (_settings_game.pf.forbid_90_deg) {
 		pfnCheckReverseTrain = &CYapfRail2::stCheckReverseTrain; // Trackdir, forbid 90-deg
 	}
 
@@ -341,7 +341,7 @@
 	PfnFindNearestDepotTwoWay pfnFindNearestDepotTwoWay = &CYapfAnyDepotRail1::stFindNearestDepotTwoWay;
 
 	// check if non-default YAPF type needed
-	if (_settings.pf.forbid_90_deg) {
+	if (_settings_game.pf.forbid_90_deg) {
 		pfnFindNearestDepotTwoWay = &CYapfAnyDepotRail2::stFindNearestDepotTwoWay; // Trackdir, forbid 90-deg
 	}
 
--- a/src/yapf/yapf_road.cpp	Thu May 29 12:52:24 2008 +0000
+++ b/src/yapf/yapf_road.cpp	Thu May 29 15:56:32 2008 +0000
@@ -407,7 +407,7 @@
 	PfnChooseRoadTrack pfnChooseRoadTrack = &CYapfRoad2::stChooseRoadTrack; // default: ExitDir, allow 90-deg
 
 	// check if non-default YAPF type should be used
-	if (_settings.pf.yapf.disable_node_optimization)
+	if (_settings_game.pf.yapf.disable_node_optimization)
 		pfnChooseRoadTrack = &CYapfRoad1::stChooseRoadTrack; // Trackdir, allow 90-deg
 
 	Trackdir td_ret = pfnChooseRoadTrack(v, tile, enterdir);
@@ -421,7 +421,7 @@
 	PfnDistanceToTile pfnDistanceToTile = &CYapfRoad2::stDistanceToTile; // default: ExitDir, allow 90-deg
 
 	// check if non-default YAPF type should be used
-	if (_settings.pf.yapf.disable_node_optimization)
+	if (_settings_game.pf.yapf.disable_node_optimization)
 		pfnDistanceToTile = &CYapfRoad1::stDistanceToTile; // Trackdir, allow 90-deg
 
 	// measure distance in YAPF units
@@ -450,7 +450,7 @@
 	PfnFindNearestDepot pfnFindNearestDepot = &CYapfRoadAnyDepot2::stFindNearestDepot;
 
 	// check if non-default YAPF type should be used
-	if (_settings.pf.yapf.disable_node_optimization)
+	if (_settings_game.pf.yapf.disable_node_optimization)
 		pfnFindNearestDepot = &CYapfRoadAnyDepot1::stFindNearestDepot; // Trackdir, allow 90-deg
 
 	Depot* ret = pfnFindNearestDepot(v, tile, trackdir);
--- a/src/yapf/yapf_ship.cpp	Thu May 29 12:52:24 2008 +0000
+++ b/src/yapf/yapf_ship.cpp	Thu May 29 15:56:32 2008 +0000
@@ -154,9 +154,9 @@
 	PfnChooseShipTrack pfnChooseShipTrack = CYapfShip2::ChooseShipTrack; // default: ExitDir, allow 90-deg
 
 	// check if non-default YAPF type needed
-	if (_settings.pf.forbid_90_deg)
+	if (_settings_game.pf.forbid_90_deg)
 		pfnChooseShipTrack = &CYapfShip3::ChooseShipTrack; // Trackdir, forbid 90-deg
-	else if (_settings.pf.yapf.disable_node_optimization)
+	else if (_settings_game.pf.yapf.disable_node_optimization)
 		pfnChooseShipTrack = &CYapfShip1::ChooseShipTrack; // Trackdir, allow 90-deg
 
 	Trackdir td_ret = pfnChooseShipTrack(v, tile, enterdir, tracks);