changeset 10571:b6779abf2e96 draft

(svn r14828) -Codechange: move most of save/load-specific code to separate files
author smatz <smatz@openttd.org>
date Sun, 04 Jan 2009 15:32:25 +0000
parents 4ab8ac10807c
children 05dce659b5b0
files projects/openttd_vs80.vcproj projects/openttd_vs90.vcproj source.list src/ai/default/default.cpp src/ai/default/default.h src/ai/trolly/trolly.h src/aircraft.h src/aircraft_cmd.cpp src/animated_tile.cpp src/autoreplace.cpp src/cargopacket.cpp src/cheat.cpp src/cheat_gui.cpp src/company_cmd.cpp src/company_manager_face.h src/console_cmds.cpp src/date.cpp src/depot.cpp src/economy.cpp src/economy_func.h src/effectvehicle.cpp src/engine.cpp src/gamelog.cpp src/gamelog_internal.h src/genworld.cpp src/group_cmd.cpp src/heightmap.cpp src/industry_cmd.cpp src/misc.cpp src/misc_gui.cpp src/network/network_client.cpp src/network/network_server.cpp src/newgrf.h src/newgrf_config.cpp src/newgrf_house.cpp src/newgrf_house.h src/newgrf_station.h src/oldloader.cpp src/openttd.cpp src/order_base.h src/order_cmd.cpp src/saveload.cpp src/saveload.h src/saveload/afterload.cpp src/saveload/ai_sl.cpp src/saveload/animated_tile_sl.cpp src/saveload/autoreplace_sl.cpp src/saveload/cargopacket_sl.cpp src/saveload/cheat_sl.cpp src/saveload/company_sl.cpp src/saveload/depot_sl.cpp src/saveload/economy_sl.cpp src/saveload/engine_sl.cpp src/saveload/gamelog_sl.cpp src/saveload/group_sl.cpp src/saveload/industry_sl.cpp src/saveload/map_sl.cpp src/saveload/misc_sl.cpp src/saveload/newgrf_sl.cpp src/saveload/oldloader.cpp src/saveload/order_sl.cpp src/saveload/saveload.cpp src/saveload/saveload.h src/saveload/saveload_internal.h src/saveload/signs_sl.cpp src/saveload/station_sl.cpp src/saveload/strings_sl.cpp src/saveload/subsidy_sl.cpp src/saveload/town_sl.cpp src/saveload/vehicle_sl.cpp src/saveload/waypoint_sl.cpp src/screenshot.cpp src/settings.cpp src/settings_internal.h src/signs.cpp src/signs_base.h src/station.cpp src/station_cmd.cpp src/station_func.h src/strings.cpp src/strings_func.h src/town.h src/town_cmd.cpp src/train.h src/train_cmd.cpp src/variables.h src/vehicle.cpp src/vehicle_base.h src/viewport.cpp src/water.h src/water_cmd.cpp src/waypoint.cpp src/waypoint.h src/win32.cpp
diffstat 94 files changed, 9226 insertions(+), 8648 deletions(-) [+]
line wrap: on
line diff
--- a/projects/openttd_vs80.vcproj
+++ b/projects/openttd_vs80.vcproj
@@ -648,10 +648,6 @@
 				>
 			</File>
 			<File
-				RelativePath=".\..\src\oldloader.cpp"
-				>
-			</File>
-			<File
 				RelativePath=".\..\src\oldpool.cpp"
 				>
 			</File>
@@ -692,10 +688,6 @@
 				>
 			</File>
 			<File
-				RelativePath=".\..\src\saveload.cpp"
-				>
-			</File>
-			<File
 				RelativePath=".\..\src\screenshot.cpp"
 				>
 			</File>
@@ -1044,6 +1036,10 @@
 				>
 			</File>
 			<File
+				RelativePath=".\..\src\gamelog_internal.h"
+				>
+			</File>
+			<File
 				RelativePath=".\..\src\genworld.h"
 				>
 			</File>
@@ -1360,10 +1356,6 @@
 				>
 			</File>
 			<File
-				RelativePath=".\..\src\saveload.h"
-				>
-			</File>
-			<File
 				RelativePath=".\..\src\screenshot.h"
 				>
 			</File>
@@ -2009,6 +2001,122 @@
 			</File>
 		</Filter>
 		<Filter
+			Name="Save/Load handlers"
+			>
+			<File
+				RelativePath=".\..\src\saveload\afterload.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\..\src\saveload\ai_sl.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\..\src\saveload\animated_tile_sl.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\..\src\saveload\autoreplace_sl.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\..\src\saveload\cargopacket_sl.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\..\src\saveload\cheat_sl.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\..\src\saveload\company_sl.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\..\src\saveload\depot_sl.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\..\src\saveload\economy_sl.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\..\src\saveload\engine_sl.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\..\src\saveload\gamelog_sl.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\..\src\saveload\group_sl.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\..\src\saveload\industry_sl.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\..\src\saveload\map_sl.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\..\src\saveload\misc_sl.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\..\src\saveload\newgrf_sl.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\..\src\saveload\oldloader.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\..\src\saveload\order_sl.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\..\src\saveload\saveload.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\..\src\saveload\saveload.h"
+				>
+			</File>
+			<File
+				RelativePath=".\..\src\saveload\saveload_internal.h"
+				>
+			</File>
+			<File
+				RelativePath=".\..\src\saveload\signs_sl.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\..\src\saveload\station_sl.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\..\src\saveload\strings_sl.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\..\src\saveload\subsidy_sl.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\..\src\saveload\town_sl.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\..\src\saveload\vehicle_sl.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\..\src\saveload\waypoint_sl.cpp"
+				>
+			</File>
+		</Filter>
+		<Filter
 			Name="Tables"
 			>
 			<File
--- a/projects/openttd_vs90.vcproj
+++ b/projects/openttd_vs90.vcproj
@@ -645,10 +645,6 @@
 				>
 			</File>
 			<File
-				RelativePath=".\..\src\oldloader.cpp"
-				>
-			</File>
-			<File
 				RelativePath=".\..\src\oldpool.cpp"
 				>
 			</File>
@@ -689,10 +685,6 @@
 				>
 			</File>
 			<File
-				RelativePath=".\..\src\saveload.cpp"
-				>
-			</File>
-			<File
 				RelativePath=".\..\src\screenshot.cpp"
 				>
 			</File>
@@ -1041,6 +1033,10 @@
 				>
 			</File>
 			<File
+				RelativePath=".\..\src\gamelog_internal.h"
+				>
+			</File>
+			<File
 				RelativePath=".\..\src\genworld.h"
 				>
 			</File>
@@ -1357,10 +1353,6 @@
 				>
 			</File>
 			<File
-				RelativePath=".\..\src\saveload.h"
-				>
-			</File>
-			<File
 				RelativePath=".\..\src\screenshot.h"
 				>
 			</File>
@@ -2006,6 +1998,122 @@
 			</File>
 		</Filter>
 		<Filter
+			Name="Save/Load handlers"
+			>
+			<File
+				RelativePath=".\..\src\saveload\afterload.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\..\src\saveload\ai_sl.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\..\src\saveload\animated_tile_sl.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\..\src\saveload\autoreplace_sl.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\..\src\saveload\cargopacket_sl.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\..\src\saveload\cheat_sl.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\..\src\saveload\company_sl.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\..\src\saveload\depot_sl.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\..\src\saveload\economy_sl.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\..\src\saveload\engine_sl.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\..\src\saveload\gamelog_sl.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\..\src\saveload\group_sl.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\..\src\saveload\industry_sl.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\..\src\saveload\map_sl.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\..\src\saveload\misc_sl.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\..\src\saveload\newgrf_sl.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\..\src\saveload\oldloader.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\..\src\saveload\order_sl.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\..\src\saveload\saveload.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\..\src\saveload\saveload.h"
+				>
+			</File>
+			<File
+				RelativePath=".\..\src\saveload\saveload_internal.h"
+				>
+			</File>
+			<File
+				RelativePath=".\..\src\saveload\signs_sl.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\..\src\saveload\station_sl.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\..\src\saveload\strings_sl.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\..\src\saveload\subsidy_sl.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\..\src\saveload\town_sl.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\..\src\saveload\vehicle_sl.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\..\src\saveload\waypoint_sl.cpp"
+				>
+			</File>
+		</Filter>
+		<Filter
 			Name="Tables"
 			>
 			<File
--- a/source.list
+++ b/source.list
@@ -50,7 +50,6 @@
 network/network_server.cpp
 network/network_udp.cpp
 npf.cpp
-oldloader.cpp
 oldpool.cpp
 openttd.cpp
 os_timer.cpp
@@ -66,7 +65,6 @@
 rail.cpp
 rev.cpp
 road.cpp
-saveload.cpp
 screenshot.cpp
 #if SDL
 	sdl.cpp
@@ -193,6 +191,7 @@
 fontcache.h
 functions.h
 gamelog.h
+gamelog_internal.h
 genworld.h
 gfx_func.h
 gfx_type.h
@@ -272,7 +271,6 @@
 road_internal.h
 road_type.h
 roadveh.h
-saveload.h
 screenshot.h
 sdl.h
 sound/sdl_s.h
@@ -452,6 +450,36 @@
 unmovable_cmd.cpp
 water_cmd.cpp
 
+# Save/Load handlers
+saveload/afterload.cpp
+saveload/ai_sl.cpp
+saveload/animated_tile_sl.cpp
+saveload/autoreplace_sl.cpp
+saveload/cargopacket_sl.cpp
+saveload/cheat_sl.cpp
+saveload/company_sl.cpp
+saveload/depot_sl.cpp
+saveload/economy_sl.cpp
+saveload/engine_sl.cpp
+saveload/gamelog_sl.cpp
+saveload/group_sl.cpp
+saveload/industry_sl.cpp
+saveload/map_sl.cpp
+saveload/misc_sl.cpp
+saveload/newgrf_sl.cpp
+saveload/oldloader.cpp
+saveload/order_sl.cpp
+saveload/saveload.cpp
+saveload/saveload.h
+saveload/saveload_internal.h
+saveload/signs_sl.cpp
+saveload/station_sl.cpp
+saveload/strings_sl.cpp
+saveload/subsidy_sl.cpp
+saveload/town_sl.cpp
+saveload/vehicle_sl.cpp
+saveload/waypoint_sl.cpp
+
 # Tables
 table/ai_rail.h
 table/animcursors.h
--- a/src/ai/default/default.cpp
+++ b/src/ai/default/default.cpp
@@ -25,7 +25,6 @@
 #include "../../window_func.h"
 #include "../../vehicle_func.h"
 #include "../../functions.h"
-#include "../../saveload.h"
 #include "../../company_func.h"
 #include "../../company_base.h"
 #include "../../settings_type.h"
@@ -4027,74 +4026,3 @@
 
 	_ai_actions[_companies_ai[c->index].state](c);
 }
-
-
-static const SaveLoad _company_ai_desc[] = {
-	    SLE_VAR(CompanyAI, state,             SLE_UINT8),
-	    SLE_VAR(CompanyAI, tick,              SLE_UINT8),
-	SLE_CONDVAR(CompanyAI, state_counter,     SLE_FILE_U16 | SLE_VAR_U32,  0, 12),
-	SLE_CONDVAR(CompanyAI, state_counter,     SLE_UINT32,                 13, SL_MAX_VERSION),
-	    SLE_VAR(CompanyAI, timeout_counter,   SLE_UINT16),
-
-	    SLE_VAR(CompanyAI, state_mode,        SLE_UINT8),
-	    SLE_VAR(CompanyAI, banned_tile_count, SLE_UINT8),
-	    SLE_VAR(CompanyAI, railtype_to_use,   SLE_UINT8),
-
-	    SLE_VAR(CompanyAI, cargo_type,        SLE_UINT8),
-	    SLE_VAR(CompanyAI, num_wagons,        SLE_UINT8),
-	    SLE_VAR(CompanyAI, build_kind,        SLE_UINT8),
-	    SLE_VAR(CompanyAI, num_build_rec,     SLE_UINT8),
-	    SLE_VAR(CompanyAI, num_loco_to_build, SLE_UINT8),
-	    SLE_VAR(CompanyAI, num_want_fullload, SLE_UINT8),
-
-	    SLE_VAR(CompanyAI, route_type_mask,   SLE_UINT8),
-
-	SLE_CONDVAR(CompanyAI, start_tile_a,      SLE_FILE_U16 | SLE_VAR_U32,  0,  5),
-	SLE_CONDVAR(CompanyAI, start_tile_a,      SLE_UINT32,                  6, SL_MAX_VERSION),
-	SLE_CONDVAR(CompanyAI, cur_tile_a,        SLE_FILE_U16 | SLE_VAR_U32,  0,  5),
-	SLE_CONDVAR(CompanyAI, cur_tile_a,        SLE_UINT32,                  6, SL_MAX_VERSION),
-	    SLE_VAR(CompanyAI, start_dir_a,       SLE_UINT8),
-	    SLE_VAR(CompanyAI, cur_dir_a,         SLE_UINT8),
-
-	SLE_CONDVAR(CompanyAI, start_tile_b,      SLE_FILE_U16 | SLE_VAR_U32,  0,  5),
-	SLE_CONDVAR(CompanyAI, start_tile_b,      SLE_UINT32,                  6, SL_MAX_VERSION),
-	SLE_CONDVAR(CompanyAI, cur_tile_b,        SLE_FILE_U16 | SLE_VAR_U32,  0,  5),
-	SLE_CONDVAR(CompanyAI, cur_tile_b,        SLE_UINT32,                  6, SL_MAX_VERSION),
-	    SLE_VAR(CompanyAI, start_dir_b,       SLE_UINT8),
-	    SLE_VAR(CompanyAI, cur_dir_b,         SLE_UINT8),
-
-	    SLE_REF(CompanyAI, cur_veh,           REF_VEHICLE),
-
-	    SLE_ARR(CompanyAI, wagon_list,        SLE_UINT16, 9),
-	    SLE_ARR(CompanyAI, order_list_blocks, SLE_UINT8, 20),
-	    SLE_ARR(CompanyAI, banned_tiles,      SLE_UINT16, 16),
-
-	SLE_CONDNULL(64, 2, SL_MAX_VERSION),
-	SLE_END()
-};
-
-static const SaveLoad _company_ai_build_rec_desc[] = {
-	SLE_CONDVAR(AiBuildRec, spec_tile,         SLE_FILE_U16 | SLE_VAR_U32, 0, 5),
-	SLE_CONDVAR(AiBuildRec, spec_tile,         SLE_UINT32,                 6, SL_MAX_VERSION),
-	SLE_CONDVAR(AiBuildRec, use_tile,          SLE_FILE_U16 | SLE_VAR_U32, 0, 5),
-	SLE_CONDVAR(AiBuildRec, use_tile,          SLE_UINT32,                 6, SL_MAX_VERSION),
-	    SLE_VAR(AiBuildRec, rand_rng,          SLE_UINT8),
-	    SLE_VAR(AiBuildRec, cur_building_rule, SLE_UINT8),
-	    SLE_VAR(AiBuildRec, unk6,              SLE_UINT8),
-	    SLE_VAR(AiBuildRec, unk7,              SLE_UINT8),
-	    SLE_VAR(AiBuildRec, buildcmd_a,        SLE_UINT8),
-	    SLE_VAR(AiBuildRec, buildcmd_b,        SLE_UINT8),
-	    SLE_VAR(AiBuildRec, direction,         SLE_UINT8),
-	    SLE_VAR(AiBuildRec, cargo,             SLE_UINT8),
-	SLE_END()
-};
-
-
-void SaveLoad_AI(CompanyID company)
-{
-	CompanyAI *cai = &_companies_ai[company];
-	SlObject(cai, _company_ai_desc);
-	for (int i = 0; i != cai->num_build_rec; i++) {
-		SlObject(&cai->src + i, _company_ai_build_rec_desc);
-	}
-}
--- a/src/ai/default/default.h
+++ b/src/ai/default/default.h
@@ -10,7 +10,6 @@
 #include "../../rail_type.h"
 
 void AiDoGameLoop(Company *c);
-void SaveLoad_AI(CompanyID company);
 
 struct AiBuildRec {
 	TileIndex spec_tile;
--- a/src/ai/trolly/trolly.h
+++ b/src/ai/trolly/trolly.h
@@ -10,6 +10,7 @@
 #include "../../vehicle_type.h"
 #include "../../date_type.h"
 #include "../../engine_type.h"
+#include "../../direction_type.h"
 
 /*
  * These defines can be altered to change the behavoir of the AI
--- a/src/aircraft.h
+++ b/src/aircraft.h
@@ -99,6 +99,11 @@
  */
 void UpdateAircraftCache(Vehicle *v);
 
+void AircraftLeaveHangar(Vehicle *v);
+void AircraftNextAirportPos_and_Order(Vehicle *v);
+void SetAircraftPosition(Vehicle *v, int x, int y, int z);
+byte GetAircraftFlyingAltitude(const Vehicle *v);
+
 /**
  * This class 'wraps' Vehicle; you do not actually instantiate this class.
  * You create a Vehicle using AllocateVehicle, so it is added to the pool
--- a/src/aircraft_cmd.cpp
+++ b/src/aircraft_cmd.cpp
@@ -82,9 +82,6 @@
 static bool AirportFindFreeHelipad(Vehicle *v, const AirportFTAClass *apc);
 static void CrashAirplane(Vehicle *v);
 
-void AircraftNextAirportPos_and_Order(Vehicle *v);
-static byte GetAircraftFlyingAltitude(const Vehicle *v);
-
 static const SpriteID _aircraft_sprite[] = {
 	0x0EB5, 0x0EBD, 0x0EC5, 0x0ECD,
 	0x0ED5, 0x0EDD, 0x0E9D, 0x0EA5,
@@ -727,7 +724,7 @@
 	EndVehicleMove(u);
 }
 
-static void SetAircraftPosition(Vehicle *v, int x, int y, int z)
+void SetAircraftPosition(Vehicle *v, int x, int y, int z)
 {
 	v->x_pos = x;
 	v->y_pos = y;
@@ -883,7 +880,7 @@
  * @param v The vehicle. Should be an aircraft
  * @returns Altitude in pixel units
  */
-static byte GetAircraftFlyingAltitude(const Vehicle *v)
+byte GetAircraftFlyingAltitude(const Vehicle *v)
 {
 	/* Make sure Aircraft fly no lower so that they don't conduct
 	 * CFITs (controlled flight into terrain)
@@ -1433,7 +1430,7 @@
 	v->u.air.pos = v->u.air.previous_pos = AircraftGetEntryPoint(v, apc);
 }
 
-static void AircraftLeaveHangar(Vehicle *v)
+void AircraftLeaveHangar(Vehicle *v)
 {
 	v->cur_speed = 0;
 	v->subspeed = 0;
@@ -2096,42 +2093,6 @@
 	return st->airport_tile == INVALID_TILE ? NULL : st;
 }
 
-/** need to be called to load aircraft from old version */
-void UpdateOldAircraft()
-{
-	/* set airport_flags to 0 for all airports just to be sure */
-	Station *st;
-	FOR_ALL_STATIONS(st) {
-		st->airport_flags = 0; // reset airport
-	}
-
-	Vehicle *v_oldstyle;
-	FOR_ALL_VEHICLES(v_oldstyle) {
-	/* airplane has another vehicle with subtype 4 (shadow), helicopter also has 3 (rotor)
-	 * skip those */
-		if (v_oldstyle->type == VEH_AIRCRAFT && IsNormalAircraft(v_oldstyle)) {
-			/* airplane in terminal stopped doesn't hurt anyone, so goto next */
-			if (v_oldstyle->vehstatus & VS_STOPPED && v_oldstyle->u.air.state == 0) {
-				v_oldstyle->u.air.state = HANGAR;
-				continue;
-			}
-
-			AircraftLeaveHangar(v_oldstyle); // make airplane visible if it was in a depot for example
-			v_oldstyle->vehstatus &= ~VS_STOPPED; // make airplane moving
-			v_oldstyle->u.air.state = FLYING;
-			AircraftNextAirportPos_and_Order(v_oldstyle); // move it to the entry point of the airport
-			GetNewVehiclePosResult gp = GetNewVehiclePos(v_oldstyle);
-			v_oldstyle->tile = 0; // aircraft in air is tile=0
-
-			/* correct speed of helicopter-rotors */
-			if (v_oldstyle->subtype == AIR_HELICOPTER) v_oldstyle->Next()->Next()->cur_speed = 32;
-
-			/* set new position x,y,z */
-			SetAircraftPosition(v_oldstyle, gp.x, gp.y, GetAircraftFlyingAltitude(v_oldstyle));
-		}
-	}
-}
-
 /**
  * Updates the status of the Aircraft heading or in the station
  * @param st Station been updated
--- a/src/animated_tile.cpp
+++ b/src/animated_tile.cpp
@@ -4,7 +4,6 @@
 
 #include "stdafx.h"
 #include "openttd.h"
-#include "saveload.h"
 #include "landscape.h"
 #include "core/alloc_func.hpp"
 #include "functions.h"
@@ -14,7 +13,7 @@
 /** The number of animated tiles in the current state. */
 uint _animated_tile_count = 0;
 /** The number of slots for animated tiles allocated currently. */
-static uint _animated_tile_allocated = 0;
+uint _animated_tile_allocated = 0;
 
 /**
  * Removes the given tile from the animated tile table.
@@ -90,46 +89,3 @@
 	_animated_tile_count = 0;
 	_animated_tile_allocated = 256;
 }
-
-/**
- * Save the ANIT chunk.
- */
-static void Save_ANIT()
-{
-	SlSetLength(_animated_tile_count * sizeof(*_animated_tile_list));
-	SlArray(_animated_tile_list, _animated_tile_count, SLE_UINT32);
-}
-
-/**
- * Load the ANIT chunk; the chunk containing the animated tiles.
- */
-static void Load_ANIT()
-{
-	/* Before version 80 we did NOT have a variable length animated tile table */
-	if (CheckSavegameVersion(80)) {
-		/* In pre version 6, we has 16bit per tile, now we have 32bit per tile, convert it ;) */
-		SlArray(_animated_tile_list, 256, CheckSavegameVersion(6) ? (SLE_FILE_U16 | SLE_VAR_U32) : SLE_UINT32);
-
-		for (_animated_tile_count = 0; _animated_tile_count < 256; _animated_tile_count++) {
-			if (_animated_tile_list[_animated_tile_count] == 0) break;
-		}
-		return;
-	}
-
-	_animated_tile_count = (uint)SlGetFieldLength() / sizeof(*_animated_tile_list);
-
-	/* Determine a nice rounded size for the amount of allocated tiles */
-	_animated_tile_allocated = 256;
-	while (_animated_tile_allocated < _animated_tile_count) _animated_tile_allocated *= 2;
-
-	_animated_tile_list = ReallocT<TileIndex>(_animated_tile_list, _animated_tile_allocated);
-	SlArray(_animated_tile_list, _animated_tile_count, SLE_UINT32);
-}
-
-/**
- * "Definition" imported by the saveload code to be able to load and save
- * the animated tile table.
- */
-extern const ChunkHandler _animated_tile_chunk_handlers[] = {
-	{ 'ANIT', Save_ANIT, Load_ANIT, CH_RIFF | CH_LAST},
-};
--- a/src/autoreplace.cpp
+++ b/src/autoreplace.cpp
@@ -6,7 +6,6 @@
 #include "openttd.h"
 #include "debug.h"
 #include "command_func.h"
-#include "saveload.h"
 #include "group.h"
 #include "autoreplace_base.h"
 #include "oldpool_func.h"
@@ -102,46 +101,6 @@
 	return CMD_ERROR;
 }
 
-static const SaveLoad _engine_renew_desc[] = {
-	    SLE_VAR(EngineRenew, from,     SLE_UINT16),
-	    SLE_VAR(EngineRenew, to,       SLE_UINT16),
-
-	    SLE_REF(EngineRenew, next,     REF_ENGINE_RENEWS),
-	SLE_CONDVAR(EngineRenew, group_id, SLE_UINT16, 60, SL_MAX_VERSION),
-	SLE_END()
-};
-
-static void Save_ERNW()
-{
-	EngineRenew *er;
-
-	FOR_ALL_ENGINE_RENEWS(er) {
-		SlSetArrayIndex(er->index);
-		SlObject(er, _engine_renew_desc);
-	}
-}
-
-static void Load_ERNW()
-{
-	int index;
-
-	while ((index = SlIterateArray()) != -1) {
-		EngineRenew *er = new (index) EngineRenew();
-		SlObject(er, _engine_renew_desc);
-
-		/* Advanced vehicle lists, ungrouped vehicles got added */
-		if (CheckSavegameVersion(60)) {
-			er->group_id = ALL_GROUP;
-		} else if (CheckSavegameVersion(71)) {
-			if (er->group_id == DEFAULT_GROUP) er->group_id = ALL_GROUP;
-		}
-	}
-}
-
-extern const ChunkHandler _autoreplace_chunk_handlers[] = {
-	{ 'ERNW', Save_ERNW,     Load_ERNW,     CH_ARRAY | CH_LAST},
-};
-
 void InitializeEngineRenews()
 {
 	/* Clean the engine renew pool and create 1 block in it */
--- a/src/cargopacket.cpp
+++ b/src/cargopacket.cpp
@@ -3,10 +3,8 @@
 /** @file cargopacket.cpp Implementation of the cargo packets */
 
 #include "stdafx.h"
-#include "openttd.h"
 #include "station_base.h"
 #include "cargopacket.h"
-#include "saveload.h"
 #include "oldpool_func.h"
 
 /* Initialize the cargopacket-pool */
@@ -43,42 +41,6 @@
 	return this->source_xy == cp->source_xy && this->days_in_transit == cp->days_in_transit && this->paid_for == cp->paid_for;
 }
 
-static const SaveLoad _cargopacket_desc[] = {
-	SLE_VAR(CargoPacket, source,          SLE_UINT16),
-	SLE_VAR(CargoPacket, source_xy,       SLE_UINT32),
-	SLE_VAR(CargoPacket, loaded_at_xy,    SLE_UINT32),
-	SLE_VAR(CargoPacket, count,           SLE_UINT16),
-	SLE_VAR(CargoPacket, days_in_transit, SLE_UINT8),
-	SLE_VAR(CargoPacket, feeder_share,    SLE_INT64),
-	SLE_VAR(CargoPacket, paid_for,        SLE_BOOL),
-
-	SLE_END()
-};
-
-static void Save_CAPA()
-{
-	CargoPacket *cp;
-
-	FOR_ALL_CARGOPACKETS(cp) {
-		SlSetArrayIndex(cp->index);
-		SlObject(cp, _cargopacket_desc);
-	}
-}
-
-static void Load_CAPA()
-{
-	int index;
-
-	while ((index = SlIterateArray()) != -1) {
-		CargoPacket *cp = new (index) CargoPacket();
-		SlObject(cp, _cargopacket_desc);
-	}
-}
-
-extern const ChunkHandler _cargopacket_chunk_handlers[] = {
-	{ 'CAPA', Save_CAPA, Load_CAPA, CH_ARRAY | CH_LAST},
-};
-
 /*
  *
  * Cargo list implementation
--- a/src/cheat.cpp
+++ b/src/cheat.cpp
@@ -3,7 +3,6 @@
 /** @file cheat.cpp Handling (loading/saving/initializing) of cheats. */
 
 #include "stdafx.h"
-#include "saveload.h"
 #include "cheat_type.h"
 
 Cheats _cheats;
@@ -13,31 +12,6 @@
 	memset(&_cheats, 0, sizeof(Cheats));
 }
 
-static void Save_CHTS()
-{
-	/* Cannot use lengthof because _cheats is of type Cheats, not Cheat */
-	byte count = sizeof(_cheats) / sizeof(Cheat);
-	Cheat *cht = (Cheat*) &_cheats;
-	Cheat *cht_last = &cht[count];
-
-	SlSetLength(count * 2);
-	for (; cht != cht_last; cht++) {
-		SlWriteByte(cht->been_used);
-		SlWriteByte(cht->value);
-	}
-}
-
-static void Load_CHTS()
-{
-	Cheat *cht = (Cheat*)&_cheats;
-	size_t count = SlGetFieldLength() / 2;
-
-	for (uint i = 0; i < count; i++) {
-		cht[i].been_used = (SlReadByte() != 0);
-		cht[i].value     = (SlReadByte() != 0);
-	}
-}
-
 bool CheatHasBeenUsed()
 {
 	/* Cannot use lengthof because _cheats is of type Cheats, not Cheat */
@@ -50,8 +24,3 @@
 
 	return false;
 }
-
-
-extern const ChunkHandler _cheat_chunk_handlers[] = {
-	{ 'CHTS', Save_CHTS,     Load_CHTS,     CH_RIFF | CH_LAST}
-};
--- a/src/cheat_gui.cpp
+++ b/src/cheat_gui.cpp
@@ -10,7 +10,7 @@
 #include "company_func.h"
 #include "gfx_func.h"
 #include "date_func.h"
-#include "saveload.h"
+#include "saveload/saveload.h"
 #include "window_gui.h"
 #include "newgrf.h"
 #include "settings_type.h"
--- a/src/company_cmd.cpp
+++ b/src/company_cmd.cpp
@@ -10,7 +10,6 @@
 #include "company_gui.h"
 #include "town.h"
 #include "news_func.h"
-#include "saveload.h"
 #include "command_func.h"
 #include "network/network.h"
 #include "network/network_func.h"
@@ -111,74 +110,6 @@
 }
 
 /**
- * Converts an old company manager's face format to the new company manager's face format
- *
- * Meaning of the bits in the old face (some bits are used in several times):
- * - 4 and 5: chin
- * - 6 to 9: eyebrows
- * - 10 to 13: nose
- * - 13 to 15: lips (also moustache for males)
- * - 16 to 19: hair
- * - 20 to 22: eye color
- * - 20 to 27: tie, ear rings etc.
- * - 28 to 30: glasses
- * - 19, 26 and 27: race (bit 27 set and bit 19 equal to bit 26 = black, otherwise white)
- * - 31: gender (0 = male, 1 = female)
- *
- * @param face the face in the old format
- * @return the face in the new format
- */
-CompanyManagerFace ConvertFromOldCompanyManagerFace(uint32 face)
-{
-	CompanyManagerFace cmf = 0;
-	GenderEthnicity ge = GE_WM;
-
-	if (HasBit(face, 31)) SetBit(ge, GENDER_FEMALE);
-	if (HasBit(face, 27) && (HasBit(face, 26) == HasBit(face, 19))) SetBit(ge, ETHNICITY_BLACK);
-
-	SetCompanyManagerFaceBits(cmf, CMFV_GEN_ETHN,    ge, ge);
-	SetCompanyManagerFaceBits(cmf, CMFV_HAS_GLASSES, ge, GB(face, 28, 3) <= 1);
-	SetCompanyManagerFaceBits(cmf, CMFV_EYE_COLOUR,  ge, HasBit(ge, ETHNICITY_BLACK) ? 0 : ClampU(GB(face, 20, 3), 5, 7) - 5);
-	SetCompanyManagerFaceBits(cmf, CMFV_CHIN,        ge, ScaleCompanyManagerFaceValue(CMFV_CHIN,     ge, GB(face,  4, 2)));
-	SetCompanyManagerFaceBits(cmf, CMFV_EYEBROWS,    ge, ScaleCompanyManagerFaceValue(CMFV_EYEBROWS, ge, GB(face,  6, 4)));
-	SetCompanyManagerFaceBits(cmf, CMFV_HAIR,        ge, ScaleCompanyManagerFaceValue(CMFV_HAIR,     ge, GB(face, 16, 4)));
-	SetCompanyManagerFaceBits(cmf, CMFV_JACKET,      ge, ScaleCompanyManagerFaceValue(CMFV_JACKET,   ge, GB(face, 20, 2)));
-	SetCompanyManagerFaceBits(cmf, CMFV_COLLAR,      ge, ScaleCompanyManagerFaceValue(CMFV_COLLAR,   ge, GB(face, 22, 2)));
-	SetCompanyManagerFaceBits(cmf, CMFV_GLASSES,     ge, GB(face, 28, 1));
-
-	uint lips = GB(face, 10, 4);
-	if (!HasBit(ge, GENDER_FEMALE) && lips < 4) {
-		SetCompanyManagerFaceBits(cmf, CMFV_HAS_MOUSTACHE, ge, true);
-		SetCompanyManagerFaceBits(cmf, CMFV_MOUSTACHE,     ge, max(lips, 1U) - 1);
-	} else {
-		if (!HasBit(ge, GENDER_FEMALE)) {
-			lips = lips * 15 / 16;
-			lips -= 3;
-			if (HasBit(ge, ETHNICITY_BLACK) && lips > 8) lips = 0;
-		} else {
-			lips = ScaleCompanyManagerFaceValue(CMFV_LIPS, ge, lips);
-		}
-		SetCompanyManagerFaceBits(cmf, CMFV_LIPS, ge, lips);
-
-		uint nose = GB(face, 13, 3);
-		if (ge == GE_WF) {
-			nose = (nose * 3 >> 3) * 3 >> 2; // There is 'hole' in the nose sprites for females
-		} else {
-			nose = ScaleCompanyManagerFaceValue(CMFV_NOSE, ge, nose);
-		}
-		SetCompanyManagerFaceBits(cmf, CMFV_NOSE, ge, nose);
-	}
-
-	uint tie_earring = GB(face, 24, 4);
-	if (!HasBit(ge, GENDER_FEMALE) || tie_earring < 3) { // Not all females have an earring
-		if (HasBit(ge, GENDER_FEMALE)) SetCompanyManagerFaceBits(cmf, CMFV_HAS_TIE_EARRING, ge, true);
-		SetCompanyManagerFaceBits(cmf, CMFV_TIE_EARRING, ge, HasBit(ge, GENDER_FEMALE) ? tie_earring : ScaleCompanyManagerFaceValue(CMFV_TIE_EARRING, ge, tie_earring / 2));
-	}
-
-	return cmf;
-}
-
-/**
  * Checks whether a company manager's face is a valid encoding.
  * Unused bits are not enforced to be 0.
  * @param cmf the fact to check
@@ -936,159 +867,3 @@
 
 	return CommandCost();
 }
-
-/* Save/load of companies */
-static const SaveLoad _company_desc[] = {
-	    SLE_VAR(Company, name_2,          SLE_UINT32),
-	    SLE_VAR(Company, name_1,          SLE_STRINGID),
-	SLE_CONDSTR(Company, name,            SLE_STR, 0,                       84, SL_MAX_VERSION),
-
-	    SLE_VAR(Company, president_name_1, SLE_UINT16),
-	    SLE_VAR(Company, president_name_2, SLE_UINT32),
-	SLE_CONDSTR(Company, president_name,  SLE_STR, 0,                       84, SL_MAX_VERSION),
-
-	    SLE_VAR(Company, face,            SLE_UINT32),
-
-	/* money was changed to a 64 bit field in savegame version 1. */
-	SLE_CONDVAR(Company, money,                 SLE_VAR_I64 | SLE_FILE_I32,  0, 0),
-	SLE_CONDVAR(Company, money,                 SLE_INT64,                   1, SL_MAX_VERSION),
-
-	SLE_CONDVAR(Company, current_loan,          SLE_VAR_I64 | SLE_FILE_I32,  0, 64),
-	SLE_CONDVAR(Company, current_loan,          SLE_INT64,                  65, SL_MAX_VERSION),
-
-	    SLE_VAR(Company, colour,                SLE_UINT8),
-	    SLE_VAR(Company, money_fraction,        SLE_UINT8),
-	SLE_CONDVAR(Company, avail_railtypes,       SLE_UINT8,                   0, 57),
-	    SLE_VAR(Company, block_preview,         SLE_UINT8),
-
-	SLE_CONDVAR(Company, cargo_types,           SLE_FILE_U16 | SLE_VAR_U32,  0, 93),
-	SLE_CONDVAR(Company, cargo_types,           SLE_UINT32,                 94, SL_MAX_VERSION),
-	SLE_CONDVAR(Company, location_of_HQ,        SLE_FILE_U16 | SLE_VAR_U32,  0,  5),
-	SLE_CONDVAR(Company, location_of_HQ,        SLE_UINT32,                  6, SL_MAX_VERSION),
-	SLE_CONDVAR(Company, last_build_coordinate, SLE_FILE_U16 | SLE_VAR_U32,  0,  5),
-	SLE_CONDVAR(Company, last_build_coordinate, SLE_UINT32,                  6, SL_MAX_VERSION),
-	SLE_CONDVAR(Company, inaugurated_year,      SLE_FILE_U8  | SLE_VAR_I32,  0, 30),
-	SLE_CONDVAR(Company, inaugurated_year,      SLE_INT32,                  31, SL_MAX_VERSION),
-
-	    SLE_ARR(Company, share_owners,          SLE_UINT8, 4),
-
-	    SLE_VAR(Company, num_valid_stat_ent,    SLE_UINT8),
-
-	    SLE_VAR(Company, quarters_of_bankrupcy, SLE_UINT8),
-	SLE_CONDVAR(Company, bankrupt_asked,        SLE_FILE_U8  | SLE_VAR_U16,  0, 103),
-	SLE_CONDVAR(Company, bankrupt_asked,        SLE_UINT16,                104, SL_MAX_VERSION),
-	    SLE_VAR(Company, bankrupt_timeout,      SLE_INT16),
-	SLE_CONDVAR(Company, bankrupt_value,        SLE_VAR_I64 | SLE_FILE_I32,  0, 64),
-	SLE_CONDVAR(Company, bankrupt_value,        SLE_INT64,                  65, SL_MAX_VERSION),
-
-	/* yearly expenses was changed to 64-bit in savegame version 2. */
-	SLE_CONDARR(Company, yearly_expenses,       SLE_FILE_I32 | SLE_VAR_I64, 3 * 13, 0, 1),
-	SLE_CONDARR(Company, yearly_expenses,       SLE_INT64, 3 * 13,                  2, SL_MAX_VERSION),
-
-	SLE_CONDVAR(Company, is_ai,                 SLE_BOOL, 2, SL_MAX_VERSION),
-	SLE_CONDNULL(1, 4, 99),
-
-	/* Engine renewal settings */
-	SLE_CONDNULL(512, 16, 18),
-	SLE_CONDREF(Company, engine_renew_list,     REF_ENGINE_RENEWS,          19, SL_MAX_VERSION),
-	SLE_CONDVAR(Company, engine_renew,          SLE_BOOL,                   16, SL_MAX_VERSION),
-	SLE_CONDVAR(Company, engine_renew_months,   SLE_INT16,                  16, SL_MAX_VERSION),
-	SLE_CONDVAR(Company, engine_renew_money,    SLE_UINT32,                 16, SL_MAX_VERSION),
-	SLE_CONDVAR(Company, renew_keep_length,     SLE_BOOL,                    2, SL_MAX_VERSION), // added with 16.1, but was blank since 2
-
-	/* reserve extra space in savegame here. (currently 63 bytes) */
-	SLE_CONDNULL(63, 2, SL_MAX_VERSION),
-
-	SLE_END()
-};
-
-static const SaveLoad _company_economy_desc[] = {
-	/* these were changed to 64-bit in savegame format 2 */
-	SLE_CONDVAR(CompanyEconomyEntry, income,              SLE_FILE_I32 | SLE_VAR_I64, 0, 1),
-	SLE_CONDVAR(CompanyEconomyEntry, income,              SLE_INT64,                  2, SL_MAX_VERSION),
-	SLE_CONDVAR(CompanyEconomyEntry, expenses,            SLE_FILE_I32 | SLE_VAR_I64, 0, 1),
-	SLE_CONDVAR(CompanyEconomyEntry, expenses,            SLE_INT64,                  2, SL_MAX_VERSION),
-	SLE_CONDVAR(CompanyEconomyEntry, company_value,       SLE_FILE_I32 | SLE_VAR_I64, 0, 1),
-	SLE_CONDVAR(CompanyEconomyEntry, company_value,       SLE_INT64,                  2, SL_MAX_VERSION),
-
-	    SLE_VAR(CompanyEconomyEntry, delivered_cargo,     SLE_INT32),
-	    SLE_VAR(CompanyEconomyEntry, performance_history, SLE_INT32),
-
-	SLE_END()
-};
-
-static const SaveLoad _company_livery_desc[] = {
-	SLE_CONDVAR(Livery, in_use,  SLE_BOOL,  34, SL_MAX_VERSION),
-	SLE_CONDVAR(Livery, colour1, SLE_UINT8, 34, SL_MAX_VERSION),
-	SLE_CONDVAR(Livery, colour2, SLE_UINT8, 34, SL_MAX_VERSION),
-	SLE_END()
-};
-
-static void SaveLoad_PLYR(Company *c)
-{
-	int i;
-
-	SlObject(c, _company_desc);
-
-	/* Write AI? */
-	if (!IsHumanCompany(c->index)) {
-		SaveLoad_AI(c->index);
-	}
-
-	/* Write economy */
-	SlObject(&c->cur_economy, _company_economy_desc);
-
-	/* Write old economy entries. */
-	for (i = 0; i < c->num_valid_stat_ent; i++) {
-		SlObject(&c->old_economy[i], _company_economy_desc);
-	}
-
-	/* Write each livery entry. */
-	int num_liveries = CheckSavegameVersion(63) ? LS_END - 4 : (CheckSavegameVersion(85) ? LS_END - 2: LS_END);
-	for (i = 0; i < num_liveries; i++) {
-		SlObject(&c->livery[i], _company_livery_desc);
-	}
-
-	if (num_liveries < LS_END) {
-		/* We want to insert some liveries somewhere in between. This means some have to be moved. */
-		memmove(&c->livery[LS_FREIGHT_WAGON], &c->livery[LS_PASSENGER_WAGON_MONORAIL], (LS_END - LS_FREIGHT_WAGON) * sizeof(c->livery[0]));
-		c->livery[LS_PASSENGER_WAGON_MONORAIL] = c->livery[LS_MONORAIL];
-		c->livery[LS_PASSENGER_WAGON_MAGLEV]   = c->livery[LS_MAGLEV];
-	}
-
-	if (num_liveries == LS_END - 4) {
-		/* Copy bus/truck liveries over to trams */
-		c->livery[LS_PASSENGER_TRAM] = c->livery[LS_BUS];
-		c->livery[LS_FREIGHT_TRAM]   = c->livery[LS_TRUCK];
-	}
-}
-
-static void Save_PLYR()
-{
-	Company *c;
-	FOR_ALL_COMPANIES(c) {
-		SlSetArrayIndex(c->index);
-		SlAutolength((AutolengthProc*)SaveLoad_PLYR, c);
-	}
-}
-
-static void Load_PLYR()
-{
-	int index;
-	while ((index = SlIterateArray()) != -1) {
-		Company *c = new (index) Company();
-		SaveLoad_PLYR(c);
-		_company_colours[index] = c->colour;
-
-		/* This is needed so an AI is attached to a loaded AI */
-		if (c->is_ai && (!_networking || _network_server) && _ai.enabled) {
-			/* Clear the memory of the new AI, otherwise we might be doing wrong things. */
-			memset(&_companies_ainew[index], 0, sizeof(CompanyAiNew));
-			AI_StartNewAI(c->index);
-		}
-	}
-}
-
-extern const ChunkHandler _company_chunk_handlers[] = {
-	{ 'PLYR', Save_PLYR, Load_PLYR, CH_ARRAY | CH_LAST},
-};
--- a/src/company_manager_face.h
+++ b/src/company_manager_face.h
@@ -7,6 +7,8 @@
 
 #include "core/random_func.hpp"
 #include "core/bitmath_func.hpp"
+#include "table/sprites.h"
+#include "company_type.h"
 
 /** The gender/race combinations that we have faces for */
 enum GenderEthnicity {
@@ -228,7 +230,6 @@
 }
 
 void DrawCompanyManagerFace(CompanyManagerFace face, int color, int x, int y);
-CompanyManagerFace ConvertFromOldCompanyManagerFace(uint32 face);
 bool IsValidCompanyManagerFace(CompanyManagerFace cmf);
 
 #endif /* COMPANY_MANAGER_FACE_H */
--- a/src/console_cmds.cpp
+++ b/src/console_cmds.cpp
@@ -8,7 +8,7 @@
 #include "debug.h"
 #include "engine_func.h"
 #include "landscape.h"
-#include "saveload.h"
+#include "saveload/saveload.h"
 #include "variables.h"
 #include "network/network.h"
 #include "network/network_func.h"
--- a/src/date.cpp
+++ b/src/date.cpp
@@ -15,7 +15,7 @@
 #include "vehicle_base.h"
 #include "debug.h"
 #include "rail_gui.h"
-#include "saveload.h"
+#include "saveload/saveload.h"
 
 Year      _cur_year;   ///< Current year, starting at 0
 Month     _cur_month;  ///< Current month (0..11)
--- a/src/depot.cpp
+++ b/src/depot.cpp
@@ -3,10 +3,8 @@
 /** @file depot.cpp Handling of depots. */
 
 #include "stdafx.h"
-#include "openttd.h"
 #include "depot_base.h"
 #include "landscape.h"
-#include "saveload.h"
 #include "order_func.h"
 #include "window_func.h"
 #include "oldpool_func.h"
@@ -51,35 +49,3 @@
 	_Depot_pool.CleanPool();
 	_Depot_pool.AddBlockToPool();
 }
-
-
-static const SaveLoad _depot_desc[] = {
-	SLE_CONDVAR(Depot, xy,         SLE_FILE_U16 | SLE_VAR_U32, 0, 5),
-	SLE_CONDVAR(Depot, xy,         SLE_UINT32,                 6, SL_MAX_VERSION),
-	    SLE_VAR(Depot, town_index, SLE_UINT16),
-	SLE_END()
-};
-
-static void Save_DEPT()
-{
-	Depot *depot;
-
-	FOR_ALL_DEPOTS(depot) {
-		SlSetArrayIndex(depot->index);
-		SlObject(depot, _depot_desc);
-	}
-}
-
-static void Load_DEPT()
-{
-	int index;
-
-	while ((index = SlIterateArray()) != -1) {
-		Depot *depot = new (index) Depot();
-		SlObject(depot, _depot_desc);
-	}
-}
-
-extern const ChunkHandler _depot_chunk_handlers[] = {
-	{ 'DEPT', Save_DEPT, Load_DEPT, CH_ARRAY | CH_LAST},
-};
--- a/src/economy.cpp
+++ b/src/economy.cpp
@@ -9,7 +9,6 @@
 #include "company_base.h"
 #include "company_func.h"
 #include "command_func.h"
-#include "saveload.h"
 #include "industry.h"
 #include "industry_map.h"
 #include "town.h"
@@ -767,7 +766,7 @@
  * Initialize the variables that will maintain the daily industry change system.
  * @param init_counter specifies if the counter is required to be initialized
  */
-static void StartupIndustryDailyChanges(bool init_counter)
+void StartupIndustryDailyChanges(bool init_counter)
 {
 	uint map_size = MapLogX() + MapLogY();
 	/* After getting map size, it needs to be scaled appropriately and divided by 31,
@@ -1121,37 +1120,6 @@
 		InvalidateWindow(WC_SUBSIDIES_LIST, 0);
 }
 
-static const SaveLoad _subsidies_desc[] = {
-	    SLE_VAR(Subsidy, cargo_type, SLE_UINT8),
-	    SLE_VAR(Subsidy, age,        SLE_UINT8),
-	SLE_CONDVAR(Subsidy, from,       SLE_FILE_U8 | SLE_VAR_U16, 0, 4),
-	SLE_CONDVAR(Subsidy, from,       SLE_UINT16,                5, SL_MAX_VERSION),
-	SLE_CONDVAR(Subsidy, to,         SLE_FILE_U8 | SLE_VAR_U16, 0, 4),
-	SLE_CONDVAR(Subsidy, to,         SLE_UINT16,                5, SL_MAX_VERSION),
-	SLE_END()
-};
-
-static void Save_SUBS()
-{
-	int i;
-	Subsidy *s;
-
-	for (i = 0; i != lengthof(_subsidies); i++) {
-		s = &_subsidies[i];
-		if (s->cargo_type != CT_INVALID) {
-			SlSetArrayIndex(i);
-			SlObject(s, _subsidies_desc);
-		}
-	}
-}
-
-static void Load_SUBS()
-{
-	int index;
-	while ((index = SlIterateArray()) != -1)
-		SlObject(&_subsidies[index], _subsidies_desc);
-}
-
 Money GetTransportedGoodsIncome(uint num_pieces, uint dist, byte transit_days, CargoID cargo_type)
 {
 	const CargoSpec *cs = GetCargo(cargo_type);
@@ -1994,54 +1962,3 @@
 	}
 	return CommandCost(EXPENSES_OTHER, c->bankrupt_value);
 }
-
-/** Prices */
-static void SaveLoad_PRIC()
-{
-	int vt = CheckSavegameVersion(65) ? (SLE_FILE_I32 | SLE_VAR_I64) : SLE_INT64;
-	SlArray(&_price,      NUM_PRICES, vt);
-	SlArray(&_price_frac, NUM_PRICES, SLE_UINT16);
-}
-
-/** Cargo payment rates */
-static void SaveLoad_CAPR()
-{
-	uint num_cargo = CheckSavegameVersion(55) ? 12 : NUM_CARGO;
-	int vt = CheckSavegameVersion(65) ? (SLE_FILE_I32 | SLE_VAR_I64) : SLE_INT64;
-	SlArray(&_cargo_payment_rates,      num_cargo, vt);
-	SlArray(&_cargo_payment_rates_frac, num_cargo, SLE_UINT16);
-}
-
-static const SaveLoad _economy_desc[] = {
-	SLE_CONDVAR(Economy, max_loan,                      SLE_FILE_I32 | SLE_VAR_I64,  0, 64),
-	SLE_CONDVAR(Economy, max_loan,                      SLE_INT64,                  65, SL_MAX_VERSION),
-	SLE_CONDVAR(Economy, max_loan_unround,              SLE_FILE_I32 | SLE_VAR_I64,  0, 64),
-	SLE_CONDVAR(Economy, max_loan_unround,              SLE_INT64,                  65, SL_MAX_VERSION),
-	SLE_CONDVAR(Economy, max_loan_unround_fract,        SLE_UINT16,                 70, SL_MAX_VERSION),
-	    SLE_VAR(Economy, fluct,                         SLE_INT16),
-	    SLE_VAR(Economy, interest_rate,                 SLE_UINT8),
-	    SLE_VAR(Economy, infl_amount,                   SLE_UINT8),
-	    SLE_VAR(Economy, infl_amount_pr,                SLE_UINT8),
-	SLE_CONDVAR(Economy, industry_daily_change_counter, SLE_UINT32,                102, SL_MAX_VERSION),
-	    SLE_END()
-};
-
-/** Economy variables */
-static void Save_ECMY()
-{
-	SlObject(&_economy, _economy_desc);
-}
-
-/** Economy variables */
-static void Load_ECMY()
-{
-	SlObject(&_economy, _economy_desc);
-	StartupIndustryDailyChanges(CheckSavegameVersion(102));  // old savegames will need to be initialized
-}
-
-extern const ChunkHandler _economy_chunk_handlers[] = {
-	{ 'PRIC', SaveLoad_PRIC, SaveLoad_PRIC, CH_RIFF | CH_AUTO_LENGTH},
-	{ 'CAPR', SaveLoad_CAPR, SaveLoad_CAPR, CH_RIFF | CH_AUTO_LENGTH},
-	{ 'SUBS', Save_SUBS,     Load_SUBS,     CH_ARRAY},
-	{ 'ECMY', Save_ECMY,     Load_ECMY,     CH_RIFF | CH_LAST},
-};
--- a/src/economy_func.h
+++ b/src/economy_func.h
@@ -34,6 +34,7 @@
 void DeleteSubsidyWithTown(TownID index);
 void DeleteSubsidyWithIndustry(IndustryID index);
 void DeleteSubsidyWithStation(StationID index);
+void StartupIndustryDailyChanges(bool init_counter);
 
 Money GetTransportedGoodsIncome(uint num_pieces, uint dist, byte transit_days, CargoID cargo_type);
 uint MoveGoodsToStation(TileIndex tile, int w, int h, CargoID type, uint amount);
--- a/src/effectvehicle.cpp
+++ b/src/effectvehicle.cpp
@@ -15,7 +15,6 @@
 #include "gfx_func.h"
 #include "news_func.h"
 #include "command_func.h"
-#include "saveload.h"
 #include "company_func.h"
 #include "debug.h"
 #include "vehicle_gui.h"
--- a/src/engine.cpp
+++ b/src/engine.cpp
@@ -9,7 +9,6 @@
 #include "company_func.h"
 #include "command_func.h"
 #include "news_func.h"
-#include "saveload.h"
 #include "variables.h"
 #include "train.h"
 #include "aircraft.h"
@@ -27,7 +26,6 @@
 #include "oldpool_func.h"
 #include "core/alloc_func.hpp"
 #include "vehicle_func.h"
-#include <map>
 
 #include "table/strings.h"
 #include "table/engines.h"
@@ -613,112 +611,3 @@
 		default: NOT_REACHED(); return CT_INVALID;
 	}
 }
-
-static const SaveLoad _engine_desc[] = {
-	SLE_CONDVAR(Engine, intro_date,          SLE_FILE_U16 | SLE_VAR_I32,  0,  30),
-	SLE_CONDVAR(Engine, intro_date,          SLE_INT32,                  31, SL_MAX_VERSION),
-	SLE_CONDVAR(Engine, age,                 SLE_FILE_U16 | SLE_VAR_I32,  0,  30),
-	SLE_CONDVAR(Engine, age,                 SLE_INT32,                  31, SL_MAX_VERSION),
-	    SLE_VAR(Engine, reliability,         SLE_UINT16),
-	    SLE_VAR(Engine, reliability_spd_dec, SLE_UINT16),
-	    SLE_VAR(Engine, reliability_start,   SLE_UINT16),
-	    SLE_VAR(Engine, reliability_max,     SLE_UINT16),
-	    SLE_VAR(Engine, reliability_final,   SLE_UINT16),
-	    SLE_VAR(Engine, duration_phase_1,    SLE_UINT16),
-	    SLE_VAR(Engine, duration_phase_2,    SLE_UINT16),
-	    SLE_VAR(Engine, duration_phase_3,    SLE_UINT16),
-
-	    SLE_VAR(Engine, lifelength,          SLE_UINT8),
-	    SLE_VAR(Engine, flags,               SLE_UINT8),
-	    SLE_VAR(Engine, preview_company_rank,SLE_UINT8),
-	    SLE_VAR(Engine, preview_wait,        SLE_UINT8),
-	SLE_CONDNULL(1, 0, 44),
-	SLE_CONDVAR(Engine, company_avail,       SLE_FILE_U8  | SLE_VAR_U16,  0, 103),
-	SLE_CONDVAR(Engine, company_avail,       SLE_UINT16,                104, SL_MAX_VERSION),
-	SLE_CONDSTR(Engine, name,                SLE_STR, 0,                 84, SL_MAX_VERSION),
-
-	/* reserve extra space in savegame here. (currently 16 bytes) */
-	SLE_CONDNULL(16, 2, SL_MAX_VERSION),
-
-	SLE_END()
-};
-
-static std::map<EngineID, Engine> _temp_engine;
-
-Engine *GetTempDataEngine(EngineID index)
-{
-	return &_temp_engine[index];
-}
-
-static void Save_ENGN()
-{
-	Engine *e;
-	FOR_ALL_ENGINES(e) {
-		SlSetArrayIndex(e->index);
-		SlObject(e, _engine_desc);
-	}
-}
-
-static void Load_ENGN()
-{
-	/* As engine data is loaded before engines are initialized we need to load
-	 * this information into a temporary array. This is then copied into the
-	 * engine pool after processing NewGRFs by CopyTempEngineData(). */
-	int index;
-	while ((index = SlIterateArray()) != -1) {
-		Engine *e = GetTempDataEngine(index);
-		SlObject(e, _engine_desc);
-	}
-}
-
-/**
- * Copy data from temporary engine array into the real engine pool.
- */
-void CopyTempEngineData()
-{
-	Engine *e;
-	FOR_ALL_ENGINES(e) {
-		if (e->index >= _temp_engine.size()) break;
-
-		const Engine *se = GetTempDataEngine(e->index);
-		e->intro_date          = se->intro_date;
-		e->age                 = se->age;
-		e->reliability         = se->reliability;
-		e->reliability_spd_dec = se->reliability_spd_dec;
-		e->reliability_start   = se->reliability_start;
-		e->reliability_max     = se->reliability_max;
-		e->reliability_final   = se->reliability_final;
-		e->duration_phase_1    = se->duration_phase_1;
-		e->duration_phase_2    = se->duration_phase_2;
-		e->duration_phase_3    = se->duration_phase_3;
-		e->lifelength          = se->lifelength;
-		e->flags               = se->flags;
-		e->preview_company_rank= se->preview_company_rank;
-		e->preview_wait        = se->preview_wait;
-		e->company_avail       = se->company_avail;
-		if (se->name != NULL) e->name = strdup(se->name);
-	}
-
-	/* Get rid of temporary data */
-	_temp_engine.clear();
-}
-
-static void Load_ENGS()
-{
-	/* Load old separate String ID list into a temporary array. This
-	 * was always 256 entries. */
-	StringID names[256];
-
-	SlArray(names, lengthof(names), SLE_STRINGID);
-
-	/* Copy each string into the temporary engine array. */
-	for (EngineID engine = 0; engine < lengthof(names); engine++) {
-		Engine *e = GetTempDataEngine(engine);
-		e->name = CopyFromOldName(names[engine]);
-	}
-}
-
-extern const ChunkHandler _engine_chunk_handlers[] = {
-	{ 'ENGN', Save_ENGN,     Load_ENGN,     CH_ARRAY          },
-	{ 'ENGS', NULL,          Load_ENGS,     CH_RIFF | CH_LAST },
-};
--- a/src/gamelog.cpp
+++ b/src/gamelog.cpp
@@ -4,7 +4,7 @@
 
 #include "stdafx.h"
 #include "openttd.h"
-#include "saveload.h"
+#include "saveload/saveload.h"
 #include "core/alloc_func.hpp"
 #include "core/bitmath_func.hpp"
 #include "core/math_func.hpp"
@@ -13,13 +13,15 @@
 #include "string_func.h"
 #include "settings_type.h"
 #include "newgrf_config.h"
-#include <string.h>
-#include <stdarg.h>
 #include "gamelog.h"
+#include "gamelog_internal.h"
 #include "console_func.h"
 #include "debug.h"
 #include "rev.h"
 
+#include <string.h>
+#include <stdarg.h>
+
 extern const uint16 SAVEGAME_VERSION;  ///< current savegame version
 
 extern SavegameType _savegame_type; ///< type of savegame we are loading
@@ -28,79 +30,11 @@
 extern uint16 _sl_version;       ///< the major savegame version identifier
 extern byte   _sl_minor_version; ///< the minor savegame version, DO NOT USE!
 
-/** Type of logged change */
-enum GamelogChangeType {
-	GLCT_MODE,        ///< Scenario editor x Game, different landscape
-	GLCT_REVISION,    ///< Changed game revision string
-	GLCT_OLDVER,      ///< Loaded from savegame without logged data
-	GLCT_PATCH,       ///< Non-networksafe patch value changed
-	GLCT_GRFADD,      ///< Removed GRF
-	GLCT_GRFREM,      ///< Added GRF
-	GLCT_GRFCOMPAT,   ///< Loading compatible GRF
-	GLCT_GRFPARAM,    ///< GRF parameter changed
-	GLCT_GRFMOVE,     ///< GRF order changed
-	GLCT_GRFBUG,      ///< GRF bug triggered
-	GLCT_END,         ///< So we know how many GLCTs are there
-	GLCT_NONE = 0xFF, ///< In savegames, end of list
-};
-
-
-/** Contains information about one logged change */
-struct LoggedChange {
-	GamelogChangeType ct; ///< Type of change logged in this struct
-	union {
-		struct {
-			byte mode;       ///< new game mode - Editor x Game
-			byte landscape;  ///< landscape (temperate, arctic, ...)
-		} mode;
-		struct {
-			char text[NETWORK_REVISION_LENGTH]; ///< revision string, _openttd_revision
-			uint32 newgrf;   ///< _openttd_newgrf_version
-			uint16 slver;    ///< _sl_version
-			byte modified;   ///< _openttd_revision_modified
-		} revision;
-		struct {
-			uint32 type;     ///< type of savegame, @see SavegameType
-			uint32 version;  ///< major and minor version OR ttdp version
-		} oldver;
-		GRFIdentifier grfadd;    ///< ID and md5sum of added GRF
-		struct {
-			uint32 grfid;    ///< ID of removed GRF
-		} grfrem;
-		GRFIdentifier grfcompat; ///< ID and new md5sum of changed GRF
-		struct {
-			uint32 grfid;    ///< ID of GRF with changed parameters
-		} grfparam;
-		struct {
-			uint32 grfid;    ///< ID of moved GRF
-			int32 offset;    ///< offset, positive = move down
-		} grfmove;
-		struct {
-			char *name;      ///< name of the patch
-			int32 oldval;    ///< old value
-			int32 newval;    ///< new value
-		} patch;
-		struct {
-			uint64 data;     ///< additional data
-			uint32 grfid;    ///< ID of problematic GRF
-			byte bug;        ///< type of bug, @see enum GRFBugs
-		} grfbug;
-	};
-};
-
-
-/** Contains information about one logged action that caused at least one logged change */
-struct LoggedAction {
-	LoggedChange *change; ///< First logged change in this action
-	uint32 changes;       ///< Number of changes in this action
-	GamelogActionType at; ///< Type of action
-	uint16 tick;          ///< Tick when it happened
-};
 
 static GamelogActionType _gamelog_action_type = GLAT_NONE; ///< action to record if anything changes
 
-static LoggedAction *_gamelog_action = NULL; ///< first logged action
-static uint _gamelog_actions         = 0;    ///< number of actions
+LoggedAction *_gamelog_action = NULL;        ///< first logged action
+uint _gamelog_actions         = 0;           ///< number of actions
 static LoggedAction *_current_action = NULL; ///< current action we are logging, NULL when there is no action active
 
 
@@ -728,155 +662,3 @@
 	free(ol);
 	free(nl);
 }
-
-
-static const SaveLoad _glog_action_desc[] = {
-	SLE_VAR(LoggedAction, tick,              SLE_UINT16),
-	SLE_END()
-};
-
-static const SaveLoad _glog_mode_desc[] = {
-	SLE_VAR(LoggedChange, mode.mode,         SLE_UINT8),
-	SLE_VAR(LoggedChange, mode.landscape,    SLE_UINT8),
-	SLE_END()
-};
-
-static const SaveLoad _glog_revision_desc[] = {
-	SLE_ARR(LoggedChange, revision.text,     SLE_UINT8,  NETWORK_REVISION_LENGTH),
-	SLE_VAR(LoggedChange, revision.newgrf,   SLE_UINT32),
-	SLE_VAR(LoggedChange, revision.slver,    SLE_UINT16),
-	SLE_VAR(LoggedChange, revision.modified, SLE_UINT8),
-	SLE_END()
-};
-
-static const SaveLoad _glog_oldver_desc[] = {
-	SLE_VAR(LoggedChange, oldver.type,       SLE_UINT32),
-	SLE_VAR(LoggedChange, oldver.version,    SLE_UINT32),
-	SLE_END()
-};
-
-static const SaveLoad _glog_patch_desc[] = {
-	SLE_STR(LoggedChange, patch.name,        SLE_STR,    128),
-	SLE_VAR(LoggedChange, patch.oldval,      SLE_INT32),
-	SLE_VAR(LoggedChange, patch.newval,      SLE_INT32),
-	SLE_END()
-};
-
-static const SaveLoad _glog_grfadd_desc[] = {
-	SLE_VAR(LoggedChange, grfadd.grfid,      SLE_UINT32    ),
-	SLE_ARR(LoggedChange, grfadd.md5sum,     SLE_UINT8,  16),
-	SLE_END()
-};
-
-static const SaveLoad _glog_grfrem_desc[] = {
-	SLE_VAR(LoggedChange, grfrem.grfid,      SLE_UINT32),
-	SLE_END()
-};
-
-static const SaveLoad _glog_grfcompat_desc[] = {
-	SLE_VAR(LoggedChange, grfcompat.grfid,   SLE_UINT32    ),
-	SLE_ARR(LoggedChange, grfcompat.md5sum,  SLE_UINT8,  16),
-	SLE_END()
-};
-
-static const SaveLoad _glog_grfparam_desc[] = {
-	SLE_VAR(LoggedChange, grfparam.grfid,    SLE_UINT32),
-	SLE_END()
-};
-
-static const SaveLoad _glog_grfmove_desc[] = {
-	SLE_VAR(LoggedChange, grfmove.grfid,     SLE_UINT32),
-	SLE_VAR(LoggedChange, grfmove.offset,    SLE_INT32),
-	SLE_END()
-};
-
-static const SaveLoad _glog_grfbug_desc[] = {
-	SLE_VAR(LoggedChange, grfbug.data,       SLE_UINT64),
-	SLE_VAR(LoggedChange, grfbug.grfid,      SLE_UINT32),
-	SLE_VAR(LoggedChange, grfbug.bug,        SLE_UINT8),
-	SLE_END()
-};
-
-static const SaveLoad *_glog_desc[] = {
-	_glog_mode_desc,
-	_glog_revision_desc,
-	_glog_oldver_desc,
-	_glog_patch_desc,
-	_glog_grfadd_desc,
-	_glog_grfrem_desc,
-	_glog_grfcompat_desc,
-	_glog_grfparam_desc,
-	_glog_grfmove_desc,
-	_glog_grfbug_desc,
-};
-
-assert_compile(lengthof(_glog_desc) == GLCT_END);
-
-static void Load_GLOG()
-{
-	assert(_gamelog_action == NULL);
-	assert(_gamelog_actions == 0);
-
-	GamelogActionType at;
-	while ((at = (GamelogActionType)SlReadByte()) != GLAT_NONE) {
-		_gamelog_action = ReallocT(_gamelog_action, _gamelog_actions + 1);
-		LoggedAction *la = &_gamelog_action[_gamelog_actions++];
-
-		la->at = at;
-
-		SlObject(la, _glog_action_desc); // has to be saved after 'DATE'!
-		la->change = NULL;
-		la->changes = 0;
-
-		GamelogChangeType ct;
-		while ((ct = (GamelogChangeType)SlReadByte()) != GLCT_NONE) {
-			la->change = ReallocT(la->change, la->changes + 1);
-
-			LoggedChange *lc = &la->change[la->changes++];
-			/* for SLE_STR, pointer has to be valid! so make it NULL */
-			memset(lc, 0, sizeof(*lc));
-			lc->ct = ct;
-
-			assert((uint)ct < GLCT_END);
-
-			SlObject(lc, _glog_desc[ct]);
-		}
-	}
-}
-
-static void Save_GLOG()
-{
-	const LoggedAction *laend = &_gamelog_action[_gamelog_actions];
-	size_t length = 0;
-
-	for (const LoggedAction *la = _gamelog_action; la != laend; la++) {
-		const LoggedChange *lcend = &la->change[la->changes];
-		for (LoggedChange *lc = la->change; lc != lcend; lc++) {
-			assert((uint)lc->ct < lengthof(_glog_desc));
-			length += SlCalcObjLength(lc, _glog_desc[lc->ct]) + 1;
-		}
-		length += 4;
-	}
-	length++;
-
-	SlSetLength(length);
-
-	for (LoggedAction *la = _gamelog_action; la != laend; la++) {
-		SlWriteByte(la->at);
-		SlObject(la, _glog_action_desc);
-
-		const LoggedChange *lcend = &la->change[la->changes];
-		for (LoggedChange *lc = la->change; lc != lcend; lc++) {
-			SlWriteByte(lc->ct);
-			assert((uint)lc->ct < GLCT_END);
-			SlObject(lc, _glog_desc[lc->ct]);
-		}
-		SlWriteByte(GLCT_NONE);
-	}
-	SlWriteByte(GLAT_NONE);
-}
-
-
-extern const ChunkHandler _gamelog_chunk_handlers[] = {
-	{ 'GLOG', Save_GLOG, Load_GLOG, CH_RIFF | CH_LAST }
-};
new file mode 100644
--- /dev/null
+++ b/src/gamelog_internal.h
@@ -0,0 +1,82 @@
+/* $Id$ */
+
+/** @file gamelog_internal.h Declaration shared among gamelog.cpp and saveload/gamelog_sl.cpp */
+
+#ifndef GAMELOG_INTERNAL_H
+#define GAMELOG_INTERNAL_H
+
+#include "network/core/config.h"
+
+/** Type of logged change */
+enum GamelogChangeType {
+	GLCT_MODE,        ///< Scenario editor x Game, different landscape
+	GLCT_REVISION,    ///< Changed game revision string
+	GLCT_OLDVER,      ///< Loaded from savegame without logged data
+	GLCT_PATCH,       ///< Non-networksafe patch value changed
+	GLCT_GRFADD,      ///< Removed GRF
+	GLCT_GRFREM,      ///< Added GRF
+	GLCT_GRFCOMPAT,   ///< Loading compatible GRF
+	GLCT_GRFPARAM,    ///< GRF parameter changed
+	GLCT_GRFMOVE,     ///< GRF order changed
+	GLCT_GRFBUG,      ///< GRF bug triggered
+	GLCT_END,         ///< So we know how many GLCTs are there
+	GLCT_NONE = 0xFF, ///< In savegames, end of list
+};
+
+
+/** Contains information about one logged change */
+struct LoggedChange {
+	GamelogChangeType ct; ///< Type of change logged in this struct
+	union {
+		struct {
+			byte mode;       ///< new game mode - Editor x Game
+			byte landscape;  ///< landscape (temperate, arctic, ...)
+		} mode;
+		struct {
+			char text[NETWORK_REVISION_LENGTH]; ///< revision string, _openttd_revision
+			uint32 newgrf;   ///< _openttd_newgrf_version
+			uint16 slver;    ///< _sl_version
+			byte modified;   ///< _openttd_revision_modified
+		} revision;
+		struct {
+			uint32 type;     ///< type of savegame, @see SavegameType
+			uint32 version;  ///< major and minor version OR ttdp version
+		} oldver;
+		GRFIdentifier grfadd;    ///< ID and md5sum of added GRF
+		struct {
+			uint32 grfid;    ///< ID of removed GRF
+		} grfrem;
+		GRFIdentifier grfcompat; ///< ID and new md5sum of changed GRF
+		struct {
+			uint32 grfid;    ///< ID of GRF with changed parameters
+		} grfparam;
+		struct {
+			uint32 grfid;    ///< ID of moved GRF
+			int32 offset;    ///< offset, positive = move down
+		} grfmove;
+		struct {
+			char *name;      ///< name of the patch
+			int32 oldval;    ///< old value
+			int32 newval;    ///< new value
+		} patch;
+		struct {
+			uint64 data;     ///< additional data
+			uint32 grfid;    ///< ID of problematic GRF
+			byte bug;        ///< type of bug, @see enum GRFBugs
+		} grfbug;
+	};
+};
+
+
+/** Contains information about one logged action that caused at least one logged change */
+struct LoggedAction {
+	LoggedChange *change; ///< First logged change in this action
+	uint32 changes;       ///< Number of changes in this action
+	GamelogActionType at; ///< Type of action
+	uint16 tick;          ///< Tick when it happened
+};
+
+extern LoggedAction *_gamelog_action;
+extern uint _gamelog_actions;
+
+#endif /* GAMELOG_INTERNAL_H */
--- a/src/genworld.cpp
+++ b/src/genworld.cpp
@@ -26,7 +26,7 @@
 #include "newgrf_storage.h"
 #include "water.h"
 #include "tilehighlight_func.h"
-#include "saveload.h"
+#include "saveload/saveload.h"
 
 #include "table/sprites.h"
 
--- a/src/group_cmd.cpp
+++ b/src/group_cmd.cpp
@@ -6,7 +6,6 @@
 #include "openttd.h"
 #include "variables.h"
 #include "command_func.h"
-#include "saveload.h"
 #include "debug.h"
 #include "group.h"
 #include "train.h"
@@ -421,40 +420,3 @@
 		if (company == g->owner) delete g;
 	}
 }
-
-
-static const SaveLoad _group_desc[] = {
-  SLE_CONDVAR(Group, name,           SLE_NAME,    0, 83),
-  SLE_CONDSTR(Group, name,           SLE_STR, 0, 84, SL_MAX_VERSION),
-  SLE_VAR(Group, num_vehicle,        SLE_UINT16),
-  SLE_VAR(Group, owner,              SLE_UINT8),
-  SLE_VAR(Group, vehicle_type,       SLE_UINT8),
-  SLE_VAR(Group, replace_protection, SLE_BOOL),
-  SLE_END()
-};
-
-
-static void Save_GROUP(void)
-{
-	Group *g;
-
-	FOR_ALL_GROUPS(g) {
-		SlSetArrayIndex(g->index);
-		SlObject(g, _group_desc);
-	}
-}
-
-
-static void Load_GROUP(void)
-{
-	int index;
-
-	while ((index = SlIterateArray()) != -1) {
-		Group *g = new (index) Group();
-		SlObject(g, _group_desc);
-	}
-}
-
-extern const ChunkHandler _group_chunk_handlers[] = {
-	{ 'GRPS', Save_GROUP, Load_GROUP, CH_ARRAY | CH_LAST},
-};
--- a/src/heightmap.cpp
+++ b/src/heightmap.cpp
@@ -10,7 +10,7 @@
 #include "void_map.h"
 #include "debug.h"
 #include "gui.h"
-#include "saveload.h"
+#include "saveload/saveload.h"
 #include "bmp.h"
 #include "gfx_func.h"
 #include "core/alloc_func.hpp"
--- a/src/industry_cmd.cpp
+++ b/src/industry_cmd.cpp
@@ -14,7 +14,6 @@
 #include "industry.h"
 #include "town.h"
 #include "news_func.h"
-#include "saveload.h"
 #include "variables.h"
 #include "cheat_func.h"
 #include "genworld.h"
@@ -2397,146 +2396,3 @@
 	GetFoundation_Industry,      /* get_foundation_proc */
 	TerraformTile_Industry,      /* terraform_tile_proc */
 };
-
-static const SaveLoad _industry_desc[] = {
-	SLE_CONDVAR(Industry, xy,                         SLE_FILE_U16 | SLE_VAR_U32,  0, 5),
-	SLE_CONDVAR(Industry, xy,                         SLE_UINT32,                  6, SL_MAX_VERSION),
-	    SLE_VAR(Industry, width,                      SLE_UINT8),
-	    SLE_VAR(Industry, height,                     SLE_UINT8),
-	    SLE_REF(Industry, town,                       REF_TOWN),
-	SLE_CONDNULL( 2, 0, 60),       ///< used to be industry's produced_cargo
-	SLE_CONDARR(Industry, produced_cargo,             SLE_UINT8,  2,              78, SL_MAX_VERSION),
-	SLE_CONDARR(Industry, incoming_cargo_waiting,     SLE_UINT16, 3,              70, SL_MAX_VERSION),
-	    SLE_ARR(Industry, produced_cargo_waiting,     SLE_UINT16, 2),
-	    SLE_ARR(Industry, production_rate,            SLE_UINT8,  2),
-	SLE_CONDNULL( 3, 0, 60),       ///< used to be industry's accepts_cargo
-	SLE_CONDARR(Industry, accepts_cargo,              SLE_UINT8,  3,              78, SL_MAX_VERSION),
-	    SLE_VAR(Industry, prod_level,                 SLE_UINT8),
-	    SLE_ARR(Industry, this_month_production,      SLE_UINT16, 2),
-	    SLE_ARR(Industry, this_month_transported,     SLE_UINT16, 2),
-	    SLE_ARR(Industry, last_month_pct_transported, SLE_UINT8,  2),
-	    SLE_ARR(Industry, last_month_production,      SLE_UINT16, 2),
-	    SLE_ARR(Industry, last_month_transported,     SLE_UINT16, 2),
-
-	    SLE_VAR(Industry, counter,                    SLE_UINT16),
-
-	    SLE_VAR(Industry, type,                       SLE_UINT8),
-	    SLE_VAR(Industry, owner,                      SLE_UINT8),
-	    SLE_VAR(Industry, random_color,               SLE_UINT8),
-	SLE_CONDVAR(Industry, last_prod_year,             SLE_FILE_U8 | SLE_VAR_I32,  0, 30),
-	SLE_CONDVAR(Industry, last_prod_year,             SLE_INT32,                 31, SL_MAX_VERSION),
-	    SLE_VAR(Industry, was_cargo_delivered,        SLE_UINT8),
-
-	SLE_CONDVAR(Industry, founder,                    SLE_UINT8,                 70, SL_MAX_VERSION),
-	SLE_CONDVAR(Industry, construction_date,          SLE_INT32,                 70, SL_MAX_VERSION),
-	SLE_CONDVAR(Industry, construction_type,          SLE_UINT8,                 70, SL_MAX_VERSION),
-	SLE_CONDVAR(Industry, last_cargo_accepted_at,     SLE_INT32,                 70, SL_MAX_VERSION),
-	SLE_CONDVAR(Industry, selected_layout,            SLE_UINT8,                 73, SL_MAX_VERSION),
-
-	SLE_CONDARRX(cpp_offsetof(Industry, psa) + cpp_offsetof(Industry::PersistentStorage, storage), SLE_UINT32, 16, 76, SL_MAX_VERSION),
-
-	SLE_CONDVAR(Industry, random_triggers,            SLE_UINT8,                 82, SL_MAX_VERSION),
-	SLE_CONDVAR(Industry, random,                     SLE_UINT16,                82, SL_MAX_VERSION),
-
-	/* reserve extra space in savegame here. (currently 32 bytes) */
-	SLE_CONDNULL(32, 2, SL_MAX_VERSION),
-
-	SLE_END()
-};
-
-static void Save_INDY()
-{
-	Industry *ind;
-
-	/* Write the industries */
-	FOR_ALL_INDUSTRIES(ind) {
-		SlSetArrayIndex(ind->index);
-		SlObject(ind, _industry_desc);
-	}
-}
-
-/* Save and load the mapping between the industry/tile id on the map, and the grf file
- * it came from. */
-static const SaveLoad _industries_id_mapping_desc[] = {
-	SLE_VAR(EntityIDMapping, grfid,         SLE_UINT32),
-	SLE_VAR(EntityIDMapping, entity_id,     SLE_UINT8),
-	SLE_VAR(EntityIDMapping, substitute_id, SLE_UINT8),
-	SLE_END()
-};
-
-static void Save_IIDS()
-{
-	uint i;
-	uint j = _industry_mngr.GetMaxMapping();
-
-	for (i = 0; i < j; i++) {
-		SlSetArrayIndex(i);
-		SlObject(&_industry_mngr.mapping_ID[i], _industries_id_mapping_desc);
-	}
-}
-
-static void Save_TIDS()
-{
-	uint i;
-	uint j = _industile_mngr.GetMaxMapping();
-
-	for (i = 0; i < j; i++) {
-		SlSetArrayIndex(i);
-		SlObject(&_industile_mngr.mapping_ID[i], _industries_id_mapping_desc);
-	}
-}
-
-static void Load_INDY()
-{
-	int index;
-
-	ResetIndustryCounts();
-
-	while ((index = SlIterateArray()) != -1) {
-		Industry *i = new (index) Industry();
-		SlObject(i, _industry_desc);
-		IncIndustryTypeCount(i->type);
-	}
-}
-
-static void Load_IIDS()
-{
-	int index;
-	uint max_id;
-
-	/* clear the current mapping stored.
-	 * This will create the manager if ever it is not yet done */
-	_industry_mngr.ResetMapping();
-
-	/* get boundary for the temporary map loader NUM_INDUSTRYTYPES? */
-	max_id = _industry_mngr.GetMaxMapping();
-
-	while ((index = SlIterateArray()) != -1) {
-		if ((uint)index >= max_id) break;
-		SlObject(&_industry_mngr.mapping_ID[index], _industries_id_mapping_desc);
-	}
-}
-
-static void Load_TIDS()
-{
-	int index;
-	uint max_id;
-
-	/* clear the current mapping stored.
-	 * This will create the manager if ever it is not yet done */
-	_industile_mngr.ResetMapping();
-
-	/* get boundary for the temporary map loader NUM_INDUSTILES? */
-	max_id = _industile_mngr.GetMaxMapping();
-
-	while ((index = SlIterateArray()) != -1) {
-		if ((uint)index >= max_id) break;
-		SlObject(&_industile_mngr.mapping_ID[index], _industries_id_mapping_desc);
-	}
-}
-
-extern const ChunkHandler _industry_chunk_handlers[] = {
-	{ 'INDY', Save_INDY, Load_INDY, CH_ARRAY},
-	{ 'IIDS', Save_IIDS, Load_IIDS, CH_ARRAY},
-	{ 'TIDS', Save_TIDS, Load_TIDS, CH_ARRAY | CH_LAST},
-};
--- a/src/misc.cpp
+++ b/src/misc.cpp
@@ -7,7 +7,6 @@
 #include "currency.h"
 #include "landscape.h"
 #include "news_func.h"
-#include "saveload.h"
 #include "vehicle_gui.h"
 #include "variables.h"
 #include "cheat_func.h"
@@ -134,290 +133,3 @@
 		_cargo_payment_rates_frac[i] = 0;
 	}
 }
-
-static const SaveLoadGlobVarList _date_desc[] = {
-	SLEG_CONDVAR(_date,                   SLE_FILE_U16 | SLE_VAR_I32,  0,  30),
-	SLEG_CONDVAR(_date,                   SLE_INT32,                  31, SL_MAX_VERSION),
-	    SLEG_VAR(_date_fract,             SLE_UINT16),
-	    SLEG_VAR(_tick_counter,           SLE_UINT16),
-	    SLEG_VAR(_vehicle_id_ctr_day,     SLE_UINT16),
-	    SLEG_VAR(_age_cargo_skip_counter, SLE_UINT8),
-	SLE_CONDNULL(1, 0, 45),
-	SLEG_CONDVAR(_cur_tileloop_tile,      SLE_FILE_U16 | SLE_VAR_U32,  0, 5),
-	SLEG_CONDVAR(_cur_tileloop_tile,      SLE_UINT32,                  6, SL_MAX_VERSION),
-	    SLEG_VAR(_disaster_delay,         SLE_UINT16),
-	    SLEG_VAR(_station_tick_ctr,       SLE_UINT16),
-	    SLEG_VAR(_random.state[0],        SLE_UINT32),
-	    SLEG_VAR(_random.state[1],        SLE_UINT32),
-	SLEG_CONDVAR(_cur_town_ctr,           SLE_FILE_U8  | SLE_VAR_U32,  0, 9),
-	SLEG_CONDVAR(_cur_town_ctr,           SLE_UINT32,                 10, SL_MAX_VERSION),
-	    SLEG_VAR(_cur_company_tick_index, SLE_FILE_U8  | SLE_VAR_U32),
-	    SLEG_VAR(_next_competitor_start,  SLE_FILE_U16 | SLE_VAR_U32),
-	    SLEG_VAR(_trees_tick_ctr,         SLE_UINT8),
-	SLEG_CONDVAR(_pause_game,             SLE_UINT8,                   4, SL_MAX_VERSION),
-	SLEG_CONDVAR(_cur_town_iter,          SLE_UINT32,                 11, SL_MAX_VERSION),
-	    SLEG_END()
-};
-
-/* Save load date related variables as well as persistent tick counters
- * XXX: currently some unrelated stuff is just put here */
-static void SaveLoad_DATE()
-{
-	SlGlobList(_date_desc);
-}
-
-
-static const SaveLoadGlobVarList _view_desc[] = {
-	SLEG_CONDVAR(_saved_scrollpos_x,    SLE_FILE_I16 | SLE_VAR_I32, 0, 5),
-	SLEG_CONDVAR(_saved_scrollpos_x,    SLE_INT32,                  6, SL_MAX_VERSION),
-	SLEG_CONDVAR(_saved_scrollpos_y,    SLE_FILE_I16 | SLE_VAR_I32, 0, 5),
-	SLEG_CONDVAR(_saved_scrollpos_y,    SLE_INT32,                  6, SL_MAX_VERSION),
-	    SLEG_VAR(_saved_scrollpos_zoom, SLE_UINT8),
-	    SLEG_END()
-};
-
-static void SaveLoad_VIEW()
-{
-	SlGlobList(_view_desc);
-}
-
-static uint32 _map_dim_x;
-static uint32 _map_dim_y;
-
-static const SaveLoadGlobVarList _map_dimensions[] = {
-	SLEG_CONDVAR(_map_dim_x, SLE_UINT32, 6, SL_MAX_VERSION),
-	SLEG_CONDVAR(_map_dim_y, SLE_UINT32, 6, SL_MAX_VERSION),
-	    SLEG_END()
-};
-
-static void Save_MAPS()
-{
-	_map_dim_x = MapSizeX();
-	_map_dim_y = MapSizeY();
-	SlGlobList(_map_dimensions);
-}
-
-static void Load_MAPS()
-{
-	SlGlobList(_map_dimensions);
-	AllocateMap(_map_dim_x, _map_dim_y);
-}
-
-enum {
-	MAP_SL_BUF_SIZE = 4096
-};
-
-static void Load_MAPT()
-{
-	SmallStackSafeStackAlloc<byte, MAP_SL_BUF_SIZE> buf;
-	TileIndex size = MapSize();
-
-	for (TileIndex i = 0; i != size;) {
-		SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8);
-		for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _m[i++].type_height = buf[j];
-	}
-}
-
-static void Save_MAPT()
-{
-	SmallStackSafeStackAlloc<byte, MAP_SL_BUF_SIZE> buf;
-	TileIndex size = MapSize();
-
-	SlSetLength(size);
-	for (TileIndex i = 0; i != size;) {
-		for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = _m[i++].type_height;
-		SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8);
-	}
-}
-
-static void Load_MAP1()
-{
-	SmallStackSafeStackAlloc<byte, MAP_SL_BUF_SIZE> buf;
-	TileIndex size = MapSize();
-
-	for (TileIndex i = 0; i != size;) {
-		SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8);
-		for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _m[i++].m1 = buf[j];
-	}
-}
-
-static void Save_MAP1()
-{
-	SmallStackSafeStackAlloc<byte, MAP_SL_BUF_SIZE> buf;
-	TileIndex size = MapSize();
-
-	SlSetLength(size);
-	for (TileIndex i = 0; i != size;) {
-		for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = _m[i++].m1;
-		SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8);
-	}
-}
-
-static void Load_MAP2()
-{
-	SmallStackSafeStackAlloc<uint16, MAP_SL_BUF_SIZE> buf;
-	TileIndex size = MapSize();
-
-	for (TileIndex i = 0; i != size;) {
-		SlArray(buf, MAP_SL_BUF_SIZE,
-			/* In those versions the m2 was 8 bits */
-			CheckSavegameVersion(5) ? SLE_FILE_U8 | SLE_VAR_U16 : SLE_UINT16
-		);
-		for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _m[i++].m2 = buf[j];
-	}
-}
-
-static void Save_MAP2()
-{
-	SmallStackSafeStackAlloc<uint16, MAP_SL_BUF_SIZE> buf;
-	TileIndex size = MapSize();
-
-	SlSetLength(size * sizeof(uint16));
-	for (TileIndex i = 0; i != size;) {
-		for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = _m[i++].m2;
-		SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT16);
-	}
-}
-
-static void Load_MAP3()
-{
-	SmallStackSafeStackAlloc<byte, MAP_SL_BUF_SIZE> buf;
-	TileIndex size = MapSize();
-
-	for (TileIndex i = 0; i != size;) {
-		SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8);
-		for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _m[i++].m3 = buf[j];
-	}
-}
-
-static void Save_MAP3()
-{
-	SmallStackSafeStackAlloc<byte, MAP_SL_BUF_SIZE> buf;
-	TileIndex size = MapSize();
-
-	SlSetLength(size);
-	for (TileIndex i = 0; i != size;) {
-		for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = _m[i++].m3;
-		SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8);
-	}
-}
-
-static void Load_MAP4()
-{
-	SmallStackSafeStackAlloc<byte, MAP_SL_BUF_SIZE> buf;
-	TileIndex size = MapSize();
-
-	for (TileIndex i = 0; i != size;) {
-		SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8);
-		for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _m[i++].m4 = buf[j];
-	}
-}
-
-static void Save_MAP4()
-{
-	SmallStackSafeStackAlloc<byte, MAP_SL_BUF_SIZE> buf;
-	TileIndex size = MapSize();
-
-	SlSetLength(size);
-	for (TileIndex i = 0; i != size;) {
-		for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = _m[i++].m4;
-		SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8);
-	}
-}
-
-static void Load_MAP5()
-{
-	SmallStackSafeStackAlloc<byte, MAP_SL_BUF_SIZE> buf;
-	TileIndex size = MapSize();
-
-	for (TileIndex i = 0; i != size;) {
-		SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8);
-		for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _m[i++].m5 = buf[j];
-	}
-}
-
-static void Save_MAP5()
-{
-	SmallStackSafeStackAlloc<byte, MAP_SL_BUF_SIZE> buf;
-	TileIndex size = MapSize();
-
-	SlSetLength(size);
-	for (TileIndex i = 0; i != size;) {
-		for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = _m[i++].m5;
-		SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8);
-	}
-}
-
-static void Load_MAP6()
-{
-	SmallStackSafeStackAlloc<byte, MAP_SL_BUF_SIZE> buf;
-	TileIndex size = MapSize();
-
-	if (CheckSavegameVersion(42)) {
-		for (TileIndex i = 0; i != size;) {
-			/* 1024, otherwise we overflow on 64x64 maps! */
-			SlArray(buf, 1024, SLE_UINT8);
-			for (uint j = 0; j != 1024; j++) {
-				_m[i++].m6 = GB(buf[j], 0, 2);
-				_m[i++].m6 = GB(buf[j], 2, 2);
-				_m[i++].m6 = GB(buf[j], 4, 2);
-				_m[i++].m6 = GB(buf[j], 6, 2);
-			}
-		}
-	} else {
-		for (TileIndex i = 0; i != size;) {
-			SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8);
-			for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _m[i++].m6 = buf[j];
-		}
-	}
-}
-
-static void Save_MAP6()
-{
-	SmallStackSafeStackAlloc<byte, MAP_SL_BUF_SIZE> buf;
-	TileIndex size = MapSize();
-
-	SlSetLength(size);
-	for (TileIndex i = 0; i != size;) {
-		for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = _m[i++].m6;
-		SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8);
-	}
-}
-
-static void Load_MAP7()
-{
-	SmallStackSafeStackAlloc<byte, MAP_SL_BUF_SIZE> buf;
-	TileIndex size = MapSize();
-
-	for (TileIndex i = 0; i != size;) {
-		SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8);
-		for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _me[i++].m7 = buf[j];
-	}
-}
-
-static void Save_MAP7()
-{
-	SmallStackSafeStackAlloc<byte, MAP_SL_BUF_SIZE> buf;
-	TileIndex size = MapSize();
-
-	SlSetLength(size);
-	for (TileIndex i = 0; i != size;) {
-		for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = _me[i++].m7;
-		SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8);
-	}
-}
-
-extern const ChunkHandler _misc_chunk_handlers[] = {
-	{ 'MAPS', Save_MAPS,     Load_MAPS,     CH_RIFF },
-	{ 'MAPT', Save_MAPT,     Load_MAPT,     CH_RIFF },
-	{ 'MAPO', Save_MAP1,     Load_MAP1,     CH_RIFF },
-	{ 'MAP2', Save_MAP2,     Load_MAP2,     CH_RIFF },
-	{ 'M3LO', Save_MAP3,     Load_MAP3,     CH_RIFF },
-	{ 'M3HI', Save_MAP4,     Load_MAP4,     CH_RIFF },
-	{ 'MAP5', Save_MAP5,     Load_MAP5,     CH_RIFF },
-	{ 'MAPE', Save_MAP6,     Load_MAP6,     CH_RIFF },
-	{ 'MAP7', Save_MAP7,     Load_MAP7,     CH_RIFF },
-
-	{ 'DATE', SaveLoad_DATE, SaveLoad_DATE, CH_RIFF},
-	{ 'VIEW', SaveLoad_VIEW, SaveLoad_VIEW, CH_RIFF | CH_LAST},
-};
--- a/src/misc_gui.cpp
+++ b/src/misc_gui.cpp
@@ -9,7 +9,7 @@
 #include "landscape.h"
 #include "newgrf.h"
 #include "newgrf_text.h"
-#include "saveload.h"
+#include "saveload/saveload.h"
 #include "tile_map.h"
 #include "gui.h"
 #include "window_gui.h"
--- a/src/network/network_client.cpp
+++ b/src/network/network_client.cpp
@@ -12,7 +12,7 @@
 #include "network_client.h"
 #include "network_gamelist.h"
 #include "network_gui.h"
-#include "../saveload.h"
+#include "../saveload/saveload.h"
 #include "../command_func.h"
 #include "../console_func.h"
 #include "../variables.h"
--- a/src/network/network_server.cpp
+++ b/src/network/network_server.cpp
@@ -17,7 +17,7 @@
 #include "network_udp.h"
 #include "../console_func.h"
 #include "../command_func.h"
-#include "../saveload.h"
+#include "../saveload/saveload.h"
 #include "../station_base.h"
 #include "../variables.h"
 #include "../genworld.h"
--- a/src/newgrf.h
+++ b/src/newgrf.h
@@ -121,7 +121,7 @@
 
 void LoadNewGRFFile(GRFConfig *config, uint file_index, GrfLoadingStage stage);
 void LoadNewGRF(uint load_index, uint file_index);
-void ReloadNewGRFData(); // in openttd.cpp
+void ReloadNewGRFData(); // in saveload/afterload.cpp
 
 void CDECL grfmsg(int severity, const char *str, ...);
 
--- a/src/newgrf_config.cpp
+++ b/src/newgrf_config.cpp
@@ -6,7 +6,6 @@
 #include "openttd.h"
 #include "debug.h"
 #include "variables.h"
-#include "saveload.h"
 #include "md5.h"
 #include "newgrf.h"
 #include "newgrf_config.h"
@@ -495,48 +494,3 @@
 {
 	return (this->grfid & 0x00FFFFFF) == OPENTTD_GRAPHICS_BASE_GRF_ID;
 }
-
-
-static const SaveLoad _grfconfig_desc[] = {
-	    SLE_STR(GRFConfig, filename,         SLE_STR,    0x40),
-	    SLE_VAR(GRFConfig, grfid,            SLE_UINT32),
-	    SLE_ARR(GRFConfig, md5sum,           SLE_UINT8,  16),
-	    SLE_ARR(GRFConfig, param,            SLE_UINT32, 0x80),
-	    SLE_VAR(GRFConfig, num_params,       SLE_UINT8),
-	SLE_CONDVAR(GRFConfig, windows_paletted, SLE_BOOL,   101, SL_MAX_VERSION),
-	SLE_END()
-};
-
-
-static void Save_NGRF()
-{
-	int index = 0;
-
-	for (GRFConfig *c = _grfconfig; c != NULL; c = c->next) {
-		if (HasBit(c->flags, GCF_STATIC)) continue;
-		SlSetArrayIndex(index++);
-		SlObject(c, _grfconfig_desc);
-	}
-}
-
-
-static void Load_NGRF()
-{
-	ClearGRFConfigList(&_grfconfig);
-	while (SlIterateArray() != -1) {
-		GRFConfig *c = CallocT<GRFConfig>(1);
-		SlObject(c, _grfconfig_desc);
-		if (CheckSavegameVersion(101)) c->windows_paletted = (_use_palette == PAL_WINDOWS);
-		AppendToGRFConfigList(&_grfconfig, c);
-	}
-
-	/* Append static NewGRF configuration */
-	AppendStaticGRFConfigs(&_grfconfig);
-}
-
-extern const ChunkHandler _newgrf_chunk_handlers[] = {
-	{ 'NGRF', Save_NGRF, Load_NGRF, CH_ARRAY | CH_LAST }
-};
-
-
-
--- a/src/newgrf_house.cpp
+++ b/src/newgrf_house.cpp
@@ -34,53 +34,6 @@
 
 HouseOverrideManager _house_mngr(NEW_HOUSE_OFFSET, HOUSE_MAX, INVALID_HOUSE_ID);
 
-/**
- * Check and update town and house values.
- *
- * Checked are the HouseIDs. Updated are the
- * town population the number of houses per
- * town, the town radius and the max passengers
- * of the town.
- */
-void UpdateHousesAndTowns()
-{
-	Town *town;
-	InitializeBuildingCounts();
-
-	/* Reset town population and num_houses */
-	FOR_ALL_TOWNS(town) {
-		town->population = 0;
-		town->num_houses = 0;
-	}
-
-	for (TileIndex t = 0; t < MapSize(); t++) {
-		HouseID house_id;
-
-		if (!IsTileType(t, MP_HOUSE)) continue;
-
-		house_id = GetHouseType(t);
-		if (!GetHouseSpecs(house_id)->enabled && house_id >= NEW_HOUSE_OFFSET) {
-			/* The specs for this type of house are not available any more, so
-			 * replace it with the substitute original house type. */
-			house_id = _house_mngr.GetSubstituteID(house_id);
-			SetHouseType(t, house_id);
-		}
-
-		town = GetTownByTile(t);
-		IncreaseBuildingCount(town, house_id);
-		if (IsHouseCompleted(t)) town->population += GetHouseSpecs(house_id)->population;
-
-		/* Increase the number of houses for every house, but only once. */
-		if (GetHouseNorthPart(house_id) == 0) town->num_houses++;
-	}
-
-	/* Update the population and num_house dependant values */
-	FOR_ALL_TOWNS(town) {
-		UpdateTownRadius(town);
-		UpdateTownMaxPass(town);
-	}
-}
-
 HouseClassID AllocateHouseClassID(byte grf_class_id, uint32 grfid)
 {
 	/* Start from 1 because 0 means that no class has been assigned. */
--- a/src/newgrf_house.h
+++ b/src/newgrf_house.h
@@ -7,6 +7,7 @@
 
 #include "town_type.h"
 #include "newgrf_callbacks.h"
+#include "tile_cmd.h"
 
 /**
  * Makes class IDs unique to each GRF file.
@@ -26,8 +27,6 @@
 	uint8  class_id;  ////< The class id within the grf file
 };
 
-void UpdateHousesAndTowns();
-
 HouseClassID AllocateHouseClassID(byte grf_class_id, uint32 grfid);
 
 void InitializeBuildingCounts();
--- a/src/newgrf_station.h
+++ b/src/newgrf_station.h
@@ -13,6 +13,7 @@
 #include "strings_type.h"
 #include "sprite.h"
 #include "direction_type.h"
+#include "newgrf.h"
 
 enum StationClassID {
 	STAT_CLASS_BEGIN = 0,    ///< the lowest valid value
deleted file mode 100644
--- a/src/oldloader.cpp
+++ /dev/null
@@ -1,1734 +0,0 @@
-/* $Id$ */
-
-/** @file oldloader.cpp Loading of old TTD(patch) savegames. */
-
-#include "stdafx.h"
-#include "openttd.h"
-#include "station_map.h"
-#include "town.h"
-#include "industry.h"
-#include "company_func.h"
-#include "company_base.h"
-#include "aircraft.h"
-#include "roadveh.h"
-#include "ship.h"
-#include "train.h"
-#include "signs_base.h"
-#include "debug.h"
-#include "depot_base.h"
-#include "newgrf_config.h"
-#include "ai/ai.h"
-#include "ai/default/default.h"
-#include "zoom_func.h"
-#include "functions.h"
-#include "date_func.h"
-#include "vehicle_func.h"
-#include "variables.h"
-#include "saveload.h"
-#include "strings_func.h"
-#include "effectvehicle_base.h"
-
-#include "table/strings.h"
-
-enum {
-	HEADER_SIZE = 49,
-	BUFFER_SIZE = 4096,
-
-	OLD_MAP_SIZE = 256 * 256
-};
-
-struct LoadgameState {
-	FILE *file;
-
-	uint chunk_size;
-
-	bool decoding;
-	byte decode_char;
-
-	uint buffer_count;
-	uint buffer_cur;
-	byte buffer[BUFFER_SIZE];
-
-	uint total_read;
-	bool failed;
-};
-
-/* OldChunk-Type */
-enum OldChunkType {
-	OC_SIMPLE    = 0,
-	OC_NULL      = 1,
-	OC_CHUNK     = 2,
-	OC_ASSERT    = 3,
-	/* 8 bits allocated (256 max) */
-
-	OC_VAR_I8    = 1 << 8,
-	OC_VAR_U8    = 2 << 8,
-	OC_VAR_I16   = 3 << 8,
-	OC_VAR_U16   = 4 << 8,
-	OC_VAR_I32   = 5 << 8,
-	OC_VAR_U32   = 6 << 8,
-	OC_VAR_I64   = 7 << 8,
-	/* 8 bits allocated (256 max) */
-
-	OC_FILE_I8   = 1 << 16,
-	OC_FILE_U8   = 2 << 16,
-	OC_FILE_I16  = 3 << 16,
-	OC_FILE_U16  = 4 << 16,
-	OC_FILE_I32  = 5 << 16,
-	OC_FILE_U32  = 6 << 16,
-	/* 8 bits allocated (256 max) */
-
-	OC_INT8      = OC_VAR_I8   | OC_FILE_I8,
-	OC_UINT8     = OC_VAR_U8   | OC_FILE_U8,
-	OC_INT16     = OC_VAR_I16  | OC_FILE_I16,
-	OC_UINT16    = OC_VAR_U16  | OC_FILE_U16,
-	OC_INT32     = OC_VAR_I32  | OC_FILE_I32,
-	OC_UINT32    = OC_VAR_U32  | OC_FILE_U32,
-
-	OC_TILE      = OC_VAR_U32  | OC_FILE_U16,
-
-	/**
-	 * Dereference the pointer once before writing to it,
-	 * so we do not have to use big static arrays.
-	 */
-	OC_DEREFERENCE_POINTER = 1 << 31,
-
-	OC_END       = 0 ///< End of the whole chunk, all 32 bits set to zero
-};
-
-DECLARE_ENUM_AS_BIT_SET(OldChunkType);
-
-typedef bool OldChunkProc(LoadgameState *ls, int num);
-
-struct OldChunks {
-	OldChunkType type;   ///< Type of field
-	uint32 amount;       ///< Amount of fields
-
-	void *ptr;           ///< Pointer where to save the data (may only be set if offset is 0)
-	uint offset;         ///< Offset from basepointer (may only be set if ptr is NULL)
-	OldChunkProc *proc;  ///< Pointer to function that is called with OC_CHUNK
-};
-
-/* If it fails, check lines above.. */
-assert_compile(sizeof(TileIndex) == 4);
-
-extern SavegameType _savegame_type;
-extern uint32 _ttdp_version;
-
-static uint32 _bump_assert_value;
-static bool   _read_ttdpatch_flags;
-
-static OldChunkType GetOldChunkType(OldChunkType type)     {return (OldChunkType)GB(type, 0, 8);}
-static OldChunkType GetOldChunkVarType(OldChunkType type)  {return (OldChunkType)(GB(type, 8, 8) << 8);}
-static OldChunkType GetOldChunkFileType(OldChunkType type) {return (OldChunkType)(GB(type, 16, 8) << 16);}
-
-static inline byte CalcOldVarLen(OldChunkType type)
-{
-	static const byte type_mem_size[] = {0, 1, 1, 2, 2, 4, 4, 8};
-	byte length = GB(type, 8, 8);
-	assert(length != 0 && length < lengthof(type_mem_size));
-	return type_mem_size[length];
-}
-
-/**
- *
- * Reads a byte from a file (do not call yourself, use ReadByte())
- *
- */
-static byte ReadByteFromFile(LoadgameState *ls)
-{
-	/* To avoid slow reads, we read BUFFER_SIZE of bytes per time
-	and just return a byte per time */
-	if (ls->buffer_cur >= ls->buffer_count) {
-		/* Read some new bytes from the file */
-		int count = (int)fread(ls->buffer, 1, BUFFER_SIZE, ls->file);
-
-		/* We tried to read, but there is nothing in the file anymore.. */
-		if (count == 0) {
-			DEBUG(oldloader, 0, "Read past end of file, loading failed");
-			ls->failed = true;
-		}
-
-		ls->buffer_count = count;
-		ls->buffer_cur   = 0;
-	}
-
-	return ls->buffer[ls->buffer_cur++];
-}
-
-/**
- *
- * Reads a byte from the buffer and decompress if needed
- *
- */
-static byte ReadByte(LoadgameState *ls)
-{
-	/* Old savegames have a nice compression algorithm (RLE)
-	which means that we have a chunk, which starts with a length
-	byte. If that byte is negative, we have to repeat the next byte
-	that many times ( + 1). Else, we need to read that amount of bytes.
-	Works pretty good if you have many zero's behind eachother */
-
-	if (ls->chunk_size == 0) {
-		/* Read new chunk */
-		int8 new_byte = ReadByteFromFile(ls);
-
-		if (new_byte < 0) {
-			/* Repeat next char for new_byte times */
-			ls->decoding    = true;
-			ls->decode_char = ReadByteFromFile(ls);
-			ls->chunk_size  = -new_byte + 1;
-		} else {
-			ls->decoding    = false;
-			ls->chunk_size  = new_byte + 1;
-		}
-	}
-
-	ls->total_read++;
-	ls->chunk_size--;
-
-	return ls->decoding ? ls->decode_char : ReadByteFromFile(ls);
-}
-
-static inline uint16 ReadUint16(LoadgameState *ls)
-{
-	byte x = ReadByte(ls);
-	return x | ReadByte(ls) << 8;
-}
-
-static inline uint32 ReadUint32(LoadgameState *ls)
-{
-	uint16 x = ReadUint16(ls);
-	return x | ReadUint16(ls) << 16;
-}
-
-/**
- *
- * Loads a chunk from the old savegame
- *
- */
-static bool LoadChunk(LoadgameState *ls, void *base, const OldChunks *chunks)
-{
-	const OldChunks *chunk = chunks;
-	byte *base_ptr = (byte*)base;
-
-	while (chunk->type != OC_END) {
-		byte *ptr = (byte*)chunk->ptr;
-		if ((chunk->type & OC_DEREFERENCE_POINTER) != 0) ptr = *(byte**)ptr;
-
-		for (uint i = 0; i < chunk->amount; i++) {
-			if (ls->failed) return false;
-
-			/* Handle simple types */
-			if (GetOldChunkType(chunk->type) != 0) {
-				switch (GetOldChunkType(chunk->type)) {
-					/* Just read the byte and forget about it */
-					case OC_NULL: ReadByte(ls); break;
-
-					case OC_CHUNK:
-						/* Call function, with 'i' as parameter to tell which item we
-						 * are going to read */
-						if (!chunk->proc(ls, i)) return false;
-						break;
-
-					case OC_ASSERT:
-						DEBUG(oldloader, 4, "Assert point: 0x%X / 0x%X", ls->total_read, chunk->offset + _bump_assert_value);
-						if (ls->total_read != chunk->offset + _bump_assert_value) ls->failed = true;
-					default: break;
-				}
-			} else {
-				uint64 res = 0;
-
-				/* Reading from the file: bits 16 to 23 have the FILE type */
-				switch (GetOldChunkFileType(chunk->type)) {
-					case OC_FILE_I8:  res = (int8)ReadByte(ls); break;
-					case OC_FILE_U8:  res = ReadByte(ls); break;
-					case OC_FILE_I16: res = (int16)ReadUint16(ls); break;
-					case OC_FILE_U16: res = ReadUint16(ls); break;
-					case OC_FILE_I32: res = (int32)ReadUint32(ls); break;
-					case OC_FILE_U32: res = ReadUint32(ls); break;
-					default: NOT_REACHED();
-				}
-
-				/* Sanity check */
-				assert(base_ptr != NULL || chunk->ptr != NULL);
-
-				/* Writing to the var: bits 8 to 15 have the VAR type */
-				if (chunk->ptr == NULL) ptr = base_ptr + chunk->offset;
-
-				/* Write the data */
-				switch (GetOldChunkVarType(chunk->type)) {
-					case OC_VAR_I8: *(int8  *)ptr = GB(res, 0, 8); break;
-					case OC_VAR_U8: *(uint8 *)ptr = GB(res, 0, 8); break;
-					case OC_VAR_I16:*(int16 *)ptr = GB(res, 0, 16); break;
-					case OC_VAR_U16:*(uint16*)ptr = GB(res, 0, 16); break;
-					case OC_VAR_I32:*(int32 *)ptr = res; break;
-					case OC_VAR_U32:*(uint32*)ptr = res; break;
-					case OC_VAR_I64:*(int64 *)ptr = res; break;
-					default: NOT_REACHED();
-				}
-
-				/* Increase pointer base for arrays when looping */
-				if (chunk->amount > 1 && chunk->ptr != NULL) ptr += CalcOldVarLen(chunk->type);
-			}
-		}
-
-		chunk++;
-	}
-
-	return true;
-}
-
-/**
- *
- * Initialize some data before reading
- *
- */
-static void InitLoading(LoadgameState *ls)
-{
-	ls->chunk_size   = 0;
-	ls->total_read   = 0;
-	ls->failed       = false;
-
-	ls->decoding     = false;
-	ls->decode_char  = 0;
-
-	ls->buffer_cur   = 0;
-	ls->buffer_count = 0;
-	memset(ls->buffer, 0, BUFFER_SIZE);
-
-	_bump_assert_value = 0;
-
-	_savegame_type   = SGT_TTD;
-	_ttdp_version    = 0;
-
-	_read_ttdpatch_flags = false;
-}
-
-
-/*
- * Begin -- Stuff to fix the savegames to be OpenTTD compatible
- */
-
-extern uint32 GetOldTownName(uint32 townnameparts, byte old_town_name_type);
-
-static void FixOldTowns()
-{
-	Town *town;
-
-	/* Convert town-names if needed */
-	FOR_ALL_TOWNS(town) {
-		if (IsInsideMM(town->townnametype, 0x20C1, 0x20C3)) {
-			town->townnametype = SPECSTR_TOWNNAME_ENGLISH + _settings_game.game_creation.town_name;
-			town->townnameparts = GetOldTownName(town->townnameparts, _settings_game.game_creation.town_name);
-		}
-	}
-}
-
-static StringID *_old_vehicle_names = NULL;
-
-static void FixOldVehicles()
-{
-	Vehicle* v;
-
-	FOR_ALL_VEHICLES(v) {
-		v->name = CopyFromOldName(_old_vehicle_names[v->index]);
-
-		/* We haven't used this bit for stations for ages */
-		if (v->type == VEH_ROAD &&
-				v->u.road.state != RVSB_IN_DEPOT &&
-				v->u.road.state != RVSB_WORMHOLE) {
-			ClrBit(v->u.road.state, RVS_IS_STOPPING);
-		}
-
-		/* The subtype should be 0, but it sometimes isn't :( */
-		if (v->type == VEH_ROAD) v->subtype = 0;
-
-		/* Sometimes primary vehicles would have a nothing (invalid) order
-		 * or vehicles that could not have an order would still have a
-		 * (loading) order which causes assertions and the like later on.
-		 */
-		if (!IsCompanyBuildableVehicleType(v) ||
-				(v->IsPrimaryVehicle() && v->current_order.IsType(OT_NOTHING))) {
-			v->current_order.MakeDummy();
-		}
-
-		/* Shared orders are fixed in AfterLoadVehicles now */
-	}
-}
-
-/*
- * End -- Stuff to fix the savegames to be OpenTTD compatible
- */
-
-
-/* Help:
- *  - OCL_SVAR: load 'type' to offset 'offset' in a struct of type 'base', which must also
- *       be given via base in LoadChunk() as real pointer
- *  - OCL_VAR: load 'type' to a global var
- *  - OCL_END: every struct must end with this
- *  - OCL_NULL: read 'amount' of bytes and send them to /dev/null or something
- *  - OCL_CHUNK: load an other proc to load a part of the savegame, 'amount' times
- *  - OCL_ASSERT: to check if we are really at the place we expect to be.. because old savegames are too binary to be sure ;)
- */
-#define OCL_SVAR(type, base, offset)         { type,          1, NULL,    (uint)cpp_offsetof(base, offset), NULL }
-#define OCL_VAR(type, amount, pointer)       { type,     amount, pointer, 0,                      NULL }
-#define OCL_END()                                   { OC_END,        0, NULL,    0,                      NULL }
-#define OCL_NULL(amount)                            { OC_NULL,  amount, NULL,    0,                      NULL }
-#define OCL_CHUNK(amount, proc)                     { OC_CHUNK, amount, NULL,    0,                      proc }
-#define OCL_ASSERT(size)                            { OC_ASSERT,     1, NULL, size,                      NULL }
-
-/* The savegames has some hard-coded pointers, because it always enters the same
-    piece of memory.. we don't.. so we need to remap ;)
-   Old Towns are 94 bytes big
-   Old Orders are 2 bytes big */
-#define REMAP_TOWN_IDX(x) ((x) - (0x0459154 - 0x0458EF0)) / 94
-#define REMAP_ORDER_IDX(x) ((x) - (0x045AB08 - 0x0458EF0)) / 2
-
-extern TileIndex *_animated_tile_list;
-extern uint _animated_tile_count;
-extern char *_old_name_array;
-
-static byte   _old_vehicle_multiplier;
-static uint8  *_old_map3;
-static uint32 _old_town_index;
-static uint16 _old_string_id;
-static uint16 _old_string_id_2;
-static uint16 _old_extra_chunk_nums;
-
-static void ReadTTDPatchFlags()
-{
-	if (_read_ttdpatch_flags) return;
-
-	_read_ttdpatch_flags = true;
-
-	/* TTDPatch misuses _old_map3 for flags.. read them! */
-	_old_vehicle_multiplier = _old_map3[0];
-	/* Somehow.... there was an error in some savegames, so 0 becomes 1
-	and 1 becomes 2. The rest of the values are okay */
-	if (_old_vehicle_multiplier < 2) _old_vehicle_multiplier++;
-
-	_old_vehicle_names = MallocT<StringID>(_old_vehicle_multiplier * 850);
-
-	/* TTDPatch increases the Vehicle-part in the middle of the game,
-	so if the multipler is anything else but 1, the assert fails..
-	bump the assert value so it doesn't!
-	(1 multipler == 850 vehicles
-	1 vehicle   == 128 bytes */
-	_bump_assert_value = (_old_vehicle_multiplier - 1) * 850 * 128;
-
-	for (uint i = 0; i < 17; i++) { // check tile 0, too
-		if (_old_map3[i] != 0) _savegame_type = SGT_TTDP1;
-	}
-
-	/* Check if we have a modern TTDPatch savegame (has extra data all around) */
-	if (memcmp(&_old_map3[0x1FFFA], "TTDp", 4) == 0) _savegame_type = SGT_TTDP2;
-
-	_old_extra_chunk_nums = _old_map3[_savegame_type == SGT_TTDP2 ? 0x1FFFE : 0x2];
-
-	/* Clean the misused places */
-	for (uint i = 0;       i < 17;      i++) _old_map3[i] = 0;
-	for (uint i = 0x1FE00; i < 0x20000; i++) _old_map3[i] = 0;
-
-	if (_savegame_type == SGT_TTDP2) DEBUG(oldloader, 2, "Found TTDPatch game");
-
-	DEBUG(oldloader, 3, "Vehicle-multiplier is set to %d (%d vehicles)", _old_vehicle_multiplier, _old_vehicle_multiplier * 850);
-}
-
-static const OldChunks town_chunk[] = {
-	OCL_SVAR(   OC_TILE, Town, xy ),
-	OCL_NULL( 2 ),         ///< population,        no longer in use
-	OCL_SVAR( OC_UINT16, Town, townnametype ),
-	OCL_SVAR( OC_UINT32, Town, townnameparts ),
-	OCL_SVAR(  OC_UINT8, Town, grow_counter ),
-	OCL_NULL( 1 ),         ///< sort_index,        no longer in use
-	OCL_NULL( 4 ),         ///< sign-coordinates,  no longer in use
-	OCL_NULL( 2 ),         ///< namewidth,         no longer in use
-	OCL_SVAR( OC_UINT16, Town, flags12 ),
-	OCL_NULL( 10 ),        ///< radius,            no longer in use
-
-	OCL_SVAR( OC_UINT16, Town, ratings[0] ),
-	OCL_SVAR( OC_UINT16, Town, ratings[1] ),
-	OCL_SVAR( OC_UINT16, Town, ratings[2] ),
-	OCL_SVAR( OC_UINT16, Town, ratings[3] ),
-	OCL_SVAR( OC_UINT16, Town, ratings[4] ),
-	OCL_SVAR( OC_UINT16, Town, ratings[5] ),
-	OCL_SVAR( OC_UINT16, Town, ratings[6] ),
-	OCL_SVAR( OC_UINT16, Town, ratings[7] ),
-
-	/* XXX - This is pretty odd.. we read 32bit, but only write 16bit.. sure there is
-	nothing changed ? ? */
-	OCL_SVAR( OC_FILE_U32 | OC_VAR_U16, Town, have_ratings ),
-	OCL_SVAR( OC_FILE_U32 | OC_VAR_U16, Town, statues ),
-	OCL_NULL( 2 ),         ///< num_houses,        no longer in use
-	OCL_SVAR(  OC_UINT8, Town, time_until_rebuild ),
-	OCL_SVAR(  OC_UINT8, Town, growth_rate ),
-
-	OCL_SVAR( OC_UINT16, Town, new_max_pass ),
-	OCL_SVAR( OC_UINT16, Town, new_max_mail ),
-	OCL_SVAR( OC_UINT16, Town, new_act_pass ),
-	OCL_SVAR( OC_UINT16, Town, new_act_mail ),
-	OCL_SVAR( OC_UINT16, Town, max_pass ),
-	OCL_SVAR( OC_UINT16, Town, max_mail ),
-	OCL_SVAR( OC_UINT16, Town, act_pass ),
-	OCL_SVAR( OC_UINT16, Town, act_mail ),
-
-	OCL_SVAR(  OC_UINT8, Town, pct_pass_transported ),
-	OCL_SVAR(  OC_UINT8, Town, pct_mail_transported ),
-
-	OCL_SVAR( OC_UINT16, Town, new_act_food ),
-	OCL_SVAR( OC_UINT16, Town, new_act_water ),
-	OCL_SVAR( OC_UINT16, Town, act_food ),
-	OCL_SVAR( OC_UINT16, Town, act_water ),
-
-	OCL_SVAR(  OC_UINT8, Town, road_build_months ),
-	OCL_SVAR(  OC_UINT8, Town, fund_buildings_months ),
-
-	OCL_NULL( 8 ),         ///< some junk at the end of the record
-
-	OCL_END()
-};
-static bool LoadOldTown(LoadgameState *ls, int num)
-{
-	Town *t = new (num) Town();
-	if (!LoadChunk(ls, t, town_chunk)) return false;
-
-	if (t->xy == 0) t->xy = INVALID_TILE;
-
-	return true;
-}
-
-static uint16 _old_order;
-static const OldChunks order_chunk[] = {
-	OCL_VAR ( OC_UINT16,   1, &_old_order ),
-	OCL_END()
-};
-
-static bool LoadOldOrder(LoadgameState *ls, int num)
-{
-	if (!LoadChunk(ls, NULL, order_chunk)) return false;
-
-	new (num) Order(UnpackOldOrder(_old_order));
-
-	/* Relink the orders to eachother (in TTD(Patch) the orders for one
-	vehicle are behind eachother, with an invalid order (OT_NOTHING) as indication that
-	it is the last order */
-	if (num > 0 && GetOrder(num)->IsValid())
-		GetOrder(num - 1)->next = GetOrder(num);
-
-	return true;
-}
-
-static bool LoadOldAnimTileList(LoadgameState *ls, int num)
-{
-	/* This is sligthly hackish - we must load a chunk into an array whose
-	 * address isn't static, but instead pointed to by _animated_tile_list.
-	 * To achieve that, create an OldChunks list on the stack on the fly.
-	 * The list cannot be static because the value of _animated_tile_list
-	 * can change between calls. */
-
-	const OldChunks anim_chunk[] = {
-		OCL_VAR (   OC_TILE, 256, _animated_tile_list ),
-		OCL_END ()
-	};
-
-	if (!LoadChunk(ls, NULL, anim_chunk)) return false;
-
-	/* Update the animated tile counter by counting till the first zero in the array */
-	for (_animated_tile_count = 0; _animated_tile_count < 256; _animated_tile_count++) {
-		if (_animated_tile_list[_animated_tile_count] == 0) break;
-	}
-
-	return true;
-}
-
-static const OldChunks depot_chunk[] = {
-	OCL_SVAR(   OC_TILE, Depot, xy ),
-	OCL_VAR ( OC_UINT32,   1, &_old_town_index ),
-	OCL_END()
-};
-
-static bool LoadOldDepot(LoadgameState *ls, int num)
-{
-	Depot *d = new (num) Depot();
-	if (!LoadChunk(ls, d, depot_chunk)) return false;
-
-	if (d->xy != 0) {
-		GetDepot(num)->town_index = REMAP_TOWN_IDX(_old_town_index);
-	} else {
-		d->xy = INVALID_TILE;
-	}
-
-	return true;
-}
-
-static int32 _old_price;
-static uint16 _old_price_frac;
-static const OldChunks price_chunk[] = {
-	OCL_VAR (  OC_INT32,   1, &_old_price ),
-	OCL_VAR ( OC_UINT16,   1, &_old_price_frac ),
-	OCL_END()
-};
-
-static bool LoadOldPrice(LoadgameState *ls, int num)
-{
-	if (!LoadChunk(ls, NULL, price_chunk)) return false;
-
-	/* We use a struct to store the prices, but they are ints in a row..
-	so just access the struct as an array of int32's */
-	((Money*)&_price)[num] = _old_price;
-	_price_frac[num] = _old_price_frac;
-
-	return true;
-}
-
-static const OldChunks cargo_payment_rate_chunk[] = {
-	OCL_VAR (  OC_INT32,   1, &_old_price ),
-	OCL_VAR ( OC_UINT16,   1, &_old_price_frac ),
-
-	OCL_NULL( 2 ),         ///< Junk
-	OCL_END()
-};
-
-static bool LoadOldCargoPaymentRate(LoadgameState *ls, int num)
-{
-	if (!LoadChunk(ls, NULL, cargo_payment_rate_chunk)) return false;
-
-	_cargo_payment_rates[num] = -_old_price;
-	_cargo_payment_rates_frac[num] = _old_price_frac;
-
-	return true;
-}
-
-static uint   _current_station_id;
-static uint16 _waiting_acceptance;
-static uint8  _cargo_source;
-static uint8  _cargo_days;
-
-static const OldChunks goods_chunk[] = {
-	OCL_VAR ( OC_UINT16, 1,          &_waiting_acceptance ),
-	OCL_SVAR(  OC_UINT8, GoodsEntry, days_since_pickup ),
-	OCL_SVAR(  OC_UINT8, GoodsEntry, rating ),
-	OCL_VAR (  OC_UINT8, 1,          &_cargo_source ),
-	OCL_VAR (  OC_UINT8, 1,          &_cargo_days ),
-	OCL_SVAR(  OC_UINT8, GoodsEntry, last_speed ),
-	OCL_SVAR(  OC_UINT8, GoodsEntry, last_age ),
-
-	OCL_END()
-};
-
-static bool LoadOldGood(LoadgameState *ls, int num)
-{
-	Station *st = GetStation(_current_station_id);
-	GoodsEntry *ge = &st->goods[num];
-	bool ret = LoadChunk(ls, ge, goods_chunk);
-	if (!ret) return false;
-
-	SB(ge->acceptance_pickup, GoodsEntry::ACCEPTANCE, 1, HasBit(_waiting_acceptance, 15));
-	SB(ge->acceptance_pickup, GoodsEntry::PICKUP, 1, _cargo_source != 0xFF);
-	if (GB(_waiting_acceptance, 0, 12) != 0) {
-		CargoPacket *cp = new CargoPacket();
-		cp->source          = (_cargo_source == 0xFF) ? INVALID_STATION : _cargo_source;
-		cp->count           = GB(_waiting_acceptance, 0, 12);
-		cp->days_in_transit = _cargo_days;
-		ge->cargo.Append(cp);
-	}
-	return ret;
-}
-
-static const OldChunks station_chunk[] = {
-	OCL_SVAR(   OC_TILE, Station, xy ),
-	OCL_VAR ( OC_UINT32,   1, &_old_town_index ),
-
-	OCL_NULL( 4 ), ///< bus/lorry tile
-	OCL_SVAR(   OC_TILE, Station, train_tile ),
-	OCL_SVAR(   OC_TILE, Station, airport_tile ),
-	OCL_SVAR(   OC_TILE, Station, dock_tile ),
-	OCL_SVAR(  OC_UINT8, Station, trainst_w ),
-
-	OCL_NULL( 1 ),         ///< sort-index, no longer in use
-	OCL_NULL( 2 ),         ///< sign-width, no longer in use
-
-	OCL_VAR ( OC_UINT16,   1, &_old_string_id ),
-
-	OCL_NULL( 4 ),         ///< sign left/top, no longer in use
-
-	OCL_SVAR( OC_UINT16, Station, had_vehicle_of_type ),
-
-	OCL_CHUNK( 12, LoadOldGood ),
-
-	OCL_SVAR(  OC_UINT8, Station, time_since_load ),
-	OCL_SVAR(  OC_UINT8, Station, time_since_unload ),
-	OCL_SVAR(  OC_UINT8, Station, delete_ctr ),
-	OCL_SVAR(  OC_UINT8, Station, owner ),
-	OCL_SVAR(  OC_UINT8, Station, facilities ),
-	OCL_SVAR(  OC_UINT8, Station, airport_type ),
-	/* Bus/truck status, no longer in use
-	 * Blocked months
-	 * Unknown
-	 */
-	OCL_NULL( 4 ),
-	OCL_SVAR( OC_FILE_U16 | OC_VAR_U32, Station, airport_flags ),
-	OCL_NULL( 2 ),         ///< last_vehicle. now last_vehicle_type
-
-	OCL_NULL( 4 ),         ///< Junk at end of chunk
-
-	OCL_END()
-};
-static bool LoadOldStation(LoadgameState *ls, int num)
-{
-	Station *st = new (num) Station();
-	_current_station_id = num;
-
-	if (!LoadChunk(ls, st, station_chunk))
-		return false;
-
-	if (st->xy != 0) {
-		st->town    = GetTown(REMAP_TOWN_IDX(_old_town_index));
-		st->string_id = RemapOldStringID(_old_string_id);
-	} else {
-		st->xy = INVALID_TILE;
-	}
-
-	return true;
-}
-
-static const OldChunks industry_chunk[] = {
-	OCL_SVAR(   OC_TILE, Industry, xy ),
-	OCL_VAR ( OC_UINT32,   1, &_old_town_index ),
-	OCL_SVAR(  OC_UINT8, Industry, width ),
-	OCL_SVAR(  OC_UINT8, Industry, height ),
-	OCL_NULL( 2 ),  ///< used to be industry's produced_cargo
-
-	OCL_SVAR( OC_UINT16, Industry, produced_cargo_waiting[0] ),
-	OCL_SVAR( OC_UINT16, Industry, produced_cargo_waiting[1] ),
-
-	OCL_SVAR(  OC_UINT8, Industry, production_rate[0] ),
-	OCL_SVAR(  OC_UINT8, Industry, production_rate[1] ),
-
-	OCL_NULL( 3 ),  ///< used to be industry's accepts_cargo
-
-	OCL_SVAR(  OC_UINT8, Industry, prod_level ),
-
-	OCL_SVAR( OC_UINT16, Industry, this_month_production[0] ),
-	OCL_SVAR( OC_UINT16, Industry, this_month_production[1] ),
-	OCL_SVAR( OC_UINT16, Industry, this_month_transported[0] ),
-	OCL_SVAR( OC_UINT16, Industry, this_month_transported[1] ),
-
-	OCL_SVAR(  OC_UINT8, Industry, last_month_pct_transported[0] ),
-	OCL_SVAR(  OC_UINT8, Industry, last_month_pct_transported[1] ),
-
-	OCL_SVAR( OC_UINT16, Industry, last_month_production[0] ),
-	OCL_SVAR( OC_UINT16, Industry, last_month_production[1] ),
-	OCL_SVAR( OC_UINT16, Industry, last_month_transported[0] ),
-	OCL_SVAR( OC_UINT16, Industry, last_month_transported[1] ),
-
-	OCL_SVAR(  OC_UINT8, Industry, type ),
-	OCL_SVAR(  OC_UINT8, Industry, owner ),
-	OCL_SVAR(  OC_UINT8, Industry, random_color ),
-	OCL_SVAR( OC_FILE_U8 | OC_VAR_I32, Industry, last_prod_year ),
-	OCL_SVAR( OC_UINT16, Industry, counter ),
-	OCL_SVAR(  OC_UINT8, Industry, was_cargo_delivered ),
-
-	OCL_NULL( 9 ), ///< Random junk at the end of this chunk
-
-	OCL_END()
-};
-
-static bool LoadOldIndustry(LoadgameState *ls, int num)
-{
-	Industry *i = new (num) Industry();
-	if (!LoadChunk(ls, i, industry_chunk)) return false;
-
-	if (i->xy != 0) {
-		i->town = GetTown(REMAP_TOWN_IDX(_old_town_index));
-		IncIndustryTypeCount(i->type);
-	} else {
-		i->xy = INVALID_TILE;
-	}
-
-	return true;
-}
-
-static CompanyID _current_company_id;
-static int32 _old_yearly;
-
-static const OldChunks _company_yearly_chunk[] = {
-	OCL_VAR(  OC_INT32,   1, &_old_yearly ),
-	OCL_END()
-};
-
-static bool OldCompanyYearly(LoadgameState *ls, int num)
-{
-	int i;
-	Company *c = GetCompany(_current_company_id);
-
-	for (i = 0; i < 13; i++) {
-		if (!LoadChunk(ls, NULL, _company_yearly_chunk)) return false;
-
-		c->yearly_expenses[num][i] = _old_yearly;
-	}
-
-	return true;
-}
-
-static const OldChunks _company_economy_chunk[] = {
-	OCL_SVAR( OC_FILE_I32 | OC_VAR_I64, CompanyEconomyEntry, income ),
-	OCL_SVAR( OC_FILE_I32 | OC_VAR_I64, CompanyEconomyEntry, expenses ),
-	OCL_SVAR( OC_INT32,                 CompanyEconomyEntry, delivered_cargo ),
-	OCL_SVAR( OC_INT32,                 CompanyEconomyEntry, performance_history ),
-	OCL_SVAR( OC_FILE_I32 | OC_VAR_I64, CompanyEconomyEntry, company_value ),
-
-	OCL_END()
-};
-
-static bool OldCompanyEconomy(LoadgameState *ls, int num)
-{
-	int i;
-	Company *c = GetCompany(_current_company_id);
-
-	if (!LoadChunk(ls, &c->cur_economy, _company_economy_chunk)) return false;
-
-	/* Don't ask, but the number in TTD(Patch) are inversed to OpenTTD */
-	c->cur_economy.income   = -c->cur_economy.income;
-	c->cur_economy.expenses = -c->cur_economy.expenses;
-
-	for (i = 0; i < 24; i++) {
-		if (!LoadChunk(ls, &c->old_economy[i], _company_economy_chunk)) return false;
-
-		c->old_economy[i].income   = -c->old_economy[i].income;
-		c->old_economy[i].expenses = -c->old_economy[i].expenses;
-	}
-
-	return true;
-}
-
-static const OldChunks _company_ai_build_rec_chunk[] = {
-	OCL_SVAR(   OC_TILE, AiBuildRec, spec_tile ),
-	OCL_SVAR(   OC_TILE, AiBuildRec, use_tile ),
-	OCL_SVAR(  OC_UINT8, AiBuildRec, rand_rng ),
-	OCL_SVAR(  OC_UINT8, AiBuildRec, cur_building_rule ),
-	OCL_SVAR(  OC_UINT8, AiBuildRec, unk6 ),
-	OCL_SVAR(  OC_UINT8, AiBuildRec, unk7 ),
-	OCL_SVAR(  OC_UINT8, AiBuildRec, buildcmd_a ),
-	OCL_SVAR(  OC_UINT8, AiBuildRec, buildcmd_b ),
-	OCL_SVAR(  OC_UINT8, AiBuildRec, direction ),
-	OCL_SVAR(  OC_UINT8, AiBuildRec, cargo ),
-
-	OCL_NULL( 8 ),  ///< Junk...
-
-	OCL_END()
-};
-
-static bool OldLoadAIBuildRec(LoadgameState *ls, int num)
-{
-	Company *c = GetCompany(_current_company_id);
-
-	switch (num) {
-		case 0: return LoadChunk(ls, &_companies_ai[c->index].src,  _company_ai_build_rec_chunk);
-		case 1: return LoadChunk(ls, &_companies_ai[c->index].dst,  _company_ai_build_rec_chunk);
-		case 2: return LoadChunk(ls, &_companies_ai[c->index].mid1, _company_ai_build_rec_chunk);
-		case 3: return LoadChunk(ls, &_companies_ai[c->index].mid2, _company_ai_build_rec_chunk);
-	}
-
-	return false;
-}
-static const OldChunks _company_ai_chunk[] = {
-	OCL_SVAR(  OC_UINT8, CompanyAI, state ),
-	OCL_NULL( 1 ),         ///< Junk
-	OCL_SVAR(  OC_UINT8, CompanyAI, state_mode ),
-	OCL_SVAR( OC_UINT16, CompanyAI, state_counter ),
-	OCL_SVAR( OC_UINT16, CompanyAI, timeout_counter ),
-
-	OCL_CHUNK( 4, OldLoadAIBuildRec ),
-
-	OCL_NULL( 20 ),        ///< More junk
-
-	OCL_SVAR(  OC_UINT8, CompanyAI, cargo_type ),
-	OCL_SVAR(  OC_UINT8, CompanyAI, num_wagons ),
-	OCL_SVAR(  OC_UINT8, CompanyAI, build_kind ),
-	OCL_SVAR(  OC_UINT8, CompanyAI, num_build_rec ),
-	OCL_SVAR(  OC_UINT8, CompanyAI, num_loco_to_build ),
-	OCL_SVAR(  OC_UINT8, CompanyAI, num_want_fullload ),
-
-	OCL_NULL( 14 ),        ///< Oh no more junk :|
-
-	OCL_NULL( 2 ),         ///< Loco-id, not used
-
-	OCL_SVAR( OC_UINT16, CompanyAI, wagon_list[0] ),
-	OCL_SVAR( OC_UINT16, CompanyAI, wagon_list[1] ),
-	OCL_SVAR( OC_UINT16, CompanyAI, wagon_list[2] ),
-	OCL_SVAR( OC_UINT16, CompanyAI, wagon_list[3] ),
-	OCL_SVAR( OC_UINT16, CompanyAI, wagon_list[4] ),
-	OCL_SVAR( OC_UINT16, CompanyAI, wagon_list[5] ),
-	OCL_SVAR( OC_UINT16, CompanyAI, wagon_list[6] ),
-	OCL_SVAR( OC_UINT16, CompanyAI, wagon_list[7] ),
-	OCL_SVAR( OC_UINT16, CompanyAI, wagon_list[8] ),
-	OCL_SVAR(  OC_UINT8, CompanyAI, order_list_blocks[0] ),
-	OCL_SVAR(  OC_UINT8, CompanyAI, order_list_blocks[1] ),
-	OCL_SVAR(  OC_UINT8, CompanyAI, order_list_blocks[2] ),
-	OCL_SVAR(  OC_UINT8, CompanyAI, order_list_blocks[3] ),
-	OCL_SVAR(  OC_UINT8, CompanyAI, order_list_blocks[4] ),
-	OCL_SVAR(  OC_UINT8, CompanyAI, order_list_blocks[5] ),
-	OCL_SVAR(  OC_UINT8, CompanyAI, order_list_blocks[6] ),
-	OCL_SVAR(  OC_UINT8, CompanyAI, order_list_blocks[7] ),
-	OCL_SVAR(  OC_UINT8, CompanyAI, order_list_blocks[8] ),
-	OCL_SVAR(  OC_UINT8, CompanyAI, order_list_blocks[9] ),
-	OCL_SVAR(  OC_UINT8, CompanyAI, order_list_blocks[10] ),
-	OCL_SVAR(  OC_UINT8, CompanyAI, order_list_blocks[11] ),
-	OCL_SVAR(  OC_UINT8, CompanyAI, order_list_blocks[12] ),
-	OCL_SVAR(  OC_UINT8, CompanyAI, order_list_blocks[13] ),
-	OCL_SVAR(  OC_UINT8, CompanyAI, order_list_blocks[14] ),
-	OCL_SVAR(  OC_UINT8, CompanyAI, order_list_blocks[15] ),
-	OCL_SVAR(  OC_UINT8, CompanyAI, order_list_blocks[16] ),
-	OCL_SVAR(  OC_UINT8, CompanyAI, order_list_blocks[17] ),
-	OCL_SVAR(  OC_UINT8, CompanyAI, order_list_blocks[18] ),
-	OCL_SVAR(  OC_UINT8, CompanyAI, order_list_blocks[19] ),
-
-	OCL_SVAR( OC_UINT16, CompanyAI, start_tile_a ),
-	OCL_SVAR( OC_UINT16, CompanyAI, start_tile_b ),
-	OCL_SVAR( OC_UINT16, CompanyAI, cur_tile_a ),
-	OCL_SVAR( OC_UINT16, CompanyAI, cur_tile_b ),
-
-	OCL_SVAR(  OC_UINT8, CompanyAI, start_dir_a ),
-	OCL_SVAR(  OC_UINT8, CompanyAI, start_dir_b ),
-	OCL_SVAR(  OC_UINT8, CompanyAI, cur_dir_a ),
-	OCL_SVAR(  OC_UINT8, CompanyAI, cur_dir_b ),
-
-	OCL_SVAR(  OC_UINT8, CompanyAI, banned_tile_count ),
-
-	OCL_SVAR(   OC_TILE, CompanyAI, banned_tiles[0] ),
-	OCL_SVAR(  OC_UINT8, CompanyAI, banned_val[0] ),
-	OCL_SVAR(   OC_TILE, CompanyAI, banned_tiles[1] ),
-	OCL_SVAR(  OC_UINT8, CompanyAI, banned_val[1] ),
-	OCL_SVAR(   OC_TILE, CompanyAI, banned_tiles[2] ),
-	OCL_SVAR(  OC_UINT8, CompanyAI, banned_val[2] ),
-	OCL_SVAR(   OC_TILE, CompanyAI, banned_tiles[3] ),
-	OCL_SVAR(  OC_UINT8, CompanyAI, banned_val[3] ),
-	OCL_SVAR(   OC_TILE, CompanyAI, banned_tiles[4] ),
-	OCL_SVAR(  OC_UINT8, CompanyAI, banned_val[4] ),
-	OCL_SVAR(   OC_TILE, CompanyAI, banned_tiles[5] ),
-	OCL_SVAR(  OC_UINT8, CompanyAI, banned_val[5] ),
-	OCL_SVAR(   OC_TILE, CompanyAI, banned_tiles[6] ),
-	OCL_SVAR(  OC_UINT8, CompanyAI, banned_val[6] ),
-	OCL_SVAR(   OC_TILE, CompanyAI, banned_tiles[7] ),
-	OCL_SVAR(  OC_UINT8, CompanyAI, banned_val[7] ),
-	OCL_SVAR(   OC_TILE, CompanyAI, banned_tiles[8] ),
-	OCL_SVAR(  OC_UINT8, CompanyAI, banned_val[8] ),
-	OCL_SVAR(   OC_TILE, CompanyAI, banned_tiles[9] ),
-	OCL_SVAR(  OC_UINT8, CompanyAI, banned_val[9] ),
-	OCL_SVAR(   OC_TILE, CompanyAI, banned_tiles[10] ),
-	OCL_SVAR(  OC_UINT8, CompanyAI, banned_val[10] ),
-	OCL_SVAR(   OC_TILE, CompanyAI, banned_tiles[11] ),
-	OCL_SVAR(  OC_UINT8, CompanyAI, banned_val[11] ),
-	OCL_SVAR(   OC_TILE, CompanyAI, banned_tiles[12] ),
-	OCL_SVAR(  OC_UINT8, CompanyAI, banned_val[12] ),
-	OCL_SVAR(   OC_TILE, CompanyAI, banned_tiles[13] ),
-	OCL_SVAR(  OC_UINT8, CompanyAI, banned_val[13] ),
-	OCL_SVAR(   OC_TILE, CompanyAI, banned_tiles[14] ),
-	OCL_SVAR(  OC_UINT8, CompanyAI, banned_val[14] ),
-	OCL_SVAR(   OC_TILE, CompanyAI, banned_tiles[15] ),
-	OCL_SVAR(  OC_UINT8, CompanyAI, banned_val[15] ),
-
-	OCL_SVAR(  OC_UINT8, CompanyAI, railtype_to_use ),
-	OCL_SVAR(  OC_UINT8, CompanyAI, route_type_mask ),
-
-	OCL_END()
-};
-
-static bool OldCompanyAI(LoadgameState *ls, int num)
-{
-	return LoadChunk(ls, &_companies_ai[_current_company_id], _company_ai_chunk);
-}
-
-uint8 ai_tick;
-static const OldChunks _company_chunk[] = {
-	OCL_VAR ( OC_UINT16,   1, &_old_string_id ),
-	OCL_SVAR( OC_UINT32, Company, name_2 ),
-	OCL_SVAR( OC_UINT32, Company, face ),
-	OCL_VAR ( OC_UINT16,   1, &_old_string_id_2 ),
-	OCL_SVAR( OC_UINT32, Company, president_name_2 ),
-
-	OCL_SVAR(  OC_INT32, Company, money ),
-	OCL_SVAR(  OC_INT32, Company, current_loan ),
-
-	OCL_SVAR(  OC_UINT8, Company, colour ),
-	OCL_SVAR(  OC_UINT8, Company, money_fraction ),
-	OCL_SVAR(  OC_UINT8, Company, quarters_of_bankrupcy ),
-	OCL_SVAR(  OC_UINT8, Company, bankrupt_asked ),
-	OCL_SVAR( OC_FILE_U32 | OC_VAR_I64, Company, bankrupt_value ),
-	OCL_SVAR( OC_UINT16, Company, bankrupt_timeout ),
-
-	OCL_SVAR( OC_UINT32, Company, cargo_types ),
-
-	OCL_CHUNK( 3, OldCompanyYearly ),
-	OCL_CHUNK( 1, OldCompanyEconomy ),
-
-	OCL_SVAR( OC_FILE_U16 | OC_VAR_I32, Company, inaugurated_year),
-	OCL_SVAR(                  OC_TILE, Company, last_build_coordinate ),
-	OCL_SVAR(                 OC_UINT8, Company, num_valid_stat_ent ),
-
-	OCL_CHUNK( 1, OldCompanyAI ),
-
-	OCL_SVAR(  OC_UINT8, Company, block_preview ),
-	 OCL_VAR(  OC_UINT8,   1, &ai_tick ),
-	OCL_SVAR(  OC_UINT8, Company, avail_railtypes ),
-	OCL_SVAR(   OC_TILE, Company, location_of_HQ ),
-	OCL_SVAR(  OC_UINT8, Company, share_owners[0] ),
-	OCL_SVAR(  OC_UINT8, Company, share_owners[1] ),
-	OCL_SVAR(  OC_UINT8, Company, share_owners[2] ),
-	OCL_SVAR(  OC_UINT8, Company, share_owners[3] ),
-
-	OCL_NULL( 8 ), ///< junk at end of chunk
-
-	OCL_END()
-};
-
-static bool LoadOldCompany(LoadgameState *ls, int num)
-{
-	Company *c = new (num) Company();
-
-	_current_company_id = (CompanyID)num;
-
-	if (!LoadChunk(ls, c, _company_chunk)) return false;
-
-	if (_old_string_id == 0) {
-		delete c;
-		return true;
-	}
-
-	c->name_1 = RemapOldStringID(_old_string_id);
-	c->president_name_1 = RemapOldStringID(_old_string_id_2);
-	_companies_ai[_current_company_id].tick = ai_tick;
-
-	if (num == 0) {
-		/* If the first company has no name, make sure we call it UNNAMED */
-		if (c->name_1 == 0)
-			c->name_1 = STR_SV_UNNAMED;
-	} else {
-		/* Beside some multiplayer maps (1 on 1), which we don't official support,
-		 * all other companys are an AI.. mark them as such */
-		c->is_ai = true;
-	}
-
-	/* Sometimes it is better to not ask.. in old scenarios, the money
-	 * was always 893288 pounds. In the newer versions this is correct,
-	 * but correct for those oldies
-	 * Ps: this also means that if you had exact 893288 pounds, you will go back
-	 * to 100000.. this is a very VERY small chance ;) */
-	if (c->money == 893288) c->money = c->current_loan = 100000;
-
-	_company_colours[num] = c->colour;
-	c->inaugurated_year -= ORIGINAL_BASE_YEAR;
-
-	/* State 20 for AI companies is sell vehicle. Since the AI struct is not
-	 * really figured out as of now, _companies_ai[c->index].cur_veh; needed for 'sell vehicle'
-	 * is NULL and the function will crash. To fix this, just change the state
-	 * to some harmless state, like 'loop vehicle'; 1 */
-	if (!IsHumanCompany((CompanyID)num) && _companies_ai[c->index].state == 20) _companies_ai[c->index].state = 1;
-
-	if (c->is_ai && (!_networking || _network_server) && _ai.enabled)
-		AI_StartNewAI(c->index);
-
-	return true;
-}
-
-static uint32 _old_order_ptr;
-static uint16 _old_next_ptr;
-static uint32 _current_vehicle_id;
-
-static const OldChunks vehicle_train_chunk[] = {
-	OCL_SVAR(  OC_UINT8, VehicleRail, track ),
-	OCL_SVAR(  OC_UINT8, VehicleRail, force_proceed ),
-	OCL_SVAR( OC_UINT16, VehicleRail, crash_anim_pos ),
-	OCL_SVAR(  OC_UINT8, VehicleRail, railtype ),
-
-	OCL_NULL( 5 ), ///< Junk
-
-	OCL_END()
-};
-
-static const OldChunks vehicle_road_chunk[] = {
-	OCL_SVAR(  OC_UINT8, VehicleRoad, state ),
-	OCL_SVAR(  OC_UINT8, VehicleRoad, frame ),
-	OCL_SVAR( OC_UINT16, VehicleRoad, blocked_ctr ),
-	OCL_SVAR(  OC_UINT8, VehicleRoad, overtaking ),
-	OCL_SVAR(  OC_UINT8, VehicleRoad, overtaking_ctr ),
-	OCL_SVAR( OC_UINT16, VehicleRoad, crashed_ctr ),
-	OCL_SVAR(  OC_UINT8, VehicleRoad, reverse_ctr ),
-
-	OCL_NULL( 1 ), ///< Junk
-
-	OCL_END()
-};
-
-static const OldChunks vehicle_ship_chunk[] = {
-	OCL_SVAR(  OC_UINT8, VehicleShip, state ),
-
-	OCL_NULL( 9 ), ///< Junk
-
-	OCL_END()
-};
-
-static const OldChunks vehicle_air_chunk[] = {
-	OCL_SVAR(  OC_UINT8, VehicleAir, pos ),
-	OCL_SVAR(  OC_FILE_U8 | OC_VAR_U16, VehicleAir, targetairport ),
-	OCL_SVAR( OC_UINT16, VehicleAir, crashed_counter ),
-	OCL_SVAR(  OC_UINT8, VehicleAir, state ),
-
-	OCL_NULL( 5 ), ///< Junk
-
-	OCL_END()
-};
-
-static const OldChunks vehicle_effect_chunk[] = {
-	OCL_SVAR( OC_UINT16, VehicleEffect, animation_state ),
-	OCL_SVAR(  OC_UINT8, VehicleEffect, animation_substate ),
-
-	OCL_NULL( 7 ), // Junk
-
-	OCL_END()
-};
-
-static const OldChunks vehicle_disaster_chunk[] = {
-	OCL_SVAR( OC_UINT16, VehicleDisaster, image_override ),
-	OCL_SVAR( OC_UINT16, VehicleDisaster, big_ufo_destroyer_target ),
-
-	OCL_NULL( 6 ), ///< Junk
-
-	OCL_END()
-};
-
-static const OldChunks vehicle_empty_chunk[] = {
-	OCL_NULL( 10 ), ///< Junk
-
-	OCL_END()
-};
-
-static bool LoadOldVehicleUnion(LoadgameState *ls, int num)
-{
-	Vehicle *v = GetVehicle(_current_vehicle_id);
-	uint temp = ls->total_read;
-	bool res;
-
-	switch (v->type) {
-		default: NOT_REACHED();
-		case VEH_INVALID : res = LoadChunk(ls, NULL,           vehicle_empty_chunk);    break;
-		case VEH_TRAIN   : res = LoadChunk(ls, &v->u.rail,     vehicle_train_chunk);    break;
-		case VEH_ROAD    : res = LoadChunk(ls, &v->u.road,     vehicle_road_chunk);     break;
-		case VEH_SHIP    : res = LoadChunk(ls, &v->u.ship,     vehicle_ship_chunk);     break;
-		case VEH_AIRCRAFT: res = LoadChunk(ls, &v->u.air,      vehicle_air_chunk);      break;
-		case VEH_EFFECT  : res = LoadChunk(ls, &v->u.effect,   vehicle_effect_chunk);   break;
-		case VEH_DISASTER: res = LoadChunk(ls, &v->u.disaster, vehicle_disaster_chunk); break;
-	}
-
-	/* This chunk size should always be 10 bytes */
-	if (ls->total_read - temp != 10) {
-		DEBUG(oldloader, 0, "Assert failed in VehicleUnion: invalid chunk size");
-		return false;
-	}
-
-	return res;
-}
-
-static uint16 _cargo_count;
-
-static const OldChunks vehicle_chunk[] = {
-	OCL_SVAR(  OC_UINT8, Vehicle, subtype ),
-
-	OCL_NULL( 2 ),         ///< Hash, calculated automatically
-	OCL_NULL( 2 ),         ///< Index, calculated automatically
-
-	OCL_VAR ( OC_UINT32,   1, &_old_order_ptr ),
-	OCL_VAR ( OC_UINT16,   1, &_old_order ),
-
-	OCL_NULL ( 1 ), ///< num_orders, now calculated
-	OCL_SVAR(  OC_UINT8, Vehicle, cur_order_index ),
-	OCL_SVAR(   OC_TILE, Vehicle, dest_tile ),
-	OCL_SVAR( OC_UINT16, Vehicle, load_unload_time_rem ),
-	OCL_SVAR( OC_FILE_U16 | OC_VAR_U32, Vehicle, date_of_last_service ),
-	OCL_SVAR( OC_UINT16, Vehicle, service_interval ),
-	OCL_SVAR( OC_FILE_U8 | OC_VAR_U16, Vehicle, last_station_visited ),
-	OCL_SVAR(  OC_UINT8, Vehicle, tick_counter ),
-	OCL_SVAR( OC_UINT16, Vehicle, max_speed ),
-
-	OCL_SVAR( OC_FILE_U16 | OC_VAR_I32, Vehicle, x_pos ),
-	OCL_SVAR( OC_FILE_U16 | OC_VAR_I32, Vehicle, y_pos ),
-	OCL_SVAR(  OC_UINT8, Vehicle, z_pos ),
-	OCL_SVAR(  OC_UINT8, Vehicle, direction ),
-	OCL_NULL( 2 ),         ///< x_offs and y_offs, calculated automatically
-	OCL_NULL( 2 ),         ///< x_extent and y_extent, calculated automatically
-	OCL_NULL( 1 ),         ///< z_extent, calculated automatically
-
-	OCL_SVAR(  OC_UINT8, Vehicle, owner ),
-	OCL_SVAR(   OC_TILE, Vehicle, tile ),
-	OCL_SVAR( OC_UINT16, Vehicle, cur_image ),
-
-	OCL_NULL( 8 ),        ///< Vehicle sprite box, calculated automatically
-
-	OCL_SVAR( OC_FILE_U16 | OC_VAR_U8, Vehicle, vehstatus ),
-	OCL_SVAR( OC_UINT16, Vehicle, cur_speed ),
-	OCL_SVAR(  OC_UINT8, Vehicle, subspeed ),
-	OCL_SVAR(  OC_UINT8, Vehicle, acceleration ),
-	OCL_SVAR(  OC_UINT8, Vehicle, progress ),
-
-	OCL_SVAR(  OC_UINT8, Vehicle, cargo_type ),
-	OCL_SVAR( OC_UINT16, Vehicle, cargo_cap ),
-	OCL_VAR ( OC_UINT16, 1,       &_cargo_count ),
-	OCL_VAR (  OC_UINT8, 1,       &_cargo_source ),
-	OCL_VAR (  OC_UINT8, 1,       &_cargo_days ),
-
-	OCL_SVAR( OC_FILE_U16 | OC_VAR_U32, Vehicle, age ),
-	OCL_SVAR( OC_FILE_U16 | OC_VAR_U32, Vehicle, max_age ),
-	OCL_SVAR( OC_FILE_U8 | OC_VAR_I32, Vehicle, build_year ),
-	OCL_SVAR( OC_FILE_U8 | OC_VAR_U16, Vehicle, unitnumber ),
-
-	OCL_SVAR( OC_UINT16, Vehicle, engine_type ),
-
-	OCL_SVAR(  OC_UINT8, Vehicle, spritenum ),
-	OCL_SVAR(  OC_UINT8, Vehicle, day_counter ),
-
-	OCL_SVAR(  OC_UINT8, Vehicle, breakdowns_since_last_service ),
-	OCL_SVAR(  OC_UINT8, Vehicle, breakdown_ctr ),
-	OCL_SVAR(  OC_UINT8, Vehicle, breakdown_delay ),
-	OCL_SVAR(  OC_UINT8, Vehicle, breakdown_chance ),
-
-	OCL_SVAR( OC_UINT16, Vehicle, reliability ),
-	OCL_SVAR( OC_UINT16, Vehicle, reliability_spd_dec ),
-
-	OCL_SVAR( OC_FILE_I32 | OC_VAR_I64, Vehicle, profit_this_year ),
-	OCL_SVAR( OC_FILE_I32 | OC_VAR_I64, Vehicle, profit_last_year ),
-
-	OCL_VAR ( OC_UINT16,   1, &_old_next_ptr ),
-
-	OCL_SVAR( OC_UINT32, Vehicle, value ),
-
-	OCL_VAR ( OC_UINT16,   1, &_old_string_id ),
-
-	OCL_CHUNK( 1, LoadOldVehicleUnion ),
-
-	OCL_NULL( 20 ), ///< Junk at end of struct (TTDPatch has some data in it)
-
-	OCL_END()
-};
-
-bool LoadOldVehicle(LoadgameState *ls, int num)
-{
-	uint i;
-
-	/* Read the TTDPatch flags, because we need some info from it */
-	ReadTTDPatchFlags();
-
-	for (i = 0; i < _old_vehicle_multiplier; i++) {
-		_current_vehicle_id = num * _old_vehicle_multiplier + i;
-
-		/* Read the vehicle type and allocate the right vehicle */
-		Vehicle *v;
-		switch (ReadByte(ls)) {
-			default: NOT_REACHED();
-			case 0x00 /*VEH_INVALID */: v = new (_current_vehicle_id) InvalidVehicle();  break;
-			case 0x10 /*VEH_TRAIN   */: v = new (_current_vehicle_id) Train();           break;
-			case 0x11 /*VEH_ROAD    */: v = new (_current_vehicle_id) RoadVehicle();     break;
-			case 0x12 /*VEH_SHIP    */: v = new (_current_vehicle_id) Ship();            break;
-			case 0x13 /*VEH_AIRCRAFT*/: v = new (_current_vehicle_id) Aircraft();        break;
-			case 0x14 /*VEH_EFFECT  */: v = new (_current_vehicle_id) EffectVehicle();   break;
-			case 0x15 /*VEH_DISASTER*/: v = new (_current_vehicle_id) DisasterVehicle(); break;
-		}
-		if (!LoadChunk(ls, v, vehicle_chunk)) return false;
-
-		/* This should be consistent, else we have a big problem... */
-		if (v->index != _current_vehicle_id) {
-			DEBUG(oldloader, 0, "Loading failed - vehicle-array is invalid");
-			return false;
-		}
-
-		if (_old_order_ptr != 0 && _old_order_ptr != 0xFFFFFFFF) {
-			uint old_id = REMAP_ORDER_IDX(_old_order_ptr);
-			/* There is a maximum of 5000 orders in old savegames, so *if*
-			 * we go over that limit something is very wrong. In that case
-			 * we just assume there are no orders for the vehicle.
-			 */
-			if (old_id < 5000) v->orders.old = GetOrder(old_id);
-		}
-		v->current_order.AssignOrder(UnpackOldOrder(_old_order));
-
-		/* For some reason we need to correct for this */
-		switch (v->spritenum) {
-			case 0xfd: break;
-			case 0xff: v->spritenum = 0xfe; break;
-			default:   v->spritenum >>= 1; break;
-		}
-
-		if (_old_next_ptr != 0xFFFF) v->next = GetVehiclePoolSize() <= _old_next_ptr ? new (_old_next_ptr) InvalidVehicle() : GetVehicle(_old_next_ptr);
-
-		_old_vehicle_names[_current_vehicle_id] = RemapOldStringID(_old_string_id);
-		v->name = NULL;
-
-		/* Vehicle-subtype is different in TTD(Patch) */
-		if (v->type == VEH_EFFECT) v->subtype = v->subtype >> 1;
-
-		if (_cargo_count != 0) {
-			CargoPacket *cp = new CargoPacket((_cargo_source == 0xFF) ? INVALID_STATION : _cargo_source, _cargo_count);
-			cp->days_in_transit = _cargo_days;
-			v->cargo.Append(cp);
-		}
-	}
-
-	return true;
-}
-
-static const OldChunks sign_chunk[] = {
-	OCL_VAR ( OC_UINT16, 1, &_old_string_id ),
-	OCL_SVAR( OC_FILE_U16 | OC_VAR_I32, Sign, x ),
-	OCL_SVAR( OC_FILE_U16 | OC_VAR_I32, Sign, y ),
-	OCL_SVAR( OC_FILE_U16 | OC_VAR_I8, Sign, z ),
-
-	OCL_NULL( 6 ),         ///< Width of sign, no longer in use
-
-	OCL_END()
-};
-
-static bool LoadOldSign(LoadgameState *ls, int num)
-{
-	Sign *si = new (num) Sign();
-	if (!LoadChunk(ls, si, sign_chunk)) return false;
-
-	_old_string_id = RemapOldStringID(_old_string_id);
-	si->name = CopyFromOldName(_old_string_id);
-
-	return true;
-}
-
-static const OldChunks engine_chunk[] = {
-	OCL_SVAR( OC_UINT16, Engine, company_avail ),
-	OCL_SVAR( OC_FILE_U16 | OC_VAR_U32, Engine, intro_date ),
-	OCL_SVAR( OC_FILE_U16 | OC_VAR_U32, Engine, age ),
-	OCL_SVAR( OC_UINT16, Engine, reliability ),
-	OCL_SVAR( OC_UINT16, Engine, reliability_spd_dec ),
-	OCL_SVAR( OC_UINT16, Engine, reliability_start ),
-	OCL_SVAR( OC_UINT16, Engine, reliability_max ),
-	OCL_SVAR( OC_UINT16, Engine, reliability_final ),
-	OCL_SVAR( OC_UINT16, Engine, duration_phase_1 ),
-	OCL_SVAR( OC_UINT16, Engine, duration_phase_2 ),
-	OCL_SVAR( OC_UINT16, Engine, duration_phase_3 ),
-
-	OCL_SVAR(  OC_UINT8, Engine, lifelength ),
-	OCL_SVAR(  OC_UINT8, Engine, flags ),
-	OCL_SVAR(  OC_UINT8, Engine, preview_company_rank ),
-	OCL_SVAR(  OC_UINT8, Engine, preview_wait ),
-
-	OCL_NULL( 2 ), ///< Junk
-
-	OCL_END()
-};
-
-static bool LoadOldEngine(LoadgameState *ls, int num)
-{
-	Engine *e = GetTempDataEngine(num);
-	return LoadChunk(ls, e, engine_chunk);
-}
-
-static bool LoadOldEngineName(LoadgameState *ls, int num)
-{
-	Engine *e = GetTempDataEngine(num);
-	e->name = CopyFromOldName(RemapOldStringID(ReadUint16(ls)));
-	return true;
-}
-
-static const OldChunks subsidy_chunk[] = {
-	OCL_SVAR(  OC_UINT8, Subsidy, cargo_type ),
-	OCL_SVAR(  OC_UINT8, Subsidy, age ),
-	OCL_SVAR(  OC_FILE_U8 | OC_VAR_U16, Subsidy, from ),
-	OCL_SVAR(  OC_FILE_U8 | OC_VAR_U16, Subsidy, to ),
-
-	OCL_END()
-};
-
-static inline bool LoadOldSubsidy(LoadgameState *ls, int num)
-{
-	return LoadChunk(ls, &_subsidies[num], subsidy_chunk);
-}
-
-static const OldChunks game_difficulty_chunk[] = {
-	OCL_SVAR( OC_FILE_U16 |  OC_VAR_U8, DifficultySettings, max_no_competitors ),
-	OCL_SVAR( OC_FILE_U16 |  OC_VAR_U8, DifficultySettings, competitor_start_time ),
-	OCL_SVAR( OC_FILE_U16 |  OC_VAR_U8, DifficultySettings, number_towns ),
-	OCL_SVAR( OC_FILE_U16 |  OC_VAR_U8, DifficultySettings, number_industries ),
-	OCL_SVAR( OC_FILE_U16 | OC_VAR_U32, DifficultySettings, max_loan ),
-	OCL_SVAR( OC_FILE_U16 |  OC_VAR_U8, DifficultySettings, initial_interest ),
-	OCL_SVAR( OC_FILE_U16 |  OC_VAR_U8, DifficultySettings, vehicle_costs ),
-	OCL_SVAR( OC_FILE_U16 |  OC_VAR_U8, DifficultySettings, competitor_speed ),
-	OCL_SVAR( OC_FILE_U16 |  OC_VAR_U8, DifficultySettings, competitor_intelligence ),
-	OCL_SVAR( OC_FILE_U16 |  OC_VAR_U8, DifficultySettings, vehicle_breakdowns ),
-	OCL_SVAR( OC_FILE_U16 |  OC_VAR_U8, DifficultySettings, subsidy_multiplier ),
-	OCL_SVAR( OC_FILE_U16 |  OC_VAR_U8, DifficultySettings, construction_cost ),
-	OCL_SVAR( OC_FILE_U16 |  OC_VAR_U8, DifficultySettings, terrain_type ),
-	OCL_SVAR( OC_FILE_U16 |  OC_VAR_U8, DifficultySettings, quantity_sea_lakes ),
-	OCL_SVAR( OC_FILE_U16 |  OC_VAR_U8, DifficultySettings, economy ),
-	OCL_SVAR( OC_FILE_U16 |  OC_VAR_U8, DifficultySettings, line_reverse_mode ),
-	OCL_SVAR( OC_FILE_U16 |  OC_VAR_U8, DifficultySettings, disasters ),
-	OCL_END()
-};
-
-static inline bool LoadOldGameDifficulty(LoadgameState *ls, int num)
-{
-	bool ret = LoadChunk(ls, &_settings_game.difficulty, game_difficulty_chunk);
-	_settings_game.difficulty.max_loan *= 1000;
-	return ret;
-}
-
-
-static bool LoadOldMapPart1(LoadgameState *ls, int num)
-{
-	uint i;
-
-	for (i = 0; i < OLD_MAP_SIZE; i++) {
-		_m[i].m1 = ReadByte(ls);
-	}
-	for (i = 0; i < OLD_MAP_SIZE; i++) {
-		_m[i].m2 = ReadByte(ls);
-	}
-	for (i = 0; i < OLD_MAP_SIZE; i++) {
-		_old_map3[i * 2] = ReadByte(ls);
-		_old_map3[i * 2 + 1] = ReadByte(ls);
-	}
-	for (i = 0; i < OLD_MAP_SIZE / 4; i++) {
-		byte b = ReadByte(ls);
-		_m[i * 4 + 0].m6 = GB(b, 0, 2);
-		_m[i * 4 + 1].m6 = GB(b, 2, 2);
-		_m[i * 4 + 2].m6 = GB(b, 4, 2);
-		_m[i * 4 + 3].m6 = GB(b, 6, 2);
-	}
-
-	return !ls->failed;
-}
-
-static bool LoadOldMapPart2(LoadgameState *ls, int num)
-{
-	uint i;
-
-	for (i = 0; i < OLD_MAP_SIZE; i++) {
-		_m[i].type_height = ReadByte(ls);
-	}
-	for (i = 0; i < OLD_MAP_SIZE; i++) {
-		_m[i].m5 = ReadByte(ls);
-	}
-
-	return !ls->failed;
-}
-
-static bool LoadTTDPatchExtraChunks(LoadgameState *ls, int num)
-{
-	ReadTTDPatchFlags();
-
-	DEBUG(oldloader, 2, "Found %d extra chunk(s)", _old_extra_chunk_nums);
-
-	for (int i = 0; i != _old_extra_chunk_nums; i++) {
-		uint16 id = ReadUint16(ls);
-		uint32 len = ReadUint32(ls);
-
-		switch (id) {
-			/* List of GRFIDs, used in the savegame. 0x8004 is the new ID
-			 * They are saved in a 'GRFID:4 active:1' format, 5 bytes for each entry */
-			case 0x2:
-			case 0x8004: {
-				/* Skip the first element: TTDP hack for the Action D special variables (FFFF0000 01) */
-				ReadUint32(ls); ReadByte(ls); len -= 5;
-
-				ClearGRFConfigList(&_grfconfig);
-				while (len != 0) {
-					uint32 grfid = ReadUint32(ls);
-
-					if (ReadByte(ls) == 1) {
-						GRFConfig *c = CallocT<GRFConfig>(1);
-						c->grfid = grfid;
-						c->filename = strdup("TTDP game, no information");
-
-						AppendToGRFConfigList(&_grfconfig, c);
-						DEBUG(oldloader, 3, "TTDPatch game using GRF file with GRFID %0X", BSWAP32(c->grfid));
-					}
-					len -= 5;
-				};
-
-				/* Append static NewGRF configuration */
-				AppendStaticGRFConfigs(&_grfconfig);
-			} break;
-
-			/* TTDPatch version and configuration */
-			case 0x3:
-				_ttdp_version = ReadUint32(ls);
-				DEBUG(oldloader, 3, "Game saved with TTDPatch version %d.%d.%d r%d",
-					GB(_ttdp_version, 24, 8), GB(_ttdp_version, 20, 4), GB(_ttdp_version, 16, 4), GB(_ttdp_version, 0, 16));
-				len -= 4;
-				while (len-- != 0) ReadByte(ls); // skip the configuration
-				break;
-
-			default:
-				DEBUG(oldloader, 4, "Skipping unknown extra chunk %X", id);
-				while (len-- != 0) ReadByte(ls);
-				break;
-		}
-	}
-
-	return !ls->failed;
-}
-
-extern TileIndex _cur_tileloop_tile;
-static uint32 _old_cur_town_ctr;
-static const OldChunks main_chunk[] = {
-	OCL_ASSERT( 0 ),
-	OCL_VAR ( OC_FILE_U16 | OC_VAR_U32, 1, &_date ),
-	OCL_VAR ( OC_UINT16,   1, &_date_fract ),
-	OCL_NULL( 600 ),            ///< TextEffects
-	OCL_VAR ( OC_UINT32,   2, &_random.state ),
-
-	OCL_ASSERT( 0x264 ),
-	OCL_CHUNK(  70, LoadOldTown ),
-	OCL_ASSERT( 0x1C18 ),
-	OCL_CHUNK(5000, LoadOldOrder ),
-	OCL_ASSERT( 0x4328 ),
-
-	OCL_CHUNK( 1, LoadOldAnimTileList ),
-	OCL_NULL( 4 ),              ///< old end-of-order-list-pointer, no longer in use
-
-	OCL_CHUNK( 255, LoadOldDepot ),
-	OCL_ASSERT( 0x4B26 ),
-
-	OCL_VAR ( OC_UINT32,   1, &_old_cur_town_ctr ),
-	OCL_NULL( 2 ),              ///< timer_counter, no longer in use
-	OCL_NULL( 2 ),              ///< land_code,     no longer in use
-
-	OCL_VAR ( OC_FILE_U16 | OC_VAR_U8, 1, &_age_cargo_skip_counter ),
-	OCL_VAR ( OC_UINT16,   1, &_tick_counter ),
-	OCL_VAR (   OC_TILE,   1, &_cur_tileloop_tile ),
-
-	OCL_CHUNK( 49, LoadOldPrice ),
-	OCL_CHUNK( 12, LoadOldCargoPaymentRate ),
-
-	OCL_ASSERT( 0x4CBA ),
-
-	OCL_CHUNK( 1, LoadOldMapPart1 ),
-
-	OCL_ASSERT( 0x48CBA ),
-
-	OCL_CHUNK(250, LoadOldStation ),
-	OCL_CHUNK( 90, LoadOldIndustry ),
-	OCL_CHUNK(  8, LoadOldCompany ),
-
-	OCL_ASSERT( 0x547F2 ),
-
-	OCL_CHUNK( 850, LoadOldVehicle ),
-
-	OCL_ASSERT( 0x6F0F2 ),
-
-	OCL_VAR (  OC_UINT8 | OC_DEREFERENCE_POINTER, 32 * 500, &_old_name_array ),
-
-	OCL_NULL( 0x2000 ),            ///< Old hash-table, no longer in use
-
-	OCL_CHUNK( 40, LoadOldSign ),
-	OCL_CHUNK(256, LoadOldEngine ),
-
-	OCL_VAR ( OC_UINT16,    1, &_vehicle_id_ctr_day ),
-
-	OCL_CHUNK(  8, LoadOldSubsidy ),
-
-	OCL_VAR ( OC_FILE_U16 | OC_VAR_U32,   1, &_next_competitor_start ),
-	OCL_VAR ( OC_FILE_I16 | OC_VAR_I32,   1, &_saved_scrollpos_x ),
-	OCL_VAR ( OC_FILE_I16 | OC_VAR_I32,   1, &_saved_scrollpos_y ),
-	OCL_VAR ( OC_FILE_U16 | OC_VAR_U8,    1, &_saved_scrollpos_zoom ),
-
-	OCL_VAR ( OC_FILE_U32 | OC_VAR_I64,   1, &_economy.max_loan ),
-	OCL_VAR ( OC_FILE_U32 | OC_VAR_I64,   1, &_economy.max_loan_unround ),
-	OCL_VAR (  OC_INT16,    1, &_economy.fluct ),
-
-	OCL_VAR ( OC_UINT16,    1, &_disaster_delay ),
-
-	OCL_NULL( 144 ),             ///< cargo-stuff, calculated in InitializeLandscapeVariables
-
-	OCL_CHUNK(256, LoadOldEngineName ),
-
-	OCL_NULL( 144 ),             ///< AI cargo-stuff, calculated in InitializeLandscapeVariables
-	OCL_NULL( 2 ),               ///< Company indexes of companies, no longer in use
-
-	OCL_VAR ( OC_FILE_U8 | OC_VAR_U16,    1, &_station_tick_ctr ),
-
-	OCL_VAR (  OC_UINT8,    1, &_settings_game.locale.currency ),
-	OCL_VAR (  OC_UINT8,    1, &_settings_game.locale.units ),
-	OCL_VAR ( OC_FILE_U8 | OC_VAR_U32,    1, &_cur_company_tick_index ),
-
-	OCL_NULL( 2 ),               ///< Date stuff, calculated automatically
-	OCL_NULL( 8 ),               ///< Company colors, calculated automatically
-
-	OCL_VAR (  OC_UINT8,    1, &_economy.infl_amount ),
-	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_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_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.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
-
-	OCL_ASSERT( 0x77179 ),
-
-	OCL_CHUNK( 1, LoadOldMapPart2 ),
-
-	OCL_ASSERT( 0x97179 ),
-
-	/* Below any (if available) extra chunks from TTDPatch can follow */
-	OCL_CHUNK(1, LoadTTDPatchExtraChunks),
-
-	OCL_END()
-};
-
-static bool LoadOldMain(LoadgameState *ls)
-{
-	int i;
-
-	/* The first 49 is the name of the game + checksum, skip it */
-	fseek(ls->file, HEADER_SIZE, SEEK_SET);
-
-	DEBUG(oldloader, 3, "Reading main chunk...");
-	/* Load the biggest chunk */
-	_old_map3 = MallocT<byte>(OLD_MAP_SIZE * 2);
-	_old_vehicle_names = NULL;
-	if (!LoadChunk(ls, NULL, main_chunk)) {
-		DEBUG(oldloader, 0, "Loading failed");
-		free(_old_map3);
-		free(_old_vehicle_names);
-		return false;
-	}
-	DEBUG(oldloader, 3, "Done, converting game data...");
-
-	/* Fix some general stuff */
-	_settings_game.game_creation.landscape = _settings_game.game_creation.landscape & 0xF;
-
-	/* Remap some pointers */
-	_cur_town_ctr      = REMAP_TOWN_IDX(_old_cur_town_ctr);
-
-	/* _old_map3 is changed in _map3_lo and _map3_hi */
-	for (i = 0; i < OLD_MAP_SIZE; i++) {
-		_m[i].m3 = _old_map3[i * 2];
-		_m[i].m4 = _old_map3[i * 2 + 1];
-	}
-
-	for (i = 0; i < OLD_MAP_SIZE; i ++) {
-		switch (GetTileType(i)) {
-			case MP_STATION:
-				_m[i].m4 = 0; // We do not understand this TTDP station mapping (yet)
-				switch (_m[i].m5) {
-					/* We have drive through stops at a totally different place */
-					case 0x53: case 0x54: _m[i].m5 += 170 - 0x53; break; // Bus drive through
-					case 0x57: case 0x58: _m[i].m5 += 168 - 0x57; break; // Truck drive through
-					case 0x55: case 0x56: _m[i].m5 += 170 - 0x55; break; // Bus tram stop
-					case 0x59: case 0x5A: _m[i].m5 += 168 - 0x59; break; // Truck tram stop
-					default: break;
-				}
-				break;
-
-			case MP_RAILWAY:
-				/* We save presignals different from TTDPatch, convert them */
-				if (GetRailTileType(i) == RAIL_TILE_SIGNALS) {
-					/* This byte is always zero in TTD for this type of tile */
-					if (_m[i].m4) /* Convert the presignals to our own format */
-						_m[i].m4 = (_m[i].m4 >> 1) & 7;
-				}
-				/* TTDPatch stores PBS things in L6 and all elsewhere; so we'll just
-				 * clear it for ourselves and let OTTD's rebuild PBS itself */
-				_m[i].m4 &= 0xF; /* Only keep the lower four bits; upper four is PBS */
-				break;
-
-			case MP_WATER:
-				if (GetWaterClass(i) == 3) MakeRiver(i, Random());
-				break;
-
-			default:
-				break;
-		}
-	}
-
-	/* Make sure the available engines are really available, otherwise
-	 * we will get a "new vehicle"-spree. */
-	Engine *e;
-	FOR_ALL_ENGINES(e) {
-		if (_date >= (e->intro_date + 365)) {
-			e->flags = (e->flags & ~ENGINE_EXCLUSIVE_PREVIEW) | ENGINE_AVAILABLE;
-			e->company_avail = (CompanyMask)-1;
-		}
-	}
-
-	/* Fix the game to be compatible with OpenTTD */
-	FixOldTowns();
-	FixOldVehicles();
-
-	/* We have a new difficulty setting */
-	_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");
-
-	free(_old_map3);
-	free(_old_vehicle_names);
-
-	return true;
-}
-
-bool LoadOldSaveGame(const char *file)
-{
-	LoadgameState ls;
-
-	DEBUG(oldloader, 3, "Trying to load a TTD(Patch) savegame");
-
-	InitLoading(&ls);
-
-	/* Open file */
-	ls.file = fopen(file, "rb");
-
-	if (ls.file == NULL) {
-		DEBUG(oldloader, 0, "Cannot open file '%s'", file);
-		return false;
-	}
-
-	/* Load the main chunk */
-	if (!LoadOldMain(&ls)) return false;
-
-	fclose(ls.file);
-
-	/* Some old TTD(Patch) savegames could have buoys at tile 0
-	 * (without assigned station struct)
-	 * MakeWater() can be used as long as sea has the same
-	 * format as old savegames (eg. everything is zeroed) */
-	MakeWater(0);
-
-	_pause_game = 2;
-
-	return true;
-}
-
-void GetOldSaveGameName(char *title, const char *path, const char *file)
-{
-	char filename[MAX_PATH];
-	FILE *f;
-
-	snprintf(filename, lengthof(filename), "%s" PATHSEP "%s", path, file);
-	f = fopen(filename, "rb");
-	title[0] = '\0';
-	title[48] = '\0';
-
-	if (f == NULL) return;
-
-	if (fread(title, 1, 48, f) != 48) snprintf(title, 48, "Corrupt file");
-
-	fclose(f);
-}
--- a/src/openttd.cpp
+++ b/src/openttd.cpp
@@ -25,7 +25,7 @@
 #include "window_func.h"
 
 #include "debug.h"
-#include "saveload.h"
+#include "saveload/saveload.h"
 #include "landscape.h"
 #include "company_func.h"
 #include "company_base.h"
@@ -96,7 +96,6 @@
 void DoPaletteAnimations();
 void MusicLoop();
 void ResetMusic();
-void ResetOldNames();
 void ProcessAsyncSaveFinish();
 void CallWindowTickEvent();
 
@@ -1182,1566 +1181,3 @@
 	_sound_driver->MainLoop();
 	MusicLoop();
 }
-
-static void ConvertTownOwner()
-{
-	for (TileIndex tile = 0; tile != MapSize(); tile++) {
-		switch (GetTileType(tile)) {
-			case MP_ROAD:
-				if (GB(_m[tile].m5, 4, 2) == ROAD_TILE_CROSSING && HasBit(_m[tile].m3, 7)) {
-					_m[tile].m3 = OWNER_TOWN;
-				}
-				/* FALLTHROUGH */
-
-			case MP_TUNNELBRIDGE:
-				if (GetTileOwner(tile) & 0x80) SetTileOwner(tile, OWNER_TOWN);
-				break;
-
-			default: break;
-		}
-	}
-}
-
-/* since savegame version 4.1, exclusive transport rights are stored at towns */
-static void UpdateExclusiveRights()
-{
-	Town *t;
-
-	FOR_ALL_TOWNS(t) {
-		t->exclusivity = INVALID_COMPANY;
-	}
-
-	/* FIXME old exclusive rights status is not being imported (stored in s->blocked_months_obsolete)
-	 *   could be implemented this way:
-	 * 1.) Go through all stations
-	 *     Build an array town_blocked[ town_id ][ company_id ]
-	 *     that stores if at least one station in that town is blocked for a company
-	 * 2.) Go through that array, if you find a town that is not blocked for
-	 *     one company, but for all others, then give him exclusivity.
-	 */
-}
-
-static const byte convert_currency[] = {
-	 0,  1, 12,  8,  3,
-	10, 14, 19,  4,  5,
-	 9, 11, 13,  6, 17,
-	16, 22, 21,  7, 15,
-	18,  2, 20, };
-
-/* since savegame version 4.2 the currencies are arranged differently */
-static void UpdateCurrencies()
-{
-	_settings_game.locale.currency = convert_currency[_settings_game.locale.currency];
-}
-
-/* Up to revision 1413 the invisible tiles at the southern border have not been
- * MP_VOID, even though they should have. This is fixed by this function
- */
-static void UpdateVoidTiles()
-{
-	uint i;
-
-	for (i = 0; i < MapMaxY(); ++i) MakeVoid(i * MapSizeX() + MapMaxX());
-	for (i = 0; i < MapSizeX(); ++i) MakeVoid(MapSizeX() * MapMaxY() + i);
-}
-
-/* since savegame version 6.0 each sign has an "owner", signs without owner (from old games are set to 255) */
-static void UpdateSignOwner()
-{
-	Sign *si;
-
-	FOR_ALL_SIGNS(si) si->owner = OWNER_NONE;
-}
-
-extern void UpdateOldAircraft();
-
-
-static inline RailType UpdateRailType(RailType rt, RailType min)
-{
-	return rt >= min ? (RailType)(rt + 1): rt;
-}
-
-/**
- * Initialization of the windows and several kinds of caches.
- * This is not done directly in AfterLoadGame because these
- * functions require that all saveload conversions have been
- * done. As people tend to add savegame conversion stuff after
- * the intialization of the windows and caches quite some bugs
- * had been made.
- * Moving this out of there is both cleaner and less bug-prone.
- *
- * @return true if everything went according to plan, otherwise false.
- */
-static bool InitializeWindowsAndCaches()
-{
-	/* Initialize windows */
-	ResetWindowSystem();
-	SetupColorsAndInitialWindow();
-
-	extern void ResetViewportAfterLoadGame();
-	ResetViewportAfterLoadGame();
-
-	/* Update coordinates of the signs. */
-	UpdateAllStationVirtCoord();
-	UpdateAllSignVirtCoords();
-	UpdateAllTownVirtCoords();
-	UpdateAllWaypointSigns();
-
-	Company *c;
-	FOR_ALL_COMPANIES(c) {
-		/* For each company, verify (while loading a scenario) that the inauguration date is the current year and set it
-		 * accordingly if it is not the case.  No need to set it on companies that are not been used already,
-		 * thus the MIN_YEAR (which is really nothing more than Zero, initialized value) test */
-		if (_file_to_saveload.filetype == FT_SCENARIO && c->inaugurated_year != MIN_YEAR) {
-			c->inaugurated_year = _cur_year;
-		}
-	}
-
-	SetCachedEngineCounts();
-
-	/* Towns have a noise controlled number of airports system
-	 * So each airport's noise value must be added to the town->noise_reached value
-	 * Reset each town's noise_reached value to '0' before. */
-	UpdateAirportsNoise();
-
-	CheckTrainsLengths();
-
-	return true;
-}
-
-/**
- * Signal handler used to give a user a more useful report for crashes during
- * the savegame loading process; especially when there's problems with the
- * NewGRFs that are required by the savegame.
- * @param unused well... unused
- */
-void CDECL HandleSavegameLoadCrash(int unused)
-{
-	char buffer[8192];
-	char *p = buffer;
-	p += seprintf(p, lastof(buffer),
-			"Loading your savegame caused OpenTTD to crash.\n"
-			"This is most likely caused by a missing NewGRF or a NewGRF that has been\n"
-			"loaded as replacement for a missing NewGRF. OpenTTD cannot easily\n"
-			"determine whether a replacement NewGRF is of a newer or older version.\n"
-			"It will load a NewGRF with the same GRF ID as the missing NewGRF. This\n"
-			"means that if the author makes incompatible NewGRFs with the same GRF ID\n"
-			"OpenTTD cannot magically do the right thing. In most cases OpenTTD will\n"
-			"load the savegame and not crash, but this is an exception.\n"
-			"Please load the savegame with the appropriate NewGRFs. When loading a\n"
-			"savegame still crashes when all NewGRFs are found you should file a\n"
-			"bug report. The missing NewGRFs are:\n");
-
-	for (GRFConfig *c = _grfconfig; c != NULL; c = c->next) {
-		if (HasBit(c->flags, GCF_COMPATIBLE)) {
-			char buf[40];
-			md5sumToString(buf, lastof(buf), c->md5sum);
-			p += seprintf(p, lastof(buffer), "NewGRF %08X (%s) not found; checksum %s. Tried another NewGRF with same GRF ID\n", BSWAP32(c->grfid), c->filename, buf);
-		}
-		if (c->status == GCS_NOT_FOUND) {
-			char buf[40];
-			md5sumToString(buf, lastof(buf), c->md5sum);
-			p += seprintf(p, lastof(buffer), "NewGRF %08X (%s) not found; checksum %s\n", BSWAP32(c->grfid), c->filename, buf);
-		}
-	}
-
-	ShowInfo(buffer);
-}
-
-bool AfterLoadGame()
-{
-	typedef void (CDECL *SignalHandlerPointer)(int);
-	SignalHandlerPointer prev_segfault = signal(SIGSEGV, HandleSavegameLoadCrash);
-	SignalHandlerPointer prev_abort = signal(SIGABRT, HandleSavegameLoadCrash);
-
-	TileIndex map_size = MapSize();
-	Company *c;
-
-	if (CheckSavegameVersion(98)) GamelogOldver();
-
-	GamelogTestRevision();
-	GamelogTestMode();
-
-	if (CheckSavegameVersion(98)) GamelogGRFAddList(_grfconfig);
-
-	/* in very old versions, size of train stations was stored differently */
-	if (CheckSavegameVersion(2)) {
-		Station *st;
-		FOR_ALL_STATIONS(st) {
-			if (st->train_tile != 0 && st->trainst_h == 0) {
-				extern SavegameType _savegame_type;
-				uint n = _savegame_type == SGT_OTTD ? 4 : 3; // OTTD uses 4 bits per dimensions, TTD 3 bits
-				uint w = GB(st->trainst_w, n, n);
-				uint h = GB(st->trainst_w, 0, n);
-
-				if (GetRailStationAxis(st->train_tile) != AXIS_X) Swap(w, h);
-
-				st->trainst_w = w;
-				st->trainst_h = h;
-
-				assert(GetStationIndex(st->train_tile + TileDiffXY(w - 1, h - 1)) == st->index);
-			}
-		}
-	}
-
-	/* in version 2.1 of the savegame, town owner was unified. */
-	if (CheckSavegameVersionOldStyle(2, 1)) ConvertTownOwner();
-
-	/* from version 4.1 of the savegame, exclusive rights are stored at towns */
-	if (CheckSavegameVersionOldStyle(4, 1)) UpdateExclusiveRights();
-
-	/* from version 4.2 of the savegame, currencies are in a different order */
-	if (CheckSavegameVersionOldStyle(4, 2)) UpdateCurrencies();
-
-	/* from version 6.1 of the savegame, signs have an "owner" */
-	if (CheckSavegameVersionOldStyle(6, 1)) UpdateSignOwner();
-
-	/* In old version there seems to be a problem that water is owned by
-	 * OWNER_NONE, not OWNER_WATER.. I can't replicate it for the current
-	 * (4.3) version, so I just check when versions are older, and then
-	 * walk through the whole map.. */
-	if (CheckSavegameVersionOldStyle(4, 3)) {
-		for (TileIndex t = 0; t < map_size; t++) {
-			if (IsTileType(t, MP_WATER) && GetTileOwner(t) >= MAX_COMPANIES) {
-				SetTileOwner(t, OWNER_WATER);
-			}
-		}
-	}
-
-	if (CheckSavegameVersion(84)) {
-		FOR_ALL_COMPANIES(c) {
-			c->name = CopyFromOldName(c->name_1);
-			if (c->name != NULL) c->name_1 = STR_SV_UNNAMED;
-			c->president_name = CopyFromOldName(c->president_name_1);
-			if (c->president_name != NULL) c->president_name_1 = SPECSTR_PRESIDENT_NAME;
-		}
-
-		Station *st;
-		FOR_ALL_STATIONS(st) {
-			st->name = CopyFromOldName(st->string_id);
-			/* generating new name would be too much work for little effect, use the station name fallback */
-			if (st->name != NULL) st->string_id = STR_SV_STNAME_FALLBACK;
-		}
-
-		Town *t;
-		FOR_ALL_TOWNS(t) {
-			t->name = CopyFromOldName(t->townnametype);
-			if (t->name != NULL) t->townnametype = SPECSTR_TOWNNAME_START + _settings_game.game_creation.town_name;
-		}
-
-		Waypoint *wp;
-		FOR_ALL_WAYPOINTS(wp) {
-			wp->name = CopyFromOldName(wp->string);
-			wp->string = STR_EMPTY;
-		}
-
-		for (uint i = 0; i < GetSignPoolSize(); i++) {
-			/* invalid signs are determined by si->ower == INVALID_COMPANY now */
-			Sign *si = GetSign(i);
-			if (!si->IsValid() && si->name != NULL) {
-				si->owner = OWNER_NONE;
-			}
-		}
-	}
-
-	/* From this point the old names array is cleared. */
-	ResetOldNames();
-
-	if (CheckSavegameVersion(106)) {
-		/* no station is determined by 'tile == INVALID_TILE' now (instead of '0') */
-		Station *st;
-		FOR_ALL_STATIONS(st) {
-			if (st->airport_tile == 0) st->airport_tile = INVALID_TILE;
-			if (st->dock_tile    == 0) st->dock_tile    = INVALID_TILE;
-			if (st->train_tile   == 0) st->train_tile   = INVALID_TILE;
-		}
-
-		/* the same applies to Company::location_of_HQ */
-		Company *c;
-		FOR_ALL_COMPANIES(c) {
-			if (c->location_of_HQ == 0 || (CheckSavegameVersion(4) && c->location_of_HQ == 0xFFFF)) {
-				c->location_of_HQ = INVALID_TILE;
-			}
-		}
-	}
-
-	/* convert road side to my format. */
-	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();
-	if (_networking && gcf_res != GLC_ALL_GOOD) {
-		SetSaveLoadError(STR_NETWORK_ERR_CLIENT_NEWGRF_MISMATCH);
-		/* Restore the signals */
-		signal(SIGSEGV, prev_segfault);
-		signal(SIGABRT, prev_abort);
-		return false;
-	}
-
-	switch (gcf_res) {
-		case GLC_COMPATIBLE: _switch_mode_errorstr = STR_NEWGRF_COMPATIBLE_LOAD_WARNING; break;
-		case GLC_NOT_FOUND: _switch_mode_errorstr = STR_NEWGRF_DISABLED_WARNING; _pause_game = -1; break;
-		default: break;
-	}
-
-	/* Update current year
-	 * must be done before loading sprites as some newgrfs check it */
-	SetDate(_date);
-
-	/* Force dynamic engines off when loading older savegames */
-	if (CheckSavegameVersion(95)) _settings_game.vehicle.dynamic_engines = 0;
-
-	/* Load the sprites */
-	GfxLoadSprites();
-	LoadStringWidthTable();
-
-	/* Copy temporary data to Engine pool */
-	CopyTempEngineData();
-
-	/* Connect front and rear engines of multiheaded trains and converts
-	 * subtype to the new format */
-	if (CheckSavegameVersionOldStyle(17, 1)) ConvertOldMultiheadToNew();
-
-	/* Connect front and rear engines of multiheaded trains */
-	ConnectMultiheadedTrains();
-
-	/* reinit the landscape variables (landscape might have changed) */
-	InitializeLandscapeVariables(true);
-
-	/* Update all vehicles */
-	AfterLoadVehicles(true);
-
-	/* Update all waypoints */
-	if (CheckSavegameVersion(12)) FixOldWaypoints();
-
-	/* in version 2.2 of the savegame, we have new airports */
-	if (CheckSavegameVersionOldStyle(2, 2)) UpdateOldAircraft();
-
-	AfterLoadTown();
-
-	/* make sure there is a town in the game */
-	if (_game_mode == GM_NORMAL && !ClosestTownFromTile(0, UINT_MAX)) {
-		SetSaveLoadError(STR_NO_TOWN_IN_SCENARIO);
-		/* Restore the signals */
-		signal(SIGSEGV, prev_segfault);
-		signal(SIGABRT, prev_abort);
-		return false;
-	}
-
-	/* The void tiles on the southern border used to belong to a wrong class (pre 4.3).
-	 * This problem appears in savegame version 21 too, see r3455. But after loading the
-	 * savegame and saving again, the buggy map array could be converted to new savegame
-	 * version. It didn't show up before r12070. */
-	if (CheckSavegameVersion(87)) UpdateVoidTiles();
-
-	/* If Load Scenario / New (Scenario) Game is used,
-	 *  a company does not exist yet. So create one here.
-	 * 1 exeption: network-games. Those can have 0 companies
-	 *   But this exeption is not true for non dedicated network_servers! */
-	if (!IsValidCompanyID(COMPANY_FIRST) && (!_networking || (_networking && _network_server && !_network_dedicated)))
-		DoStartupNewCompany(false);
-
-	if (CheckSavegameVersion(72)) {
-		/* Locks/shiplifts in very old savegames had OWNER_WATER as owner */
-		for (TileIndex t = 0; t < MapSize(); t++) {
-			switch (GetTileType(t)) {
-				default: break;
-
-				case MP_WATER:
-					if (GetWaterTileType(t) == WATER_TILE_LOCK && GetTileOwner(t) == OWNER_WATER) SetTileOwner(t, OWNER_NONE);
-					break;
-
-				case MP_STATION: {
-					if (HasBit(_m[t].m6, 3)) SetBit(_m[t].m6, 2);
-					StationGfx gfx = GetStationGfx(t);
-					StationType st;
-					if (       IsInsideMM(gfx,   0,   8)) { // Railway station
-						st = STATION_RAIL;
-						SetStationGfx(t, gfx - 0);
-					} else if (IsInsideMM(gfx,   8,  67)) { // Airport
-						st = STATION_AIRPORT;
-						SetStationGfx(t, gfx - 8);
-					} else if (IsInsideMM(gfx,  67,  71)) { // Truck
-						st = STATION_TRUCK;
-						SetStationGfx(t, gfx - 67);
-					} else if (IsInsideMM(gfx,  71,  75)) { // Bus
-						st = STATION_BUS;
-						SetStationGfx(t, gfx - 71);
-					} else if (gfx == 75) {                    // Oil rig
-						st = STATION_OILRIG;
-						SetStationGfx(t, gfx - 75);
-					} else if (IsInsideMM(gfx,  76,  82)) { // Dock
-						st = STATION_DOCK;
-						SetStationGfx(t, gfx - 76);
-					} else if (gfx == 82) {                    // Buoy
-						st = STATION_BUOY;
-						SetStationGfx(t, gfx - 82);
-					} else if (IsInsideMM(gfx,  83, 168)) { // Extended airport
-						st = STATION_AIRPORT;
-						SetStationGfx(t, gfx - 83 + 67 - 8);
-					} else if (IsInsideMM(gfx, 168, 170)) { // Drive through truck
-						st = STATION_TRUCK;
-						SetStationGfx(t, gfx - 168 + GFX_TRUCK_BUS_DRIVETHROUGH_OFFSET);
-					} else if (IsInsideMM(gfx, 170, 172)) { // Drive through bus
-						st = STATION_BUS;
-						SetStationGfx(t, gfx - 170 + GFX_TRUCK_BUS_DRIVETHROUGH_OFFSET);
-					} else {
-						/* Restore the signals */
-						signal(SIGSEGV, prev_segfault);
-						signal(SIGABRT, prev_abort);
-						return false;
-					}
-					SB(_m[t].m6, 3, 3, st);
-				} break;
-			}
-		}
-	}
-
-	for (TileIndex t = 0; t < map_size; t++) {
-		switch (GetTileType(t)) {
-			case MP_STATION: {
-				Station *st = GetStationByTile(t);
-
-				/* Set up station spread; buoys do not have one */
-				if (!IsBuoy(t)) st->rect.BeforeAddTile(t, StationRect::ADD_FORCE);
-
-				switch (GetStationType(t)) {
-					case STATION_TRUCK:
-					case STATION_BUS:
-						if (CheckSavegameVersion(6)) {
-							/* From this version on there can be multiple road stops of the
-							 * same type per station. Convert the existing stops to the new
-							 * internal data structure. */
-							RoadStop *rs = new RoadStop(t);
-							if (rs == NULL) error("Too many road stops in savegame");
-
-							RoadStop **head =
-								IsTruckStop(t) ? &st->truck_stops : &st->bus_stops;
-							*head = rs;
-						}
-						break;
-
-					case STATION_OILRIG: {
-						/* Very old savegames sometimes have phantom oil rigs, i.e.
-						 * an oil rig which got shut down, but not completly removed from
-						 * the map
-						 */
-						TileIndex t1 = TILE_ADDXY(t, 0, 1);
-						if (IsTileType(t1, MP_INDUSTRY) &&
-								GetIndustryGfx(t1) == GFX_OILRIG_1) {
-							/* The internal encoding of oil rigs was changed twice.
-							 * It was 3 (till 2.2) and later 5 (till 5.1).
-							 * Setting it unconditionally does not hurt.
-							 */
-							GetStationByTile(t)->airport_type = AT_OILRIG;
-						} else {
-							DeleteOilRig(t);
-						}
-						break;
-					}
-
-					default: break;
-				}
-				break;
-			}
-
-			default: break;
-		}
-	}
-
-	/* In version 6.1 we put the town index in the map-array. To do this, we need
-	 *  to use m2 (16bit big), so we need to clean m2, and that is where this is
-	 *  all about ;) */
-	if (CheckSavegameVersionOldStyle(6, 1)) {
-		for (TileIndex t = 0; t < map_size; t++) {
-			switch (GetTileType(t)) {
-				case MP_HOUSE:
-					_m[t].m4 = _m[t].m2;
-					SetTownIndex(t, CalcClosestTownFromTile(t, UINT_MAX)->index);
-					break;
-
-				case MP_ROAD:
-					_m[t].m4 |= (_m[t].m2 << 4);
-					if ((GB(_m[t].m5, 4, 2) == ROAD_TILE_CROSSING ? (Owner)_m[t].m3 : GetTileOwner(t)) == OWNER_TOWN) {
-						SetTownIndex(t, CalcClosestTownFromTile(t, UINT_MAX)->index);
-					} else {
-						SetTownIndex(t, 0);
-					}
-					break;
-
-				default: break;
-			}
-		}
-	}
-
-	/* From version 9.0, we update the max passengers of a town (was sometimes negative
-	 *  before that. */
-	if (CheckSavegameVersion(9)) {
-		Town *t;
-		FOR_ALL_TOWNS(t) UpdateTownMaxPass(t);
-	}
-
-	/* From version 16.0, we included autorenew on engines, which are now saved, but
-	 *  of course, we do need to initialize them for older savegames. */
-	if (CheckSavegameVersion(16)) {
-		FOR_ALL_COMPANIES(c) {
-			c->engine_renew_list   = NULL;
-			c->engine_renew        = false;
-			c->engine_renew_months = -6;
-			c->engine_renew_money  = 100000;
-		}
-
-		/* When loading a game, _local_company is not yet set to the correct value.
-		 * However, in a dedicated server we are a spectator, so nothing needs to
-		 * happen. In case we are not a dedicated server, the local company always
-		 * becomes company 0, unless we are in the scenario editor where all the
-		 * companies are 'invalid'.
-		 */
-		if (!_network_dedicated && IsValidCompanyID(COMPANY_FIRST)) {
-			c = GetCompany(COMPANY_FIRST);
-			c->engine_renew        = _settings_client.gui.autorenew;
-			c->engine_renew_months = _settings_client.gui.autorenew_months;
-			c->engine_renew_money  = _settings_client.gui.autorenew_money;
-		}
-	}
-
-	if (CheckSavegameVersion(48)) {
-		for (TileIndex t = 0; t < map_size; t++) {
-			switch (GetTileType(t)) {
-				case MP_RAILWAY:
-					if (IsPlainRailTile(t)) {
-						/* Swap ground type and signal type for plain rail tiles, so the
-						 * ground type uses the same bits as for depots and waypoints. */
-						uint tmp = GB(_m[t].m4, 0, 4);
-						SB(_m[t].m4, 0, 4, GB(_m[t].m2, 0, 4));
-						SB(_m[t].m2, 0, 4, tmp);
-					} else if (HasBit(_m[t].m5, 2)) {
-						/* Split waypoint and depot rail type and remove the subtype. */
-						ClrBit(_m[t].m5, 2);
-						ClrBit(_m[t].m5, 6);
-					}
-					break;
-
-				case MP_ROAD:
-					/* Swap m3 and m4, so the track type for rail crossings is the
-					 * same as for normal rail. */
-					Swap(_m[t].m3, _m[t].m4);
-					break;
-
-				default: break;
-			}
-		}
-	}
-
-	if (CheckSavegameVersion(61)) {
-		/* Added the RoadType */
-		bool old_bridge = CheckSavegameVersion(42);
-		for (TileIndex t = 0; t < map_size; t++) {
-			switch(GetTileType(t)) {
-				case MP_ROAD:
-					SB(_m[t].m5, 6, 2, GB(_m[t].m5, 4, 2));
-					switch (GetRoadTileType(t)) {
-						default: NOT_REACHED();
-						case ROAD_TILE_NORMAL:
-							SB(_m[t].m4, 0, 4, GB(_m[t].m5, 0, 4));
-							SB(_m[t].m4, 4, 4, 0);
-							SB(_m[t].m6, 2, 4, 0);
-							break;
-						case ROAD_TILE_CROSSING:
-							SB(_m[t].m4, 5, 2, GB(_m[t].m5, 2, 2));
-							break;
-						case ROAD_TILE_DEPOT:    break;
-					}
-					SetRoadTypes(t, ROADTYPES_ROAD);
-					break;
-
-				case MP_STATION:
-					if (IsRoadStop(t)) SetRoadTypes(t, ROADTYPES_ROAD);
-					break;
-
-				case MP_TUNNELBRIDGE:
-					/* Middle part of "old" bridges */
-					if (old_bridge && IsBridge(t) && HasBit(_m[t].m5, 6)) break;
-					if (((old_bridge && IsBridge(t)) ? (TransportType)GB(_m[t].m5, 1, 2) : GetTunnelBridgeTransportType(t)) == TRANSPORT_ROAD) {
-						SetRoadTypes(t, ROADTYPES_ROAD);
-					}
-					break;
-
-				default: break;
-			}
-		}
-	}
-
-	if (CheckSavegameVersion(42)) {
-		Vehicle* v;
-
-		for (TileIndex t = 0; t < map_size; t++) {
-			if (MayHaveBridgeAbove(t)) ClearBridgeMiddle(t);
-			if (IsBridgeTile(t)) {
-				if (HasBit(_m[t].m5, 6)) { // middle part
-					Axis axis = (Axis)GB(_m[t].m5, 0, 1);
-
-					if (HasBit(_m[t].m5, 5)) { // transport route under bridge?
-						if (GB(_m[t].m5, 3, 2) == TRANSPORT_RAIL) {
-							MakeRailNormal(
-								t,
-								GetTileOwner(t),
-								axis == AXIS_X ? TRACK_BIT_Y : TRACK_BIT_X,
-								GetRailType(t)
-							);
-						} else {
-							TownID town = IsTileOwner(t, OWNER_TOWN) ? ClosestTownFromTile(t, UINT_MAX)->index : 0;
-
-							MakeRoadNormal(
-								t,
-								axis == AXIS_X ? ROAD_Y : ROAD_X,
-								ROADTYPES_ROAD,
-								town,
-								GetTileOwner(t), OWNER_NONE, OWNER_NONE
-							);
-						}
-					} else {
-						if (GB(_m[t].m5, 3, 2) == 0) {
-							MakeClear(t, CLEAR_GRASS, 3);
-						} else {
-							if (GetTileSlope(t, NULL) != SLOPE_FLAT) {
-								MakeShore(t);
-							} else {
-								if (GetTileOwner(t) == OWNER_WATER) {
-									MakeWater(t);
-								} else {
-									MakeCanal(t, GetTileOwner(t), Random());
-								}
-							}
-						}
-					}
-					SetBridgeMiddle(t, axis);
-				} else { // ramp
-					Axis axis = (Axis)GB(_m[t].m5, 0, 1);
-					uint north_south = GB(_m[t].m5, 5, 1);
-					DiagDirection dir = ReverseDiagDir(XYNSToDiagDir(axis, north_south));
-					TransportType type = (TransportType)GB(_m[t].m5, 1, 2);
-
-					_m[t].m5 = 1 << 7 | type << 2 | dir;
-				}
-			}
-		}
-
-		FOR_ALL_VEHICLES(v) {
-			if (v->type != VEH_TRAIN && v->type != VEH_ROAD) continue;
-			if (IsBridgeTile(v->tile)) {
-				DiagDirection dir = GetTunnelBridgeDirection(v->tile);
-
-				if (dir != DirToDiagDir(v->direction)) continue;
-				switch (dir) {
-					default: NOT_REACHED();
-					case DIAGDIR_NE: if ((v->x_pos & 0xF) !=  0)            continue; break;
-					case DIAGDIR_SE: if ((v->y_pos & 0xF) != TILE_SIZE - 1) continue; break;
-					case DIAGDIR_SW: if ((v->x_pos & 0xF) != TILE_SIZE - 1) continue; break;
-					case DIAGDIR_NW: if ((v->y_pos & 0xF) !=  0)            continue; break;
-				}
-			} else if (v->z_pos > GetSlopeZ(v->x_pos, v->y_pos)) {
-				v->tile = GetNorthernBridgeEnd(v->tile);
-			} else {
-				continue;
-			}
-			if (v->type == VEH_TRAIN) {
-				v->u.rail.track = TRACK_BIT_WORMHOLE;
-			} else {
-				v->u.road.state = RVSB_WORMHOLE;
-			}
-		}
-	}
-
-	/* Elrails got added in rev 24 */
-	if (CheckSavegameVersion(24)) {
-		Vehicle *v;
-		RailType min_rail = RAILTYPE_ELECTRIC;
-
-		FOR_ALL_VEHICLES(v) {
-			if (v->type == VEH_TRAIN) {
-				RailType rt = RailVehInfo(v->engine_type)->railtype;
-
-				v->u.rail.railtype = rt;
-				if (rt == RAILTYPE_ELECTRIC) min_rail = RAILTYPE_RAIL;
-			}
-		}
-
-		/* .. so we convert the entire map from normal to elrail (so maintain "fairness") */
-		for (TileIndex t = 0; t < map_size; t++) {
-			switch (GetTileType(t)) {
-				case MP_RAILWAY:
-					SetRailType(t, UpdateRailType(GetRailType(t), min_rail));
-					break;
-
-				case MP_ROAD:
-					if (IsLevelCrossing(t)) {
-						SetRailType(t, UpdateRailType(GetRailType(t), min_rail));
-					}
-					break;
-
-				case MP_STATION:
-					if (IsRailwayStation(t)) {
-						SetRailType(t, UpdateRailType(GetRailType(t), min_rail));
-					}
-					break;
-
-				case MP_TUNNELBRIDGE:
-					if (GetTunnelBridgeTransportType(t) == TRANSPORT_RAIL) {
-						SetRailType(t, UpdateRailType(GetRailType(t), min_rail));
-					}
-					break;
-
-				default:
-					break;
-			}
-		}
-
-		FOR_ALL_VEHICLES(v) {
-			if (v->type == VEH_TRAIN && (IsFrontEngine(v) || IsFreeWagon(v))) TrainConsistChanged(v, true);
-		}
-
-	}
-
-	/* In version 16.1 of the savegame a company can decide if trains, which get
-	 * replaced, shall keep their old length. In all prior versions, just default
-	 * to false */
-	if (CheckSavegameVersionOldStyle(16, 1)) {
-		FOR_ALL_COMPANIES(c) c->renew_keep_length = false;
-	}
-
-	/* In version 17, ground type is moved from m2 to m4 for depots and
-	 * waypoints to make way for storing the index in m2. The custom graphics
-	 * id which was stored in m4 is now saved as a grf/id reference in the
-	 * waypoint struct. */
-	if (CheckSavegameVersion(17)) {
-		Waypoint *wp;
-
-		FOR_ALL_WAYPOINTS(wp) {
-			if (wp->deleted == 0) {
-				const StationSpec *statspec = NULL;
-
-				if (HasBit(_m[wp->xy].m3, 4))
-					statspec = GetCustomStationSpec(STAT_CLASS_WAYP, _m[wp->xy].m4 + 1);
-
-				if (statspec != NULL) {
-					wp->stat_id = _m[wp->xy].m4 + 1;
-					wp->grfid = statspec->grffile->grfid;
-					wp->localidx = statspec->localidx;
-				} else {
-					/* No custom graphics set, so set to default. */
-					wp->stat_id = 0;
-					wp->grfid = 0;
-					wp->localidx = 0;
-				}
-
-				/* Move ground type bits from m2 to m4. */
-				_m[wp->xy].m4 = GB(_m[wp->xy].m2, 0, 4);
-				/* Store waypoint index in the tile. */
-				_m[wp->xy].m2 = wp->index;
-			}
-		}
-	} else {
-		/* As of version 17, we recalculate the custom graphic ID of waypoints
-		 * from the GRF ID / station index. */
-		AfterLoadWaypoints();
-	}
-
-	/* From version 15, we moved a semaphore bit from bit 2 to bit 3 in m4, making
-	 *  room for PBS. Now in version 21 move it back :P. */
-	if (CheckSavegameVersion(21) && !CheckSavegameVersion(15)) {
-		for (TileIndex t = 0; t < map_size; t++) {
-			switch (GetTileType(t)) {
-				case MP_RAILWAY:
-					if (HasSignals(t)) {
-						/* convert PBS signals to combo-signals */
-						if (HasBit(_m[t].m2, 2)) SetSignalType(t, TRACK_X, SIGTYPE_COMBO);
-
-						/* move the signal variant back */
-						SetSignalVariant(t, TRACK_X, HasBit(_m[t].m2, 3) ? SIG_SEMAPHORE : SIG_ELECTRIC);
-						ClrBit(_m[t].m2, 3);
-					}
-
-					/* Clear PBS reservation on track */
-					if (!IsRailDepotTile(t)) {
-						SB(_m[t].m4, 4, 4, 0);
-					} else {
-						ClrBit(_m[t].m3, 6);
-					}
-					break;
-
-				case MP_ROAD: /* Clear PBS reservation on crossing */
-					if (IsLevelCrossing(t)) ClrBit(_m[t].m5, 0);
-					break;
-
-				case MP_STATION: /* Clear PBS reservation on station */
-					ClrBit(_m[t].m3, 6);
-					break;
-
-				default: break;
-			}
-		}
-	}
-
-	if (CheckSavegameVersion(25)) {
-		Vehicle *v;
-		FOR_ALL_VEHICLES(v) {
-			if (v->type == VEH_ROAD) {
-				v->vehstatus &= ~0x40;
-				v->u.road.slot = NULL;
-				v->u.road.slot_age = 0;
-			}
-		}
-	} else {
-		Vehicle *v;
-		FOR_ALL_VEHICLES(v) {
-			if (v->type == VEH_ROAD && v->u.road.slot != NULL) v->u.road.slot->num_vehicles++;
-		}
-	}
-
-	if (CheckSavegameVersion(26)) {
-		Station *st;
-		FOR_ALL_STATIONS(st) {
-			st->last_vehicle_type = VEH_INVALID;
-		}
-	}
-
-	YapfNotifyTrackLayoutChange(INVALID_TILE, INVALID_TRACK);
-
-	if (CheckSavegameVersion(34)) FOR_ALL_COMPANIES(c) ResetCompanyLivery(c);
-
-	FOR_ALL_COMPANIES(c) {
-		c->avail_railtypes = GetCompanyRailtypes(c->index);
-		c->avail_roadtypes = GetCompanyRoadtypes(c->index);
-	}
-
-	if (!CheckSavegameVersion(27)) AfterLoadStations();
-
-	/* Time starts at 0 instead of 1920.
-	 * Account for this in older games by adding an offset */
-	if (CheckSavegameVersion(31)) {
-		Station *st;
-		Waypoint *wp;
-		Engine *e;
-		Industry *i;
-		Vehicle *v;
-
-		_date += DAYS_TILL_ORIGINAL_BASE_YEAR;
-		_cur_year += ORIGINAL_BASE_YEAR;
-
-		FOR_ALL_STATIONS(st)  st->build_date      += DAYS_TILL_ORIGINAL_BASE_YEAR;
-		FOR_ALL_WAYPOINTS(wp) wp->build_date      += DAYS_TILL_ORIGINAL_BASE_YEAR;
-		FOR_ALL_ENGINES(e)    e->intro_date       += DAYS_TILL_ORIGINAL_BASE_YEAR;
-		FOR_ALL_COMPANIES(c)  c->inaugurated_year += ORIGINAL_BASE_YEAR;
-		FOR_ALL_INDUSTRIES(i) i->last_prod_year   += ORIGINAL_BASE_YEAR;
-
-		FOR_ALL_VEHICLES(v) {
-			v->date_of_last_service += DAYS_TILL_ORIGINAL_BASE_YEAR;
-			v->build_year += ORIGINAL_BASE_YEAR;
-		}
-	}
-
-	/* From 32 on we save the industry who made the farmland.
-	 *  To give this prettyness to old savegames, we remove all farmfields and
-	 *  plant new ones. */
-	if (CheckSavegameVersion(32)) {
-		Industry *i;
-
-		for (TileIndex t = 0; t < map_size; t++) {
-			if (IsTileType(t, MP_CLEAR) && IsClearGround(t, CLEAR_FIELDS)) {
-				/* remove fields */
-				MakeClear(t, CLEAR_GRASS, 3);
-			} else if (IsTileType(t, MP_CLEAR) || IsTileType(t, MP_TREES)) {
-				/* remove fences around fields */
-				SetFenceSE(t, 0);
-				SetFenceSW(t, 0);
-			}
-		}
-
-		FOR_ALL_INDUSTRIES(i) {
-			uint j;
-
-			if (GetIndustrySpec(i->type)->behaviour & INDUSTRYBEH_PLANT_ON_BUILT) {
-				for (j = 0; j != 50; j++) PlantRandomFarmField(i);
-			}
-		}
-	}
-
-	/* Setting no refit flags to all orders in savegames from before refit in orders were added */
-	if (CheckSavegameVersion(36)) {
-		Order *order;
-		Vehicle *v;
-
-		FOR_ALL_ORDERS(order) {
-			order->SetRefit(CT_NO_REFIT);
-		}
-
-		FOR_ALL_VEHICLES(v) {
-			v->current_order.SetRefit(CT_NO_REFIT);
-		}
-	}
-
-	/* 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_game.vehicle.disable_elrails = false;
-	/* do the same as when elrails were enabled/disabled manually just now */
-	SettingsDisableElrail(_settings_game.vehicle.disable_elrails);
-	InitializeRailGUI();
-
-	/* From version 53, the map array was changed for house tiles to allow
-	 * space for newhouses grf features. A new byte, m7, was also added. */
-	if (CheckSavegameVersion(53)) {
-		for (TileIndex t = 0; t < map_size; t++) {
-			if (IsTileType(t, MP_HOUSE)) {
-				if (GB(_m[t].m3, 6, 2) != TOWN_HOUSE_COMPLETED) {
-					/* Move the construction stage from m3[7..6] to m5[5..4].
-					 * The construction counter does not have to move. */
-					SB(_m[t].m5, 3, 2, GB(_m[t].m3, 6, 2));
-					SB(_m[t].m3, 6, 2, 0);
-
-					/* The "house is completed" bit is now in m6[2]. */
-					SetHouseCompleted(t, false);
-				} else {
-					/* The "lift has destination" bit has been moved from
-					 * m5[7] to m7[0]. */
-					SB(_me[t].m7, 0, 1, HasBit(_m[t].m5, 7));
-					ClrBit(_m[t].m5, 7);
-
-					/* The "lift is moving" bit has been removed, as it does
-					 * the same job as the "lift has destination" bit. */
-					ClrBit(_m[t].m1, 7);
-
-					/* The position of the lift goes from m1[7..0] to m6[7..2],
-					 * making m1 totally free, now. The lift position does not
-					 * have to be a full byte since the maximum value is 36. */
-					SetLiftPosition(t, GB(_m[t].m1, 0, 6 ));
-
-					_m[t].m1 = 0;
-					_m[t].m3 = 0;
-					SetHouseCompleted(t, true);
-				}
-			}
-		}
-	}
-
-	/* Check and update house and town values */
-	UpdateHousesAndTowns();
-
-	if (CheckSavegameVersion(43)) {
-		for (TileIndex t = 0; t < map_size; t++) {
-			if (IsTileType(t, MP_INDUSTRY)) {
-				switch (GetIndustryGfx(t)) {
-					case GFX_POWERPLANT_SPARKS:
-						SetIndustryAnimationState(t, GB(_m[t].m1, 2, 5));
-						break;
-
-					case GFX_OILWELL_ANIMATED_1:
-					case GFX_OILWELL_ANIMATED_2:
-					case GFX_OILWELL_ANIMATED_3:
-						SetIndustryAnimationState(t, GB(_m[t].m1, 0, 2));
-						break;
-
-					case GFX_COAL_MINE_TOWER_ANIMATED:
-					case GFX_COPPER_MINE_TOWER_ANIMATED:
-					case GFX_GOLD_MINE_TOWER_ANIMATED:
-						 SetIndustryAnimationState(t, _m[t].m1);
-						 break;
-
-					default: /* No animation states to change */
-						break;
-				}
-			}
-		}
-	}
-
-	if (CheckSavegameVersion(44)) {
-		Vehicle *v;
-		/* If we remove a station while cargo from it is still enroute, payment calculation will assume
-		 * 0, 0 to be the source of the cargo, resulting in very high payments usually. v->source_xy
-		 * stores the coordinates, preserving them even if the station is removed. However, if a game is loaded
-		 * where this situation exists, the cargo-source information is lost. in this case, we set the source
-		 * to the current tile of the vehicle to prevent excessive profits
-		 */
-		FOR_ALL_VEHICLES(v) {
-			const CargoList::List *packets = v->cargo.Packets();
-			for (CargoList::List::const_iterator it = packets->begin(); it != packets->end(); it++) {
-				CargoPacket *cp = *it;
-				cp->source_xy = IsValidStationID(cp->source) ? GetStation(cp->source)->xy : v->tile;
-				cp->loaded_at_xy = cp->source_xy;
-			}
-			v->cargo.InvalidateCache();
-		}
-
-		/* Store position of the station where the goods come from, so there
-		 * are no very high payments when stations get removed. However, if the
-		 * station where the goods came from is already removed, the source
-		 * information is lost. In that case we set it to the position of this
-		 * station */
-		Station *st;
-		FOR_ALL_STATIONS(st) {
-			for (CargoID c = 0; c < NUM_CARGO; c++) {
-				GoodsEntry *ge = &st->goods[c];
-
-				const CargoList::List *packets = ge->cargo.Packets();
-				for (CargoList::List::const_iterator it = packets->begin(); it != packets->end(); it++) {
-					CargoPacket *cp = *it;
-					cp->source_xy = IsValidStationID(cp->source) ? GetStation(cp->source)->xy : st->xy;
-					cp->loaded_at_xy = cp->source_xy;
-				}
-			}
-		}
-	}
-
-	if (CheckSavegameVersion(45)) {
-		Vehicle *v;
-		/* Originally just the fact that some cargo had been paid for was
-		 * stored to stop people cheating and cashing in several times. This
-		 * wasn't enough though as it was cleared when the vehicle started
-		 * loading again, even if it didn't actually load anything, so now the
-		 * amount of cargo that has been paid for is stored. */
-		FOR_ALL_VEHICLES(v) {
-			const CargoList::List *packets = v->cargo.Packets();
-			for (CargoList::List::const_iterator it = packets->begin(); it != packets->end(); it++) {
-				CargoPacket *cp = *it;
-				cp->paid_for = HasBit(v->vehicle_flags, 2);
-			}
-			ClrBit(v->vehicle_flags, 2);
-			v->cargo.InvalidateCache();
-		}
-	}
-
-	/* Buoys do now store the owner of the previous water tile, which can never
-	 * be OWNER_NONE. So replace OWNER_NONE with OWNER_WATER. */
-	if (CheckSavegameVersion(46)) {
-		Station *st;
-		FOR_ALL_STATIONS(st) {
-			if (st->IsBuoy() && IsTileOwner(st->xy, OWNER_NONE) && TileHeight(st->xy) == 0) SetTileOwner(st->xy, OWNER_WATER);
-		}
-	}
-
-	if (CheckSavegameVersion(50)) {
-		Vehicle *v;
-		/* Aircraft units changed from 8 mph to 1 km/h */
-		FOR_ALL_VEHICLES(v) {
-			if (v->type == VEH_AIRCRAFT && v->subtype <= AIR_AIRCRAFT) {
-				const AircraftVehicleInfo *avi = AircraftVehInfo(v->engine_type);
-				v->cur_speed *= 129;
-				v->cur_speed /= 10;
-				v->max_speed = avi->max_speed;
-				v->acceleration = avi->acceleration;
-			}
-		}
-	}
-
-	if (CheckSavegameVersion(49)) FOR_ALL_COMPANIES(c) c->face = ConvertFromOldCompanyManagerFace(c->face);
-
-	if (CheckSavegameVersion(52)) {
-		for (TileIndex t = 0; t < map_size; t++) {
-			if (IsStatueTile(t)) {
-				_m[t].m2 = CalcClosestTownFromTile(t, UINT_MAX)->index;
-			}
-		}
-	}
-
-	/* A patch option containing the proportion of towns that grow twice as
-	 * fast was added in version 54. From version 56 this is now saved in the
-	 * town as cities can be built specifically in the scenario editor. */
-	if (CheckSavegameVersion(56)) {
-		Town *t;
-
-		FOR_ALL_TOWNS(t) {
-			if (_settings_game.economy.larger_towns != 0 && (t->index % _settings_game.economy.larger_towns) == 0) {
-				t->larger_town = true;
-			}
-		}
-	}
-
-	if (CheckSavegameVersion(57)) {
-		Vehicle *v;
-		/* Added a FIFO queue of vehicles loading at stations */
-		FOR_ALL_VEHICLES(v) {
-			if ((v->type != VEH_TRAIN || IsFrontEngine(v)) &&  // for all locs
-					!(v->vehstatus & (VS_STOPPED | VS_CRASHED)) && // not stopped or crashed
-					v->current_order.IsType(OT_LOADING)) {         // loading
-				GetStation(v->last_station_visited)->loading_vehicles.push_back(v);
-
-				/* The loading finished flag is *only* set when actually completely
-				 * finished. Because the vehicle is loading, it is not finished. */
-				ClrBit(v->vehicle_flags, VF_LOADING_FINISHED);
-			}
-		}
-	} else if (CheckSavegameVersion(59)) {
-		/* For some reason non-loading vehicles could be in the station's loading vehicle list */
-
-		Station *st;
-		FOR_ALL_STATIONS(st) {
-			std::list<Vehicle *>::iterator iter;
-			for (iter = st->loading_vehicles.begin(); iter != st->loading_vehicles.end();) {
-				Vehicle *v = *iter;
-				iter++;
-				if (!v->current_order.IsType(OT_LOADING)) st->loading_vehicles.remove(v);
-			}
-		}
-	}
-
-	if (CheckSavegameVersion(58)) {
-		/* patch difficulty number_industries other than zero get bumped to +1
-		 * since a new option (very low at position1) has been added */
-		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_game.difficulty.number_towns++;
-	}
-
-	if (CheckSavegameVersion(64)) {
-		/* copy the signal type/variant and move signal states bits */
-		for (TileIndex t = 0; t < map_size; t++) {
-			if (IsTileType(t, MP_RAILWAY) && HasSignals(t)) {
-				SetSignalStates(t, GB(_m[t].m2, 4, 4));
-				SetSignalVariant(t, INVALID_TRACK, GetSignalVariant(t, TRACK_X));
-				SetSignalType(t, INVALID_TRACK, GetSignalType(t, TRACK_X));
-				ClrBit(_m[t].m2, 7);
-			}
-		}
-	}
-
-	if (CheckSavegameVersion(69)) {
-		/* In some old savegames a bit was cleared when it should not be cleared */
-		Vehicle *v;
-		FOR_ALL_VEHICLES(v) {
-			if (v->type == VEH_ROAD && (v->u.road.state == 250 || v->u.road.state == 251)) {
-				SetBit(v->u.road.state, RVS_IS_STOPPING);
-			}
-		}
-	}
-
-	if (CheckSavegameVersion(70)) {
-		/* Added variables to support newindustries */
-		Industry *i;
-		FOR_ALL_INDUSTRIES(i) i->founder = OWNER_NONE;
-	}
-
-	/* From version 82, old style canals (above sealevel (0), WATER owner) are no longer supported.
-	    Replace the owner for those by OWNER_NONE. */
-	if (CheckSavegameVersion(82)) {
-		for (TileIndex t = 0; t < map_size; t++) {
-			if (IsTileType(t, MP_WATER) &&
-					GetWaterTileType(t) == WATER_TILE_CLEAR &&
-					GetTileOwner(t) == OWNER_WATER &&
-					TileHeight(t) != 0) {
-				SetTileOwner(t, OWNER_NONE);
-			}
-		}
-	}
-
-	/*
-	 * Add the 'previous' owner to the ship depots so we can reset it with
-	 * the correct values when it gets destroyed. This prevents that
-	 * someone can remove canals owned by somebody else and it prevents
-	 * making floods using the removal of ship depots.
-	 */
-	if (CheckSavegameVersion(83)) {
-		for (TileIndex t = 0; t < map_size; t++) {
-			if (IsTileType(t, MP_WATER) && IsShipDepot(t)) {
-				_m[t].m4 = (TileHeight(t) == 0) ? OWNER_WATER : OWNER_NONE;
-			}
-		}
-	}
-
-	if (CheckSavegameVersion(74)) {
-		Station *st;
-		FOR_ALL_STATIONS(st) {
-			for (CargoID c = 0; c < NUM_CARGO; c++) {
-				st->goods[c].last_speed = 0;
-				if (st->goods[c].cargo.Count() != 0) SetBit(st->goods[c].acceptance_pickup, GoodsEntry::PICKUP);
-			}
-		}
-	}
-
-	if (CheckSavegameVersion(78)) {
-		Industry *i;
-		uint j;
-		FOR_ALL_INDUSTRIES(i) {
-			const IndustrySpec *indsp = GetIndustrySpec(i->type);
-			for (j = 0; j < lengthof(i->produced_cargo); j++) {
-				i->produced_cargo[j] = indsp->produced_cargo[j];
-			}
-			for (j = 0; j < lengthof(i->accepts_cargo); j++) {
-				i->accepts_cargo[j] = indsp->accepts_cargo[j];
-			}
-		}
-	}
-
-	/* Before version 81, the density of grass was always stored as zero, and
-	 * grassy trees were always drawn fully grassy. Furthermore, trees on rough
-	 * land used to have zero density, now they have full density. Therefore,
-	 * make all grassy/rough land trees have a density of 3. */
-	if (CheckSavegameVersion(81)) {
-		for (TileIndex t = 0; t < map_size; t++) {
-			if (GetTileType(t) == MP_TREES) {
-				TreeGround groundType = GetTreeGround(t);
-				if (groundType != TREE_GROUND_SNOW_DESERT) SetTreeGroundDensity(t, groundType, 3);
-			}
-		}
-	}
-
-
-	if (CheckSavegameVersion(93)) {
-		/* Rework of orders. */
-		Order *order;
-		FOR_ALL_ORDERS(order) order->ConvertFromOldSavegame();
-
-		Vehicle *v;
-		FOR_ALL_VEHICLES(v) {
-			if (v->orders.list != NULL && v->orders.list->GetFirstOrder() != NULL && !v->orders.list->GetFirstOrder()->IsValid()) {
-				v->orders.list->FreeChain();
-				v->orders.list = NULL;
-			}
-
-			v->current_order.ConvertFromOldSavegame();
-			if (v->type == VEH_ROAD && v->IsPrimaryVehicle() && v->FirstShared() == v) {
-				FOR_VEHICLE_ORDERS(v, order) order->SetNonStopType(ONSF_NO_STOP_AT_INTERMEDIATE_STATIONS);
-			}
-		}
-	} else if (CheckSavegameVersion(94)) {
-		/* Unload and transfer are now mutual exclusive. */
-		Order *order;
-		FOR_ALL_ORDERS(order) {
-			if ((order->GetUnloadType() & (OUFB_UNLOAD | OUFB_TRANSFER)) == (OUFB_UNLOAD | OUFB_TRANSFER)) {
-				order->SetUnloadType(OUFB_TRANSFER);
-				order->SetLoadType(OLFB_NO_LOAD);
-			}
-		}
-
-		Vehicle *v;
-		FOR_ALL_VEHICLES(v) {
-			if ((v->current_order.GetUnloadType() & (OUFB_UNLOAD | OUFB_TRANSFER)) == (OUFB_UNLOAD | OUFB_TRANSFER)) {
-				v->current_order.SetUnloadType(OUFB_TRANSFER);
-				v->current_order.SetLoadType(OLFB_NO_LOAD);
-			}
-		}
-	}
-
-	if (CheckSavegameVersion(84)) {
-		/* Update go to buoy orders because they are just waypoints */
-		Order *order;
-		FOR_ALL_ORDERS(order) {
-			if (order->IsType(OT_GOTO_STATION) && GetStation(order->GetDestination())->IsBuoy()) {
-				order->SetLoadType(OLF_LOAD_IF_POSSIBLE);
-				order->SetUnloadType(OUF_UNLOAD_IF_POSSIBLE);
-			}
-		}
-
-		/* Set all share owners to INVALID_COMPANY for
-		 * 1) all inactive companies
-		 *     (when inactive companies were stored in the savegame - TTD, TTDP and some
-		 *      *really* old revisions of OTTD; else it is already set in InitializeCompanies())
-		 * 2) shares that are owned by inactive companies or self
-		 *     (caused by cheating clients in earlier revisions) */
-		FOR_ALL_COMPANIES(c) {
-			for (uint i = 0; i < 4; i++) {
-				CompanyID company = c->share_owners[i];
-				if (company == INVALID_COMPANY) continue;
-				if (!IsValidCompanyID(company) || company == c->index) c->share_owners[i] = INVALID_COMPANY;
-			}
-		}
-	}
-
-	if (CheckSavegameVersion(86)) {
-		for (TileIndex t = 0; t < map_size; t++) {
-			/* Move river flag and update canals to use water class */
-			if (IsTileType(t, MP_WATER)) {
-				if (GetWaterClass(t) != WATER_CLASS_RIVER) {
-					if (IsWater(t)) {
-						Owner o = GetTileOwner(t);
-						if (o == OWNER_WATER) {
-							MakeWater(t);
-						} else {
-							MakeCanal(t, o, Random());
-						}
-					} else if (IsShipDepot(t)) {
-						Owner o = (Owner)_m[t].m4; // Original water owner
-						SetWaterClass(t, o == OWNER_WATER ? WATER_CLASS_SEA : WATER_CLASS_CANAL);
-					}
-				}
-			}
-		}
-
-		/* Update locks, depots, docks and buoys to have a water class based
-		 * on its neighbouring tiles. Done after river and canal updates to
-		 * ensure neighbours are correct. */
-		for (TileIndex t = 0; t < map_size; t++) {
-			if (GetTileSlope(t, NULL) != SLOPE_FLAT) continue;
-
-			if (IsTileType(t, MP_WATER) && IsLock(t)) SetWaterClassDependingOnSurroundings(t, false);
-			if (IsTileType(t, MP_STATION) && (IsDock(t) || IsBuoy(t))) SetWaterClassDependingOnSurroundings(t, false);
-		}
-	}
-
-	if (CheckSavegameVersion(87)) {
-		for (TileIndex t = 0; t < map_size; t++) {
-			/* skip oil rigs at borders! */
-			if ((IsTileType(t, MP_WATER) || IsBuoyTile(t)) &&
-					(TileX(t) == 0 || TileY(t) == 0 || TileX(t) == MapMaxX() - 1 || TileY(t) == MapMaxY() - 1)) {
-				/* Some version 86 savegames have wrong water class at map borders (under buoy, or after removing buoy).
-				 * This conversion has to be done before buoys with invalid owner are removed. */
-				SetWaterClass(t, WATER_CLASS_SEA);
-			}
-
-			if (IsBuoyTile(t) || IsDriveThroughStopTile(t) || IsTileType(t, MP_WATER)) {
-				Owner o = GetTileOwner(t);
-				if (o < MAX_COMPANIES && !IsValidCompanyID(o)) {
-					_current_company = o;
-					ChangeTileOwner(t, o, INVALID_OWNER);
-				}
-				if (IsBuoyTile(t)) {
-					/* reset buoy owner to OWNER_NONE in the station struct
-					 * (even if it is owned by active company) */
-					GetStationByTile(t)->owner = OWNER_NONE;
-				}
-			} else if (IsTileType(t, MP_ROAD)) {
-				/* works for all RoadTileType */
-				for (RoadType rt = ROADTYPE_ROAD; rt < ROADTYPE_END; rt++) {
-					/* update even non-existing road types to update tile owner too */
-					Owner o = GetRoadOwner(t, rt);
-					if (o < MAX_COMPANIES && !IsValidCompanyID(o)) SetRoadOwner(t, rt, OWNER_NONE);
-				}
-				if (IsLevelCrossing(t)) {
-					Owner o = GetTileOwner(t);
-					if (!IsValidCompanyID(o)) {
-						/* remove leftover rail piece from crossing (from very old savegames) */
-						_current_company = o;
-						DoCommand(t, 0, GetCrossingRailTrack(t), DC_EXEC | DC_BANKRUPT, CMD_REMOVE_SINGLE_RAIL);
-					}
-				}
-			}
-		}
-
-		/* Convert old PF settings to new */
-		if (_settings_game.pf.yapf.rail_use_yapf || CheckSavegameVersion(28)) {
-			_settings_game.pf.pathfinder_for_trains = VPF_YAPF;
-		} else {
-			_settings_game.pf.pathfinder_for_trains = (_settings_game.pf.new_pathfinding_all ? VPF_NPF : VPF_NTP);
-		}
-
-		if (_settings_game.pf.yapf.road_use_yapf || CheckSavegameVersion(28)) {
-			_settings_game.pf.pathfinder_for_roadvehs = VPF_YAPF;
-		} else {
-			_settings_game.pf.pathfinder_for_roadvehs = (_settings_game.pf.new_pathfinding_all ? VPF_NPF : VPF_OPF);
-		}
-
-		if (_settings_game.pf.yapf.ship_use_yapf) {
-			_settings_game.pf.pathfinder_for_ships = VPF_YAPF;
-		} else {
-			_settings_game.pf.pathfinder_for_ships = (_settings_game.pf.new_pathfinding_all ? VPF_NPF : VPF_OPF);
-		}
-	}
-
-	if (CheckSavegameVersion(88)) {
-		/* Profits are now with 8 bit fract */
-		Vehicle *v;
-		FOR_ALL_VEHICLES(v) {
-			v->profit_this_year <<= 8;
-			v->profit_last_year <<= 8;
-			v->running_ticks = 0;
-		}
-	}
-
-	if (CheckSavegameVersion(91)) {
-		/* Increase HouseAnimationFrame from 5 to 7 bits */
-		for (TileIndex t = 0; t < map_size; t++) {
-			if (IsTileType(t, MP_HOUSE) && GetHouseType(t) >= NEW_HOUSE_OFFSET) {
-				SetHouseAnimationFrame(t, GB(_m[t].m6, 3, 5));
-			}
-		}
-	}
-
-	if (CheckSavegameVersion(62)) {
-		/* Remove all trams from savegames without tram support.
-		 * There would be trams without tram track under causing crashes sooner or later. */
-		Vehicle *v;
-		FOR_ALL_VEHICLES(v) {
-			if (v->type == VEH_ROAD && v->First() == v &&
-					HasBit(EngInfo(v->engine_type)->misc_flags, EF_ROAD_TRAM)) {
-				if (_switch_mode_errorstr == INVALID_STRING_ID || _switch_mode_errorstr == STR_NEWGRF_COMPATIBLE_LOAD_WARNING) {
-					_switch_mode_errorstr = STR_LOADGAME_REMOVED_TRAMS;
-				}
-				delete v;
-			}
-		}
-	}
-
-	if (CheckSavegameVersion(99)) {
-		for (TileIndex t = 0; t < map_size; t++) {
-			/* Set newly introduced WaterClass of industry tiles */
-			if (IsTileType(t, MP_STATION) && IsOilRig(t)) {
-				SetWaterClassDependingOnSurroundings(t, true);
-			}
-			if (IsTileType(t, MP_INDUSTRY)) {
-				if ((GetIndustrySpec(GetIndustryType(t))->behaviour & INDUSTRYBEH_BUILT_ONWATER) != 0) {
-					SetWaterClassDependingOnSurroundings(t, true);
-				} else {
-					SetWaterClass(t, WATER_CLASS_INVALID);
-				}
-			}
-
-			/* Replace "house construction year" with "house age" */
-			if (IsTileType(t, MP_HOUSE) && IsHouseCompleted(t)) {
-				_m[t].m5 = Clamp(_cur_year - (_m[t].m5 + ORIGINAL_BASE_YEAR), 0, 0xFF);
-			}
-		}
-	}
-
-	/* Move the signal variant back up one bit for PBS. We don't convert the old PBS
-	 * format here, as an old layout wouldn't work properly anyway. To be safe, we
-	 * clear any possible PBS reservations as well. */
-	if (CheckSavegameVersion(100)) {
-		for (TileIndex t = 0; t < map_size; t++) {
-			switch (GetTileType(t)) {
-				case MP_RAILWAY:
-					if (HasSignals(t)) {
-						/* move the signal variant */
-						SetSignalVariant(t, TRACK_UPPER, HasBit(_m[t].m2, 2) ? SIG_SEMAPHORE : SIG_ELECTRIC);
-						SetSignalVariant(t, TRACK_LOWER, HasBit(_m[t].m2, 6) ? SIG_SEMAPHORE : SIG_ELECTRIC);
-						ClrBit(_m[t].m2, 2);
-						ClrBit(_m[t].m2, 6);
-					}
-
-					/* Clear PBS reservation on track */
-					if (IsRailDepot(t) ||IsRailWaypoint(t)) {
-						SetDepotWaypointReservation(t, false);
-					} else {
-						SetTrackReservation(t, TRACK_BIT_NONE);
-					}
-					break;
-
-				case MP_ROAD: /* Clear PBS reservation on crossing */
-					if (IsLevelCrossing(t)) SetCrossingReservation(t, false);
-					break;
-
-				case MP_STATION: /* Clear PBS reservation on station */
-					if (IsRailwayStation(t)) SetRailwayStationReservation(t, false);
-					break;
-
-				case MP_TUNNELBRIDGE: /* Clear PBS reservation on tunnels/birdges */
-					if (GetTunnelBridgeTransportType(t) == TRANSPORT_RAIL) SetTunnelBridgeReservation(t, false);
-					break;
-
-				default: break;
-			}
-		}
-	}
-
-	/* Reserve all tracks trains are currently on. */
-	if (CheckSavegameVersion(101)) {
-		Vehicle *v;
-		FOR_ALL_VEHICLES(v) {
-			if (v->type == VEH_TRAIN) {
-				if ((v->u.rail.track & TRACK_BIT_WORMHOLE) == TRACK_BIT_WORMHOLE) {
-					TryReserveRailTrack(v->tile, DiagDirToDiagTrack(GetTunnelBridgeDirection(v->tile)));
-				} else if ((v->u.rail.track & TRACK_BIT_MASK) != TRACK_BIT_NONE) {
-					TryReserveRailTrack(v->tile, TrackBitsToTrack(v->u.rail.track));
-				}
-			}
-		}
-
-		/* Give owners to waypoints, based on rail tracks it is sitting on.
-		 * If none is available, specify OWNER_NONE */
-		Waypoint *wp;
-		FOR_ALL_WAYPOINTS(wp) {
-			Owner owner = (IsRailWaypointTile(wp->xy) ? GetTileOwner(wp->xy) : OWNER_NONE);
-			wp->owner = IsValidCompanyID(owner) ? owner : OWNER_NONE;
-		}
-	}
-
-	if (CheckSavegameVersion(102)) {
-		for (TileIndex t = 0; t < map_size; t++) {
-			/* Now all crossings should be in correct state */
-			if (IsLevelCrossingTile(t)) UpdateLevelCrossing(t, false);
-		}
-	}
-
-	if (CheckSavegameVersion(103)) {
-		/* Non-town-owned roads now store the closest town */
-		UpdateNearestTownForRoadTiles(false);
-
-		/* signs with invalid owner left from older savegames */
-		Sign *si;
-		FOR_ALL_SIGNS(si) {
-			if (si->owner != OWNER_NONE && !IsValidCompanyID(si->owner)) si->owner = OWNER_NONE;
-		}
-
-		/* Station can get named based on an industry type, but the current ones
-		 * are not, so mark them as if they are not named by an industry. */
-		Station *st;
-		FOR_ALL_STATIONS(st) {
-			st->indtype = IT_INVALID;
-		}
-	}
-
-	if (CheckSavegameVersion(104)) {
-		Vehicle *v;
-		FOR_ALL_VEHICLES(v) {
-			/* Set engine_type of shadow and rotor */
-			if (v->type == VEH_AIRCRAFT && !IsNormalAircraft(v)) {
-				v->engine_type = v->First()->engine_type;
-			}
-		}
-
-		/* More companies ... */
-		Company *c;
-		FOR_ALL_COMPANIES(c) {
-			if (c->bankrupt_asked == 0xFF) c->bankrupt_asked = 0xFFFF;
-		}
-
-		Engine *e;
-		FOR_ALL_ENGINES(e) {
-			if (e->company_avail == 0xFF) e->company_avail = 0xFFFF;
-		}
-
-		Town *t;
-		FOR_ALL_TOWNS(t) {
-			if (t->have_ratings == 0xFF) t->have_ratings = 0xFFFF;
-			for (uint i = 8; i != MAX_COMPANIES; i++) t->ratings[i] = RATING_INITIAL;
-		}
-	}
-
-	GamelogPrintDebug(1);
-
-	bool ret = InitializeWindowsAndCaches();
-	/* Restore the signals */
-	signal(SIGSEGV, prev_segfault);
-	signal(SIGABRT, prev_abort);
-	return ret;
-}
-
-/** Reload all NewGRF files during a running game. This is a cut-down
- * version of AfterLoadGame().
- * XXX - We need to reset the vehicle position hash because with a non-empty
- * hash AfterLoadVehicles() will loop infinitely. We need AfterLoadVehicles()
- * to recalculate vehicle data as some NewGRF vehicle sets could have been
- * removed or added and changed statistics */
-void ReloadNewGRFData()
-{
-	/* reload grf data */
-	GfxLoadSprites();
-	LoadStringWidthTable();
-	ResetEconomy();
-	/* reload vehicles */
-	ResetVehiclePosHash();
-	AfterLoadVehicles(false);
-	StartupEngines();
-	SetCachedEngineCounts();
-	/* update station and waypoint graphics */
-	AfterLoadWaypoints();
-	AfterLoadStations();
-	/* Check and update house and town values */
-	UpdateHousesAndTowns();
-	/* Update livery selection windows */
-	for (CompanyID i = COMPANY_FIRST; i < MAX_COMPANIES; i++) InvalidateWindowData(WC_COMPANY_COLOR, i, _loaded_newgrf_features.has_2CC);
-	/* redraw the whole screen */
-	MarkWholeScreenDirty();
-	CheckTrainsLengths();
-}
--- a/src/order_base.h
+++ b/src/order_base.h
@@ -431,7 +431,4 @@
 #define FOR_ALL_ORDER_LISTS_FROM(ol, start) for (ol = GetOrderList(start); ol != NULL; ol = (ol->index + 1U < GetOrderListPoolSize()) ? GetOrderList(ol->index + 1U) : NULL) if (ol->IsValid())
 #define FOR_ALL_ORDER_LISTS(ol) FOR_ALL_ORDER_LISTS_FROM(ol, 0)
 
-/* (Un)pack routines */
-Order UnpackOldOrder(uint16 packed);
-
 #endif /* ORDER_H */
--- a/src/order_cmd.cpp
+++ b/src/order_cmd.cpp
@@ -13,7 +13,6 @@
 #include "command_func.h"
 #include "company_func.h"
 #include "news_func.h"
-#include "saveload.h"
 #include "vehicle_gui.h"
 #include "cargotype.h"
 #include "aircraft.h"
@@ -147,82 +146,6 @@
 	this->travel_time   = 0;
 }
 
-void Order::ConvertFromOldSavegame()
-{
-	uint8 old_flags = this->flags;
-	this->flags = 0;
-
-	/* First handle non-stop */
-	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 {
-		this->SetNonStopType((old_flags & 8) ? ONSF_NO_STOP_AT_INTERMEDIATE_STATIONS : ONSF_STOP_EVERYWHERE);
-	}
-
-	switch (this->GetType()) {
-		/* Only a few types need the other savegame conversions. */
-		case OT_GOTO_DEPOT: case OT_GOTO_STATION: case OT_LOADING: break;
-		default: return;
-	}
-
-	if (this->GetType() != OT_GOTO_DEPOT) {
-		/* Then the load flags */
-		if ((old_flags & 2) != 0) { // OFB_UNLOAD
-			this->SetLoadType(OLFB_NO_LOAD);
-		} else if ((old_flags & 4) == 0) { // !OFB_FULL_LOAD
-			this->SetLoadType(OLF_LOAD_IF_POSSIBLE);
-		} else {
-			this->SetLoadType(_settings_client.gui.sg_full_load_any ? OLF_FULL_LOAD_ANY : OLFB_FULL_LOAD);
-		}
-
-		/* Finally fix the unload flags */
-		if ((old_flags & 1) != 0) { // OFB_TRANSFER
-			this->SetUnloadType(OUFB_TRANSFER);
-		} else if ((old_flags & 2) != 0) { // OFB_UNLOAD
-			this->SetUnloadType(OUFB_UNLOAD);
-		} else {
-			this->SetUnloadType(OUF_UNLOAD_IF_POSSIBLE);
-		}
-	} else {
-		/* Then the depot action flags */
-		this->SetDepotActionType(((old_flags & 6) == 4) ? ODATFB_HALT : ODATF_SERVICE_ONLY);
-
-		/* Finally fix the depot type flags */
-		uint t = ((old_flags & 6) == 6) ? ODTFB_SERVICE : ODTF_MANUAL;
-		if ((old_flags & 2) != 0) t |= ODTFB_PART_OF_ORDERS;
-		this->SetDepotOrderType((OrderDepotTypeFlags)t);
-	}
-}
-
-/**
- *
- * Unpacks a order from savegames with version 4 and lower
- *
- */
-static Order UnpackVersion4Order(uint16 packed)
-{
-	return Order(GB(packed, 8, 8) << 16 | GB(packed, 4, 4) << 8 | GB(packed, 0, 4));
-}
-
-/**
- *
- * Unpacks a order from savegames made with TTD(Patch)
- *
- */
-Order UnpackOldOrder(uint16 packed)
-{
-	Order order = UnpackVersion4Order(packed);
-
-	/*
-	 * Sanity check
-	 * TTD stores invalid orders as OT_NOTHING with non-zero flags/station
-	 */
-	if (!order.IsValid() && packed != 0) order.MakeDummy();
-
-	return order;
-}
-
 /**
  *
  * Updates the widgets of a vehicle which contains the order-data
@@ -1898,118 +1821,3 @@
 
 	_backup_orders_tile = 0;
 }
-
-const SaveLoad *GetOrderDescription() {
-static const SaveLoad _order_desc[] = {
-	SLE_VAR(Order, type,  SLE_UINT8),
-	SLE_VAR(Order, flags, SLE_UINT8),
-	SLE_VAR(Order, dest,  SLE_UINT16),
-	SLE_REF(Order, next,  REF_ORDER),
-	SLE_CONDVAR(Order, refit_cargo,    SLE_UINT8,  36, SL_MAX_VERSION),
-	SLE_CONDVAR(Order, refit_subtype,  SLE_UINT8,  36, SL_MAX_VERSION),
-	SLE_CONDVAR(Order, wait_time,      SLE_UINT16, 67, SL_MAX_VERSION),
-	SLE_CONDVAR(Order, travel_time,    SLE_UINT16, 67, SL_MAX_VERSION),
-
-	/* Leftover from the minor savegame version stuff
-	 * We will never use those free bytes, but we have to keep this line to allow loading of old savegames */
-	SLE_CONDNULL(10, 5, 35),
-	SLE_END()
-};
-	return _order_desc;
-}
-
-static void Save_ORDR()
-{
-	Order *order;
-
-	FOR_ALL_ORDERS(order) {
-		SlSetArrayIndex(order->index);
-		SlObject(order, GetOrderDescription());
-	}
-}
-
-static void Load_ORDR()
-{
-	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) */
-		size_t len = SlGetFieldLength();
-		uint i;
-
-		if (CheckSavegameVersion(5)) {
-			/* Pre-version 5 had an other layout for orders
-			    (uint16 instead of uint32) */
-			len /= sizeof(uint16);
-			uint16 *orders = MallocT<uint16>(len + 1);
-
-			SlArray(orders, len, SLE_UINT16);
-
-			for (i = 0; i < len; ++i) {
-				Order *order = new (i) Order();
-				order->AssignOrder(UnpackVersion4Order(orders[i]));
-			}
-
-			free(orders);
-		} else if (CheckSavegameVersionOldStyle(5, 2)) {
-			len /= sizeof(uint16);
-			uint16 *orders = MallocT<uint16>(len + 1);
-
-			SlArray(orders, len, SLE_UINT32);
-
-			for (i = 0; i < len; ++i) {
-				new (i) Order(orders[i]);
-			}
-
-			free(orders);
-		}
-
-		/* Update all the next pointer */
-		for (i = 1; i < len; ++i) {
-			/* The orders were built like this:
-			 *   While the order is valid, set the previous will get it's next pointer set
-			 *   We start with index 1 because no order will have the first in it's next pointer */
-			if (GetOrder(i)->IsValid())
-				GetOrder(i - 1)->next = GetOrder(i);
-		}
-	} else {
-		int index;
-
-		while ((index = SlIterateArray()) != -1) {
-			Order *order = new (index) Order();
-			SlObject(order, GetOrderDescription());
-		}
-	}
-}
-
-const SaveLoad *GetOrderListDescription() {
-static const SaveLoad _orderlist_desc[] = {
-	SLE_REF(OrderList, first,              REF_ORDER),
-	SLE_END()
-};
-	return _orderlist_desc;
-}
-
-static void Save_ORDL()
-{
-	OrderList *list;
-
-	FOR_ALL_ORDER_LISTS(list) {
-		SlSetArrayIndex(list->index);
-		SlObject(list, GetOrderListDescription());
-	}
-}
-
-static void Load_ORDL()
-{
-	int index;
-
-	while ((index = SlIterateArray()) != -1) {
-		OrderList *list = new (index) OrderList();
-		SlObject(list, GetOrderListDescription());
-	}
-}
-
-extern const ChunkHandler _order_chunk_handlers[] = {
-	{ 'ORDR', Save_ORDR, Load_ORDR, CH_ARRAY},
-	{ 'ORDL', Save_ORDL, Load_ORDL, CH_ARRAY | CH_LAST},
-};
deleted file mode 100644
--- a/src/saveload.cpp
+++ /dev/null
@@ -1,1893 +0,0 @@
-/* $Id$ */
-
-/** @file saveload.cpp
- * All actions handling saving and loading goes on in this file. The general actions
- * are as follows for saving a game (loading is analogous):
- * <ol>
- * <li>initialize the writer by creating a temporary memory-buffer for it
- * <li>go through all to-be saved elements, each 'chunk' (ChunkHandler) prefixed by a label
- * <li>use their description array (SaveLoad) to know what elements to save and in what version
- *    of the game it was active (used when loading)
- * <li>write all data byte-by-byte to the temporary buffer so it is endian-safe
- * <li>when the buffer is full; flush it to the output (eg save to file) (_sl.buf, _sl.bufp, _sl.bufe)
- * <li>repeat this until everything is done, and flush any remaining output to file
- * </ol>
- */
-#include "stdafx.h"
-#include "openttd.h"
-#include "debug.h"
-#include "station_base.h"
-#include "thread.h"
-#include "town.h"
-#include "saveload.h"
-#include "network/network.h"
-#include "variables.h"
-#include "window_func.h"
-#include "strings_func.h"
-#include "gfx_func.h"
-#include "core/alloc_func.hpp"
-#include "functions.h"
-#include "core/endian_func.hpp"
-#include "vehicle_base.h"
-#include "company_func.h"
-#include "date_func.h"
-#include "autoreplace_base.h"
-#include "statusbar_gui.h"
-#include "fileio_func.h"
-#include <list>
-#include "gamelog.h"
-
-#include "table/strings.h"
-
-extern const uint16 SAVEGAME_VERSION = 105;
-
-SavegameType _savegame_type; ///< type of savegame we are loading
-
-uint32 _ttdp_version;     ///< version of TTDP savegame (if applicable)
-uint16 _sl_version;       ///< the major savegame version identifier
-byte   _sl_minor_version; ///< the minor savegame version, DO NOT USE!
-
-typedef void WriterProc(size_t len);
-typedef size_t ReaderProc();
-
-/** The saveload struct, containing reader-writer functions, bufffer, version, etc. */
-static struct {
-	bool save;                           ///< are we doing a save or a load atm. True when saving
-	byte need_length;                    ///< ???
-	byte block_mode;                     ///< ???
-	bool error;                          ///< did an error occur or not
-
-	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
-
-	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
-
-	const ChunkHandler* const *chs;      ///< the chunk of data that is being processed atm (vehicles, signs, etc.)
-
-	/* When saving/loading savegames, they are always saved to a temporary memory-place
-	 * to be flushed to file (save) or to final place (load) when full. */
-	byte *bufp, *bufe;                   ///< bufp(ointer) gives the current position in the buffer bufe(nd) gives the end of the buffer
-
-	/* these 3 may be used by compressor/decompressors. */
-	byte *buf;                           ///< pointer to temporary memory to read/write, initialized by SaveLoadFormat->initread/write
-	byte *buf_ori;                       ///< pointer to the original memory location of buf, used to free it afterwards
-	uint bufsize;                        ///< the size of the temporary memory *buf
-	FILE *fh;                            ///< the file from which is read or written to
-
-	void (*excpt_uninit)();              ///< the function to execute on any encountered error
-	StringID error_str;                  ///< the translateable error message to show
-	char *extra_msg;                     ///< the error message
-} _sl;
-
-
-enum NeedLengthValues {NL_NONE = 0, NL_WANTLENGTH = 1, NL_CALCLENGTH = 2};
-
-/** Error handler, calls longjmp to simulate an exception.
- * @todo this was used to have a central place to handle errors, but it is
- * pretty ugly, and seriously interferes with any multithreaded approaches */
-static void NORETURN SlError(StringID string, const char *extra_msg = NULL)
-{
-	_sl.error_str = string;
-	free(_sl.extra_msg);
-	_sl.extra_msg = (extra_msg == NULL) ? NULL : strdup(extra_msg);
-	throw std::exception();
-}
-
-typedef void (*AsyncSaveFinishProc)();
-static AsyncSaveFinishProc _async_save_finish = NULL;
-static ThreadObject *_save_thread;
-
-/**
- * Called by save thread to tell we finished saving.
- */
-static void SetAsyncSaveFinish(AsyncSaveFinishProc proc)
-{
-	if (_exit_game) return;
-	while (_async_save_finish != NULL) CSleep(10);
-
-	_async_save_finish = proc;
-}
-
-/**
- * Handle async save finishes.
- */
-void ProcessAsyncSaveFinish()
-{
-	if (_async_save_finish == NULL) return;
-
-	_async_save_finish();
-
-	_async_save_finish = NULL;
-
-	if (_save_thread != NULL) {
-		_save_thread->Join();
-		delete _save_thread;
-		_save_thread = NULL;
-	}
-}
-
-/**
- * Fill the input buffer by reading from the file with the given reader
- */
-static void SlReadFill()
-{
-	size_t len = _sl.read_bytes();
-	if (len == 0) SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME, "Unexpected end of chunk");
-
-	_sl.bufp = _sl.buf;
-	_sl.bufe = _sl.buf + len;
-	_sl.offs_base += len;
-}
-
-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
- * @param conv VarType type of variable that is used for calculating the size
- * @return Return the size of this type in bytes */
-static inline byte SlCalcConvMemLen(VarType conv)
-{
-	static const byte conv_mem_size[] = {1, 1, 1, 2, 2, 4, 4, 8, 8, 0};
-	byte length = GB(conv, 4, 4);
-	assert(length < lengthof(conv_mem_size));
-	return conv_mem_size[length];
-}
-
-/** Return the size in bytes of a certain type of normal/atomic variable
- * as it appears in a saved game. See VarTypes
- * @param conv VarType type of variable that is used for calculating the size
- * @return Return the size of this type in bytes */
-static inline byte SlCalcConvFileLen(VarType conv)
-{
-	static const byte conv_file_size[] = {1, 1, 2, 2, 4, 4, 8, 8, 2};
-	byte length = GB(conv, 0, 4);
-	assert(length < lengthof(conv_file_size));
-	return conv_file_size[length];
-}
-
-/** Return the size in bytes of a reference (pointer) */
-static inline size_t SlCalcRefLen() {return CheckSavegameVersion(69) ? 2 : 4;}
-
-/** Flush the output buffer by writing to disk with the given reader.
- * If the buffer pointer has not yet been set up, set it up now. Usually
- * only called when the buffer is full, or there is no more data to be processed
- */
-static void SlWriteFill()
-{
-	/* flush the buffer to disk (the writer) */
-	if (_sl.bufp != NULL) {
-		uint len = _sl.bufp - _sl.buf;
-		_sl.offs_base += len;
-		if (len) _sl.write_bytes(len);
-	}
-
-	/* All the data from the buffer has been written away, rewind to the beginning
-	 * to start reading in more data */
-	_sl.bufp = _sl.buf;
-	_sl.bufe = _sl.buf + _sl.bufsize;
-}
-
-/** Read in a single byte from file. If the temporary buffer is full,
- * flush it to its final destination
- * @return return the read byte from file
- */
-static inline byte SlReadByteInternal()
-{
-	if (_sl.bufp == _sl.bufe) SlReadFill();
-	return *_sl.bufp++;
-}
-
-/** Wrapper for SlReadByteInternal */
-byte SlReadByte() {return SlReadByteInternal();}
-
-/** Write away a single byte from memory. If the temporary buffer is full,
- * flush it to its destination (file)
- * @param b the byte that is currently written
- */
-static inline void SlWriteByteInternal(byte b)
-{
-	if (_sl.bufp == _sl.bufe) SlWriteFill();
-	*_sl.bufp++ = b;
-}
-
-/** Wrapper for SlWriteByteInternal */
-void SlWriteByte(byte b) {SlWriteByteInternal(b);}
-
-static inline int SlReadUint16()
-{
-	int x = SlReadByte() << 8;
-	return x | SlReadByte();
-}
-
-static inline uint32 SlReadUint32()
-{
-	uint32 x = SlReadUint16() << 16;
-	return x | SlReadUint16();
-}
-
-static inline uint64 SlReadUint64()
-{
-	uint32 x = SlReadUint32();
-	uint32 y = SlReadUint32();
-	return (uint64)x << 32 | y;
-}
-
-static inline void SlWriteUint16(uint16 v)
-{
-	SlWriteByte(GB(v, 8, 8));
-	SlWriteByte(GB(v, 0, 8));
-}
-
-static inline void SlWriteUint32(uint32 v)
-{
-	SlWriteUint16(GB(v, 16, 16));
-	SlWriteUint16(GB(v,  0, 16));
-}
-
-static inline void SlWriteUint64(uint64 x)
-{
-	SlWriteUint32((uint32)(x >> 32));
-	SlWriteUint32((uint32)x);
-}
-
-/**
- * Read in the header descriptor of an object or an array.
- * If the highest bit is set (7), then the index is bigger than 127
- * elements, so use the next byte to read in the real value.
- * The actual value is then both bytes added with the first shifted
- * 8 bits to the left, and dropping the highest bit (which only indicated a big index).
- * x = ((x & 0x7F) << 8) + SlReadByte();
- * @return Return the value of the index
- */
-static uint SlReadSimpleGamma()
-{
-	uint i = SlReadByte();
-	if (HasBit(i, 7)) {
-		i &= ~0x80;
-		if (HasBit(i, 6)) {
-			i &= ~0x40;
-			if (HasBit(i, 5)) {
-				i &= ~0x20;
-				if (HasBit(i, 4))
-					SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME, "Unsupported gamma");
-				i = (i << 8) | SlReadByte();
-			}
-			i = (i << 8) | SlReadByte();
-		}
-		i = (i << 8) | SlReadByte();
-	}
-	return i;
-}
-
-/**
- * Write the header descriptor of an object or an array.
- * If the element is bigger than 127, use 2 bytes for saving
- * and use the highest byte of the first written one as a notice
- * that the length consists of 2 bytes, etc.. like this:
- * 0xxxxxxx
- * 10xxxxxx xxxxxxxx
- * 110xxxxx xxxxxxxx xxxxxxxx
- * 1110xxxx xxxxxxxx xxxxxxxx xxxxxxxx
- * @param i Index being written
- */
-
-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)(i >> 16));
-			} else {
-				SlWriteByte((byte)(0xC0 | (i >> 16)));
-			}
-			SlWriteByte((byte)(i >> 8));
-		} else {
-			SlWriteByte((byte)(0x80 | (i >> 8)));
-		}
-	}
-	SlWriteByte((byte)i);
-}
-
-/** Return how many bytes used to encode a gamma value */
-static inline uint SlGetGammaLength(size_t i)
-{
-	return 1 + (i >= (1 << 7)) + (i >= (1 << 14)) + (i >= (1 << 21));
-}
-
-static inline uint SlReadSparseIndex() {return SlReadSimpleGamma();}
-static inline void SlWriteSparseIndex(uint index) {SlWriteSimpleGamma(index);}
-
-static inline uint SlReadArrayLength() {return SlReadSimpleGamma();}
-static inline void SlWriteArrayLength(size_t length) {SlWriteSimpleGamma(length);}
-static inline uint SlGetArrayLength(size_t length) {return SlGetGammaLength(length);}
-
-void SlSetArrayIndex(uint index)
-{
-	_sl.need_length = NL_WANTLENGTH;
-	_sl.array_index = index;
-}
-
-static size_t _next_offs;
-
-/**
- * Iterate through the elements of an array and read the whole thing
- * @return The index of the object, or -1 if we have reached the end of current block
- */
-int SlIterateArray()
-{
-	int index;
-
-	/* After reading in the whole array inside the loop
-	 * we must have read in all the data, so we must be at end of current block. */
-	if (_next_offs != 0 && SlGetOffs() != _next_offs) SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME, "Invalid chunk size");
-
-	while (true) {
-		uint length = SlReadArrayLength();
-		if (length == 0) {
-			_next_offs = 0;
-			return -1;
-		}
-
-		_sl.obj_len = --length;
-		_next_offs = SlGetOffs() + length;
-
-		switch (_sl.block_mode) {
-		case CH_SPARSE_ARRAY: index = (int)SlReadSparseIndex(); break;
-		case CH_ARRAY:        index = _sl.array_index++; break;
-		default:
-			DEBUG(sl, 0, "SlIterateArray error");
-			return -1; // error
-		}
-
-		if (length != 0) return index;
-	}
-}
-
-/**
- * Sets the length of either a RIFF object or the number of items in an array.
- * This lets us load an object or an array of arbitrary size
- * @param length The length of the sought object/array
- */
-void SlSetLength(size_t length)
-{
-	assert(_sl.save);
-
-	switch (_sl.need_length) {
-	case NL_WANTLENGTH:
-		_sl.need_length = NL_NONE;
-		switch (_sl.block_mode) {
-		case CH_RIFF:
-			/* Ugly encoding of >16M RIFF chunks
-			 * The lower 24 bits are normal
-			 * The uppermost 4 bits are bits 24:27 */
-			assert(length < (1 << 28));
-			SlWriteUint32((uint32)((length & 0xFFFFFF) | ((length >> 24) << 28)));
-			break;
-		case CH_ARRAY:
-			assert(_sl.last_array_index <= _sl.array_index);
-			while (++_sl.last_array_index <= _sl.array_index)
-				SlWriteArrayLength(1);
-			SlWriteArrayLength(length + 1);
-			break;
-		case CH_SPARSE_ARRAY:
-			SlWriteArrayLength(length + 1 + SlGetArrayLength(_sl.array_index)); // Also include length of sparse index.
-			SlWriteSparseIndex(_sl.array_index);
-			break;
-		default: NOT_REACHED();
-		} break;
-	case NL_CALCLENGTH:
-		_sl.obj_len += (int)length;
-		break;
-	}
-}
-
-/**
- * Save/Load bytes. These do not need to be converted to Little/Big Endian
- * so directly write them or read them to/from file
- * @param ptr The source or destination of the object being manipulated
- * @param length number of bytes this fast CopyBytes lasts
- */
-static void SlCopyBytes(void *ptr, size_t length)
-{
-	byte *p = (byte*)ptr;
-
-	if (_sl.save) {
-		for (; length != 0; length--) {SlWriteByteInternal(*p++);}
-	} else {
-		for (; length != 0; length--) {*p++ = SlReadByteInternal();}
-	}
-}
-
-/** Read in bytes from the file/data structure but don't do
- * anything with them, discarding them in effect
- * @param length The amount of bytes that is being treated this way
- */
-static inline void SlSkipBytes(size_t length)
-{
-	for (; length != 0; length--) SlReadByte();
-}
-
-/* Get the length of the current object */
-size_t SlGetFieldLength() {return _sl.obj_len;}
-
-/** Return a signed-long version of the value of a setting
- * @param ptr pointer to the variable
- * @param conv type of variable, can be a non-clean
- * type, eg one with other flags because it is parsed
- * @return returns the value of the pointer-setting */
-int64 ReadValue(const void *ptr, VarType conv)
-{
-	switch (GetVarMemType(conv)) {
-	case SLE_VAR_BL:  return (*(bool*)ptr != 0);
-	case SLE_VAR_I8:  return *(int8*  )ptr;
-	case SLE_VAR_U8:  return *(byte*  )ptr;
-	case SLE_VAR_I16: return *(int16* )ptr;
-	case SLE_VAR_U16: return *(uint16*)ptr;
-	case SLE_VAR_I32: return *(int32* )ptr;
-	case SLE_VAR_U32: return *(uint32*)ptr;
-	case SLE_VAR_I64: return *(int64* )ptr;
-	case SLE_VAR_U64: return *(uint64*)ptr;
-	case SLE_VAR_NULL:return 0;
-	default: NOT_REACHED();
-	}
-
-	/* useless, but avoids compiler warning this way */
-	return 0;
-}
-
-/** Write the value of a setting
- * @param ptr pointer to the variable
- * @param conv type of variable, can be a non-clean type, eg
- *             with other flags. It is parsed upon read
- * @param val the new value being given to the variable */
-void WriteValue(void *ptr, VarType conv, int64 val)
-{
-	switch (GetVarMemType(conv)) {
-	case SLE_VAR_BL:  *(bool  *)ptr = (val != 0);  break;
-	case SLE_VAR_I8:  *(int8  *)ptr = val; break;
-	case SLE_VAR_U8:  *(byte  *)ptr = val; break;
-	case SLE_VAR_I16: *(int16 *)ptr = val; break;
-	case SLE_VAR_U16: *(uint16*)ptr = val; break;
-	case SLE_VAR_I32: *(int32 *)ptr = val; break;
-	case SLE_VAR_U32: *(uint32*)ptr = val; break;
-	case SLE_VAR_I64: *(int64 *)ptr = val; break;
-	case SLE_VAR_U64: *(uint64*)ptr = val; break;
-	case SLE_VAR_NAME: *(char**)ptr = CopyFromOldName(val); break;
-	case SLE_VAR_NULL: break;
-	default: NOT_REACHED();
-	}
-}
-
-/**
- * Handle all conversion and typechecking of variables here.
- * In the case of saving, read in the actual value from the struct
- * and then write them to file, endian safely. Loading a value
- * goes exactly the opposite way
- * @param ptr The object being filled/read
- * @param conv VarType type of the current element of the struct
- */
-static void SlSaveLoadConv(void *ptr, VarType conv)
-{
-	int64 x = 0;
-
-	if (_sl.save) { // SAVE values
-		/* Read a value from the struct. These ARE endian safe. */
-		x = ReadValue(ptr, conv);
-
-		/* Write the value to the file and check if its value is in the desired range */
-		switch (GetVarFileType(conv)) {
-		case SLE_FILE_I8: assert(x >= -128 && x <= 127);     SlWriteByte(x);break;
-		case SLE_FILE_U8: assert(x >= 0 && x <= 255);        SlWriteByte(x);break;
-		case SLE_FILE_I16:assert(x >= -32768 && x <= 32767); SlWriteUint16(x);break;
-		case SLE_FILE_STRINGID:
-		case SLE_FILE_U16:assert(x >= 0 && x <= 65535);      SlWriteUint16(x);break;
-		case SLE_FILE_I32:
-		case SLE_FILE_U32:                                   SlWriteUint32((uint32)x);break;
-		case SLE_FILE_I64:
-		case SLE_FILE_U64:                                   SlWriteUint64(x);break;
-		default: NOT_REACHED();
-		}
-	} else { // LOAD values
-
-		/* Read a value from the file */
-		switch (GetVarFileType(conv)) {
-		case SLE_FILE_I8:  x = (int8  )SlReadByte();   break;
-		case SLE_FILE_U8:  x = (byte  )SlReadByte();   break;
-		case SLE_FILE_I16: x = (int16 )SlReadUint16(); break;
-		case SLE_FILE_U16: x = (uint16)SlReadUint16(); break;
-		case SLE_FILE_I32: x = (int32 )SlReadUint32(); break;
-		case SLE_FILE_U32: x = (uint32)SlReadUint32(); break;
-		case SLE_FILE_I64: x = (int64 )SlReadUint64(); break;
-		case SLE_FILE_U64: x = (uint64)SlReadUint64(); break;
-		case SLE_FILE_STRINGID: x = RemapOldStringID((uint16)SlReadUint16()); break;
-		default: NOT_REACHED();
-		}
-
-		/* Write The value to the struct. These ARE endian safe. */
-		WriteValue(ptr, conv, x);
-	}
-}
-
-/** Calculate the net length of a string. This is in almost all cases
- * just strlen(), but if the string is not properly terminated, we'll
- * resort to the maximum length of the buffer.
- * @param ptr pointer to the stringbuffer
- * @param length maximum length of the string (buffer). If -1 we don't care
- * about a maximum length, but take string length as it is.
- * @return return the net length of the string */
-static inline size_t SlCalcNetStringLen(const char *ptr, size_t length)
-{
-	if (ptr == NULL) return 0;
-	return min(strlen(ptr), length - 1);
-}
-
-/** Calculate the gross length of the string that it
- * will occupy in the savegame. This includes the real length, returned
- * by SlCalcNetStringLen and the length that the index will occupy.
- * @param ptr pointer to the stringbuffer
- * @param length maximum length of the string (buffer size, etc.)
- * @param conv type of data been used
- * @return return the gross length of the string */
-static inline size_t SlCalcStringLen(const void *ptr, size_t length, VarType conv)
-{
-	size_t len;
-	const char *str;
-
-	switch (GetVarMemType(conv)) {
-		default: NOT_REACHED();
-		case SLE_VAR_STR:
-		case SLE_VAR_STRQ:
-			str = *(const char**)ptr;
-			len = SIZE_MAX;
-			break;
-		case SLE_VAR_STRB:
-		case SLE_VAR_STRBQ:
-			str = (const char*)ptr;
-			len = length;
-			break;
-	}
-
-	len = SlCalcNetStringLen(str, len);
-	return len + SlGetArrayLength(len); // also include the length of the index
-}
-
-/**
- * Save/Load a string.
- * @param ptr the string being manipulated
- * @param length of the string (full length)
- * @param conv must be SLE_FILE_STRING */
-static void SlString(void *ptr, size_t length, VarType conv)
-{
-	size_t len;
-
-	if (_sl.save) { // SAVE string
-		switch (GetVarMemType(conv)) {
-			default: NOT_REACHED();
-			case SLE_VAR_STRB:
-			case SLE_VAR_STRBQ:
-				len = SlCalcNetStringLen((char*)ptr, length);
-				break;
-			case SLE_VAR_STR:
-			case SLE_VAR_STRQ:
-				ptr = *(char**)ptr;
-				len = SlCalcNetStringLen((char*)ptr, SIZE_MAX);
-				break;
-		}
-
-		SlWriteArrayLength(len);
-		SlCopyBytes(ptr, len);
-	} else { // LOAD string
-		len = SlReadArrayLength();
-
-		switch (GetVarMemType(conv)) {
-			default: NOT_REACHED();
-			case SLE_VAR_STRB:
-			case SLE_VAR_STRBQ:
-				if (len >= length) {
-					DEBUG(sl, 1, "String length in savegame is bigger than buffer, truncating");
-					SlCopyBytes(ptr, length);
-					SlSkipBytes(len - length);
-					len = length - 1;
-				} else {
-					SlCopyBytes(ptr, len);
-				}
-				break;
-			case SLE_VAR_STR:
-			case SLE_VAR_STRQ: // Malloc'd string, free previous incarnation, and allocate
-				free(*(char**)ptr);
-				if (len == 0) {
-					*(char**)ptr = NULL;
-				} else {
-					*(char**)ptr = MallocT<char>(len + 1); // terminating '\0'
-					ptr = *(char**)ptr;
-					SlCopyBytes(ptr, len);
-				}
-				break;
-		}
-
-		((char*)ptr)[len] = '\0'; // properly terminate the string
-	}
-}
-
-/**
- * Return the size in bytes of a certain type of atomic array
- * @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(size_t length, VarType conv)
-{
-	return SlCalcConvFileLen(conv) * length;
-}
-
-/**
- * Save/Load an array.
- * @param array The array being manipulated
- * @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, size_t length, VarType conv)
-{
-	/* Automatically calculate the length? */
-	if (_sl.need_length != NL_NONE) {
-		SlSetLength(SlCalcArrayLen(length, conv));
-		/* Determine length only? */
-		if (_sl.need_length == NL_CALCLENGTH) return;
-	}
-
-	/* NOTICE - handle some buggy stuff, in really old versions everything was saved
-	 * as a byte-type. So detect this, and adjust array size accordingly */
-	if (!_sl.save && _sl_version == 0) {
-		/* all arrays except difficulty settings */
-		if (conv == SLE_INT16 || conv == SLE_UINT16 || conv == SLE_STRINGID ||
-				conv == SLE_INT32 || conv == SLE_UINT32) {
-			SlCopyBytes(array, length * SlCalcConvFileLen(conv));
-			return;
-		}
-		/* used for conversion of Money 32bit->64bit */
-		if (conv == (SLE_FILE_I32 | SLE_VAR_I64)) {
-			for (uint i = 0; i < length; i++) {
-				((int64*)array)[i] = (int32)BSWAP32(SlReadUint32());
-			}
-			return;
-		}
-	}
-
-	/* If the size of elements is 1 byte both in file and memory, no special
-	 * conversion is needed, use specialized copy-copy function to speed up things */
-	if (conv == SLE_INT8 || conv == SLE_UINT8) {
-		SlCopyBytes(array, length);
-	} else {
-		byte *a = (byte*)array;
-		byte mem_size = SlCalcConvMemLen(conv);
-
-		for (; length != 0; length --) {
-			SlSaveLoadConv(a, conv);
-			a += mem_size; // get size
-		}
-	}
-}
-
-
-static uint ReferenceToInt(const void* obj, SLRefType rt);
-static void* IntToReference(uint index, SLRefType rt);
-
-
-/**
- * Return the size in bytes of a list
- * @param list The std::list to find the size of
- */
-static inline size_t SlCalcListLen(const void *list)
-{
-	std::list<void *> *l = (std::list<void *> *) list;
-
-	int type_size = CheckSavegameVersion(69) ? 2 : 4;
-	/* Each entry is saved as type_size bytes, plus type_size bytes are used for the length
-	 * of the list */
-	return l->size() * type_size + type_size;
-}
-
-
-/**
- * Save/Load a list.
- * @param list The list being manipulated
- * @param conv SLRefType type of the list (Vehicle *, Station *, etc)
- */
-void SlList(void *list, SLRefType conv)
-{
-	/* Automatically calculate the length? */
-	if (_sl.need_length != NL_NONE) {
-		SlSetLength(SlCalcListLen(list));
-		/* Determine length only? */
-		if (_sl.need_length == NL_CALCLENGTH) return;
-	}
-
-	std::list<void *> *l = (std::list<void *> *) list;
-
-	if (_sl.save) {
-		SlWriteUint32((uint32)l->size());
-
-		std::list<void *>::iterator iter;
-		for (iter = l->begin(); iter != l->end(); ++iter) {
-			void *ptr = *iter;
-			SlWriteUint32(ReferenceToInt(ptr, conv));
-		}
-	} else {
-		uint length = CheckSavegameVersion(69) ? SlReadUint16() : SlReadUint32();
-
-		/* Load each reference and push to the end of the list */
-		for (uint i = 0; i < length; i++) {
-			void *ptr = IntToReference(CheckSavegameVersion(69) ? SlReadUint16() : SlReadUint32(), conv);
-			l->push_back(ptr);
-		}
-	}
-}
-
-
-/** Are we going to save this object or not? */
-static inline bool SlIsObjectValidInSavegame(const SaveLoad *sld)
-{
-	if (_sl_version < sld->version_from || _sl_version > sld->version_to) return false;
-	if (sld->conv & SLF_SAVE_NO) return false;
-
-	return true;
-}
-
-/** Are we going to load this variable when loading a savegame or not?
- * @note If the variable is skipped it is skipped in the savegame
- * bytestream itself as well, so there is no need to skip it somewhere else */
-static inline bool SlSkipVariableOnLoad(const SaveLoad *sld)
-{
-	if ((sld->conv & SLF_NETWORK_NO) && !_sl.save && _networking && !_network_server) {
-		SlSkipBytes(SlCalcConvMemLen(sld->conv) * sld->length);
-		return true;
-	}
-
-	return false;
-}
-
-/**
- * Calculate the size of an object.
- * @param object to be measured
- * @param sld The SaveLoad description of the object so we know how to manipulate it
- * @return size of given objetc
- */
-size_t SlCalcObjLength(const void *object, const SaveLoad *sld)
-{
-	size_t length = 0;
-
-	/* Need to determine the length and write a length tag. */
-	for (; sld->cmd != SL_END; sld++) {
-		length += SlCalcObjMemberLength(object, sld);
-	}
-	return length;
-}
-
-size_t SlCalcObjMemberLength(const void *object, const SaveLoad *sld)
-{
-	assert(_sl.save);
-
-	switch (sld->cmd) {
-		case SL_VAR:
-		case SL_REF:
-		case SL_ARR:
-		case SL_STR:
-		case SL_LST:
-			/* CONDITIONAL saveload types depend on the savegame version */
-			if (!SlIsObjectValidInSavegame(sld)) break;
-
-			switch (sld->cmd) {
-			case SL_VAR: return SlCalcConvFileLen(sld->conv);
-			case SL_REF: return SlCalcRefLen();
-			case SL_ARR: return SlCalcArrayLen(sld->length, sld->conv);
-			case SL_STR: return SlCalcStringLen(GetVariableAddress(object, sld), sld->length, sld->conv);
-			case SL_LST: return SlCalcListLen(GetVariableAddress(object, sld));
-			default: NOT_REACHED();
-			}
-			break;
-		case SL_WRITEBYTE: return 1; // a byte is logically of size 1
-		case SL_VEH_INCLUDE: return SlCalcObjLength(object, GetVehicleDescription(VEH_END));
-		default: NOT_REACHED();
-	}
-	return 0;
-}
-
-
-bool SlObjectMember(void *ptr, const SaveLoad *sld)
-{
-	VarType conv = GB(sld->conv, 0, 8);
-	switch (sld->cmd) {
-	case SL_VAR:
-	case SL_REF:
-	case SL_ARR:
-	case SL_STR:
-	case SL_LST:
-		/* CONDITIONAL saveload types depend on the savegame version */
-		if (!SlIsObjectValidInSavegame(sld)) return false;
-		if (SlSkipVariableOnLoad(sld)) return false;
-
-		switch (sld->cmd) {
-		case SL_VAR: SlSaveLoadConv(ptr, conv); break;
-		case SL_REF: // Reference variable, translate
-			if (_sl.save) {
-				SlWriteUint32(ReferenceToInt(*(void**)ptr, (SLRefType)conv));
-			} else {
-				*(void**)ptr = IntToReference(CheckSavegameVersion(69) ? SlReadUint16() : SlReadUint32(), (SLRefType)conv);
-			}
-			break;
-		case SL_ARR: SlArray(ptr, sld->length, conv); break;
-		case SL_STR: SlString(ptr, sld->length, conv); break;
-		case SL_LST: SlList(ptr, (SLRefType)conv); break;
-		default: NOT_REACHED();
-		}
-		break;
-
-	/* SL_WRITEBYTE translates a value of a variable to another one upon
-	 * saving or loading.
-	 * XXX - variable renaming abuse
-	 * game_value: the value of the variable ingame is abused by sld->version_from
-	 * file_value: the value of the variable in the savegame is abused by sld->version_to */
-	case SL_WRITEBYTE:
-		if (_sl.save) {
-			SlWriteByte(sld->version_to);
-		} else {
-			*(byte*)ptr = sld->version_from;
-		}
-		break;
-
-	/* SL_VEH_INCLUDE loads common code for vehicles */
-	case SL_VEH_INCLUDE:
-		SlObject(ptr, GetVehicleDescription(VEH_END));
-		break;
-	default: NOT_REACHED();
-	}
-	return true;
-}
-
-/**
- * Main SaveLoad function.
- * @param object The object that is being saved or loaded
- * @param sld The SaveLoad description of the object so we know how to manipulate it
- */
-void SlObject(void *object, const SaveLoad *sld)
-{
-	/* Automatically calculate the length? */
-	if (_sl.need_length != NL_NONE) {
-		SlSetLength(SlCalcObjLength(object, sld));
-		if (_sl.need_length == NL_CALCLENGTH) return;
-	}
-
-	for (; sld->cmd != SL_END; sld++) {
-		void *ptr = sld->global ? sld->address : GetVariableAddress(object, sld);
-		SlObjectMember(ptr, sld);
-	}
-}
-
-/**
- * Save or Load (a list of) global variables
- * @param sldg The global variable that is being loaded or saved
- */
-void SlGlobList(const SaveLoadGlobVarList *sldg)
-{
-	SlObject(NULL, (const SaveLoad*)sldg);
-}
-
-/**
- * Do something of which I have no idea what it is :P
- * @param proc The callback procedure that is called
- * @param arg The variable that will be used for the callback procedure
- */
-void SlAutolength(AutolengthProc *proc, void *arg)
-{
-	size_t offs;
-
-	assert(_sl.save);
-
-	/* Tell it to calculate the length */
-	_sl.need_length = NL_CALCLENGTH;
-	_sl.obj_len = 0;
-	proc(arg);
-
-	/* Setup length */
-	_sl.need_length = NL_WANTLENGTH;
-	SlSetLength(_sl.obj_len);
-
-	offs = SlGetOffs() + _sl.obj_len;
-
-	/* And write the stuff */
-	proc(arg);
-
-	if (offs != SlGetOffs()) SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME, "Invalid chunk size");
-}
-
-/**
- * Load a chunk of data (eg vehicles, stations, etc.)
- * @param ch The chunkhandler that will be used for the operation
- */
-static void SlLoadChunk(const ChunkHandler *ch)
-{
-	byte m = SlReadByte();
-	size_t len;
-	size_t endoffs;
-
-	_sl.block_mode = m;
-	_sl.obj_len = 0;
-
-	switch (m) {
-	case CH_ARRAY:
-		_sl.array_index = 0;
-		ch->load_proc();
-		break;
-	case CH_SPARSE_ARRAY:
-		ch->load_proc();
-		break;
-	default:
-		if ((m & 0xF) == CH_RIFF) {
-			/* Read length */
-			len = (SlReadByte() << 16) | ((m >> 4) << 24);
-			len += SlReadUint16();
-			_sl.obj_len = len;
-			endoffs = SlGetOffs() + len;
-			ch->load_proc();
-			if (SlGetOffs() != endoffs) SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME, "Invalid chunk size");
-		} else {
-			SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME, "Invalid chunk type");
-		}
-		break;
-	}
-}
-
-/* Stub Chunk handlers to only calculate length and do nothing else */
-static ChunkSaveLoadProc *_tmp_proc_1;
-static inline void SlStubSaveProc2(void *arg) {_tmp_proc_1();}
-static void SlStubSaveProc() {SlAutolength(SlStubSaveProc2, NULL);}
-
-/** Save a chunk of data (eg. vehicles, stations, etc.). Each chunk is
- * prefixed by an ID identifying it, followed by data, and terminator where appropiate
- * @param ch The chunkhandler that will be used for the operation
- */
-static void SlSaveChunk(const ChunkHandler *ch)
-{
-	ChunkSaveLoadProc *proc = ch->save_proc;
-
-	/* Don't save any chunk information if there is no save handler. */
-	if (proc == NULL) return;
-
-	SlWriteUint32(ch->id);
-	DEBUG(sl, 2, "Saving chunk %c%c%c%c", ch->id >> 24, ch->id >> 16, ch->id >> 8, ch->id);
-
-	if (ch->flags & CH_AUTO_LENGTH) {
-		/* Need to calculate the length. Solve that by calling SlAutoLength in the save_proc. */
-		_tmp_proc_1 = proc;
-		proc = SlStubSaveProc;
-	}
-
-	_sl.block_mode = ch->flags & CH_TYPE_MASK;
-	switch (ch->flags & CH_TYPE_MASK) {
-	case CH_RIFF:
-		_sl.need_length = NL_WANTLENGTH;
-		proc();
-		break;
-	case CH_ARRAY:
-		_sl.last_array_index = 0;
-		SlWriteByte(CH_ARRAY);
-		proc();
-		SlWriteArrayLength(0); // Terminate arrays
-		break;
-	case CH_SPARSE_ARRAY:
-		SlWriteByte(CH_SPARSE_ARRAY);
-		proc();
-		SlWriteArrayLength(0); // Terminate arrays
-		break;
-	default: NOT_REACHED();
-	}
-}
-
-/** Save all chunks */
-static void SlSaveChunks()
-{
-	const ChunkHandler *ch;
-	const ChunkHandler* const *chsc;
-	uint p;
-
-	for (p = 0; p != CH_NUM_PRI_LEVELS; p++) {
-		for (chsc = _sl.chs; (ch = *chsc++) != NULL;) {
-			while (true) {
-				if (((ch->flags >> CH_PRI_SHL) & (CH_NUM_PRI_LEVELS - 1)) == p)
-					SlSaveChunk(ch);
-				if (ch->flags & CH_LAST)
-					break;
-				ch++;
-			}
-		}
-	}
-
-	/* Terminator */
-	SlWriteUint32(0);
-}
-
-/** Find the ChunkHandler that will be used for processing the found
- * chunk in the savegame or in memory
- * @param id the chunk in question
- * @return returns the appropiate chunkhandler
- */
-static const ChunkHandler *SlFindChunkHandler(uint32 id)
-{
-	const ChunkHandler *ch;
-	const ChunkHandler *const *chsc;
-	for (chsc = _sl.chs; (ch = *chsc++) != NULL;) {
-		for (;;) {
-			if (ch->id == id) return ch;
-			if (ch->flags & CH_LAST) break;
-			ch++;
-		}
-	}
-	return NULL;
-}
-
-/** Load all chunks */
-static void SlLoadChunks()
-{
-	uint32 id;
-	const ChunkHandler *ch;
-
-	for (id = SlReadUint32(); id != 0; id = SlReadUint32()) {
-		DEBUG(sl, 2, "Loading chunk %c%c%c%c", id >> 24, id >> 16, id >> 8, id);
-
-		ch = SlFindChunkHandler(id);
-		if (ch == NULL) SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME, "Unknown chunk type");
-		SlLoadChunk(ch);
-	}
-}
-
-/*******************************************
- ********** START OF LZO CODE **************
- *******************************************/
-#define LZO_SIZE 8192
-
-#include "minilzo.h"
-
-static size_t ReadLZO()
-{
-	byte out[LZO_SIZE + LZO_SIZE / 64 + 16 + 3 + 8];
-	uint32 tmp[2];
-	uint32 size;
-	uint len;
-
-	/* Read header*/
-	if (fread(tmp, sizeof(tmp), 1, _sl.fh) != 1) SlError(STR_GAME_SAVELOAD_ERROR_FILE_NOT_READABLE, "File read failed");
-
-	/* Check if size is bad */
-	((uint32*)out)[0] = size = tmp[1];
-
-	if (_sl_version != 0) {
-		tmp[0] = TO_BE32(tmp[0]);
-		size = TO_BE32(size);
-	}
-
-	if (size >= sizeof(out)) SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME, "Inconsistent size");
-
-	/* Read block */
-	if (fread(out + sizeof(uint32), size, 1, _sl.fh) != 1) SlError(STR_GAME_SAVELOAD_ERROR_FILE_NOT_READABLE);
-
-	/* Verify checksum */
-	if (tmp[0] != lzo_adler32(0, out, size + sizeof(uint32))) SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME, "Bad checksum");
-
-	/* Decompress */
-	lzo1x_decompress(out + sizeof(uint32)*1, size, _sl.buf, &len, NULL);
-	return len;
-}
-
-/* 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(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, (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);
-}
-
-static bool InitLZO()
-{
-	_sl.bufsize = LZO_SIZE;
-	_sl.buf = _sl.buf_ori = MallocT<byte>(LZO_SIZE);
-	return true;
-}
-
-static void UninitLZO()
-{
-	free(_sl.buf_ori);
-}
-
-/*********************************************
- ******** START OF NOCOMP CODE (uncompressed)*
- *********************************************/
-static size_t ReadNoComp()
-{
-	return fread(_sl.buf, 1, LZO_SIZE, _sl.fh);
-}
-
-static void WriteNoComp(size_t size)
-{
-	if (fwrite(_sl.buf, 1, size, _sl.fh) != size) SlError(STR_GAME_SAVELOAD_ERROR_FILE_NOT_WRITEABLE);
-}
-
-static bool InitNoComp()
-{
-	_sl.bufsize = LZO_SIZE;
-	_sl.buf = _sl.buf_ori = MallocT<byte>(LZO_SIZE);
-	return true;
-}
-
-static void UninitNoComp()
-{
-	free(_sl.buf_ori);
-}
-
-/********************************************
- ********** START OF MEMORY CODE (in ram)****
- ********************************************/
-
-#include "table/sprites.h"
-#include "gui.h"
-
-struct ThreadedSave {
-	uint count;
-	byte ff_state;
-	bool saveinprogress;
-	CursorID cursor;
-};
-
-/* A maximum size of of 128K * 500 = 64.000KB savegames */
-STATIC_OLD_POOL(Savegame, byte, 17, 500, NULL, NULL)
-static ThreadedSave _ts;
-
-static bool InitMem()
-{
-	_ts.count = 0;
-
-	_Savegame_pool.CleanPool();
-	_Savegame_pool.AddBlockToPool();
-
-	/* A block from the pool is a contigious area of memory, so it is safe to write to it sequentially */
-	_sl.bufsize = GetSavegamePoolSize();
-	_sl.buf = GetSavegame(_ts.count);
-	return true;
-}
-
-static void UnInitMem()
-{
-	_Savegame_pool.CleanPool();
-}
-
-static void WriteMem(size_t size)
-{
-	_ts.count += (uint)size;
-	/* Allocate new block and new buffer-pointer */
-	_Savegame_pool.AddBlockIfNeeded(_ts.count);
-	_sl.buf = GetSavegame(_ts.count);
-}
-
-/********************************************
- ********** START OF ZLIB CODE **************
- ********************************************/
-
-#if defined(WITH_ZLIB)
-#include <zlib.h>
-
-static z_stream _z;
-
-static bool InitReadZlib()
-{
-	memset(&_z, 0, sizeof(_z));
-	if (inflateInit(&_z) != Z_OK) return false;
-
-	_sl.bufsize = 4096;
-	_sl.buf = _sl.buf_ori = MallocT<byte>(4096 + 4096); // also contains fread buffer
-	return true;
-}
-
-static size_t ReadZlib()
-{
-	int r;
-
-	_z.next_out = _sl.buf;
-	_z.avail_out = 4096;
-
-	do {
-		/* read more bytes from the file? */
-		if (_z.avail_in == 0) {
-			_z.avail_in = (uint)fread(_z.next_in = _sl.buf + 4096, 1, 4096, _sl.fh);
-		}
-
-		/* inflate the data */
-		r = inflate(&_z, 0);
-		if (r == Z_STREAM_END)
-			break;
-
-		if (r != Z_OK) SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR, "inflate() failed");
-	} while (_z.avail_out);
-
-	return 4096 - _z.avail_out;
-}
-
-static void UninitReadZlib()
-{
-	inflateEnd(&_z);
-	free(_sl.buf_ori);
-}
-
-static bool InitWriteZlib()
-{
-	memset(&_z, 0, sizeof(_z));
-	if (deflateInit(&_z, 6) != Z_OK) return false;
-
-	_sl.bufsize = 4096;
-	_sl.buf = _sl.buf_ori = MallocT<byte>(4096); // also contains fread buffer
-	return true;
-}
-
-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 = (uInt)len;
-	do {
-		z->next_out = buf;
-		z->avail_out = sizeof(buf);
-		r = deflate(z, mode);
-			/* bytes were emitted? */
-		if ((n = sizeof(buf) - z->avail_out) != 0) {
-			if (fwrite(buf, n, 1, _sl.fh) != 1) SlError(STR_GAME_SAVELOAD_ERROR_FILE_NOT_WRITEABLE);
-		}
-		if (r == Z_STREAM_END)
-			break;
-		if (r != Z_OK) SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR, "zlib returned error code");
-	} while (z->avail_in || !z->avail_out);
-}
-
-static void WriteZlib(size_t len)
-{
-	WriteZlibLoop(&_z, _sl.buf, len, 0);
-}
-
-static void UninitWriteZlib()
-{
-	/* flush any pending output. */
-	if (_sl.fh) WriteZlibLoop(&_z, NULL, 0, Z_FINISH);
-	deflateEnd(&_z);
-	free(_sl.buf_ori);
-}
-
-#endif /* WITH_ZLIB */
-
-/*******************************************
- ************* END OF CODE *****************
- *******************************************/
-
-/* these define the chunks */
-extern const ChunkHandler _gamelog_chunk_handlers[];
-extern const ChunkHandler _misc_chunk_handlers[];
-extern const ChunkHandler _name_chunk_handlers[];
-extern const ChunkHandler _cheat_chunk_handlers[] ;
-extern const ChunkHandler _setting_chunk_handlers[];
-extern const ChunkHandler _company_chunk_handlers[];
-extern const ChunkHandler _engine_chunk_handlers[];
-extern const ChunkHandler _veh_chunk_handlers[];
-extern const ChunkHandler _waypoint_chunk_handlers[];
-extern const ChunkHandler _depot_chunk_handlers[];
-extern const ChunkHandler _order_chunk_handlers[];
-extern const ChunkHandler _town_chunk_handlers[];
-extern const ChunkHandler _sign_chunk_handlers[];
-extern const ChunkHandler _station_chunk_handlers[];
-extern const ChunkHandler _industry_chunk_handlers[];
-extern const ChunkHandler _economy_chunk_handlers[];
-extern const ChunkHandler _animated_tile_chunk_handlers[];
-extern const ChunkHandler _newgrf_chunk_handlers[];
-extern const ChunkHandler _group_chunk_handlers[];
-extern const ChunkHandler _cargopacket_chunk_handlers[];
-extern const ChunkHandler _autoreplace_chunk_handlers[];
-
-static const ChunkHandler * const _chunk_handlers[] = {
-	_gamelog_chunk_handlers,
-	_misc_chunk_handlers,
-	_name_chunk_handlers,
-	_cheat_chunk_handlers,
-	_setting_chunk_handlers,
-	_veh_chunk_handlers,
-	_waypoint_chunk_handlers,
-	_depot_chunk_handlers,
-	_order_chunk_handlers,
-	_industry_chunk_handlers,
-	_economy_chunk_handlers,
-	_engine_chunk_handlers,
-	_town_chunk_handlers,
-	_sign_chunk_handlers,
-	_station_chunk_handlers,
-	_company_chunk_handlers,
-	_animated_tile_chunk_handlers,
-	_newgrf_chunk_handlers,
-	_group_chunk_handlers,
-	_cargopacket_chunk_handlers,
-	_autoreplace_chunk_handlers,
-	NULL,
-};
-
-/**
- * Pointers cannot be saved to a savegame, so this functions gets
- * the index of the item, and if not available, it hussles with
- * pointers (looks really bad :()
- * Remember that a NULL item has value 0, and all
- * indeces have +1, so vehicle 0 is saved as index 1.
- * @param obj The object that we want to get the index of
- * @param rt SLRefType type of the object the index is being sought of
- * @return Return the pointer converted to an index of the type pointed to
- */
-static uint ReferenceToInt(const void *obj, SLRefType rt)
-{
-	if (obj == NULL) return 0;
-
-	switch (rt) {
-		case REF_VEHICLE_OLD: // Old vehicles we save as new onces
-		case REF_VEHICLE:   return ((const  Vehicle*)obj)->index + 1;
-		case REF_STATION:   return ((const  Station*)obj)->index + 1;
-		case REF_TOWN:      return ((const     Town*)obj)->index + 1;
-		case REF_ORDER:     return ((const    Order*)obj)->index + 1;
-		case REF_ROADSTOPS: return ((const RoadStop*)obj)->index + 1;
-		case REF_ENGINE_RENEWS: return ((const EngineRenew*)obj)->index + 1;
-		case REF_CARGO_PACKET:  return ((const CargoPacket*)obj)->index + 1;
-		case REF_ORDERLIST:     return ((const   OrderList*)obj)->index + 1;
-		default: NOT_REACHED();
-	}
-
-	return 0; // avoid compiler warning
-}
-
-/**
- * Pointers cannot be loaded from a savegame, so this function
- * gets the index from the savegame and returns the appropiate
- * pointer from the already loaded base.
- * Remember that an index of 0 is a NULL pointer so all indeces
- * are +1 so vehicle 0 is saved as 1.
- * @param index The index that is being converted to a pointer
- * @param rt SLRefType type of the object the pointer is sought of
- * @return Return the index converted to a pointer of any type
- */
-static void *IntToReference(uint index, SLRefType rt)
-{
-	/* After version 4.3 REF_VEHICLE_OLD is saved as REF_VEHICLE,
-	 * and should be loaded like that */
-	if (rt == REF_VEHICLE_OLD && !CheckSavegameVersionOldStyle(4, 4)) {
-		rt = REF_VEHICLE;
-	}
-
-	/* No need to look up NULL pointers, just return immediately */
-	if (rt != REF_VEHICLE_OLD && index == 0) {
-		return NULL;
-	}
-
-	index--; // correct for the NULL index
-
-	switch (rt) {
-		case REF_ORDERLIST:
-			if (_OrderList_pool.AddBlockIfNeeded(index)) return GetOrderList(index);
-			error("Orders: failed loading savegame: too many order lists");
-
-		case REF_ORDER:
-			if (_Order_pool.AddBlockIfNeeded(index)) return GetOrder(index);
-			error("Orders: failed loading savegame: too many orders");
-
-		case REF_VEHICLE:
-			if (_Vehicle_pool.AddBlockIfNeeded(index)) return GetVehicle(index);
-			error("Vehicles: failed loading savegame: too many vehicles");
-
-		case REF_STATION:
-			if (_Station_pool.AddBlockIfNeeded(index)) return GetStation(index);
-			error("Stations: failed loading savegame: too many stations");
-
-		case REF_TOWN:
-			if (_Town_pool.AddBlockIfNeeded(index)) return GetTown(index);
-			error("Towns: failed loading savegame: too many towns");
-
-		case REF_ROADSTOPS:
-			if (_RoadStop_pool.AddBlockIfNeeded(index)) return GetRoadStop(index);
-			error("RoadStops: failed loading savegame: too many RoadStops");
-
-		case REF_ENGINE_RENEWS:
-			if (_EngineRenew_pool.AddBlockIfNeeded(index)) return GetEngineRenew(index);
-			error("EngineRenews: failed loading savegame: too many EngineRenews");
-
-		case REF_CARGO_PACKET:
-			if (_CargoPacket_pool.AddBlockIfNeeded(index)) return GetCargoPacket(index);
-			error("CargoPackets: failed loading savegame: too many Cargo packets");
-
-		case REF_VEHICLE_OLD:
-			/* Old vehicles were saved differently:
-			 * invalid vehicle was 0xFFFF,
-			 * and the index was not - 1.. correct for this */
-			index++;
-			if (index == INVALID_VEHICLE) return NULL;
-
-			if (_Vehicle_pool.AddBlockIfNeeded(index)) return GetVehicle(index);
-			error("Vehicles: failed loading savegame: too many vehicles");
-
-		default: NOT_REACHED();
-	}
-
-	return NULL;
-}
-
-/** The format for a reader/writer type of a savegame */
-struct SaveLoadFormat {
-	const char *name;           ///< name of the compressor/decompressor (debug-only)
-	uint32 tag;                 ///< the 4-letter tag by which it is identified in the savegame
-
-	bool (*init_read)();        ///< function executed upon initalization of the loader
-	ReaderProc *reader;         ///< function that loads the data from the file
-	void (*uninit_read)();      ///< function executed when reading is finished
-
-	bool (*init_write)();       ///< function executed upon intialization of the saver
-	WriterProc *writer;         ///< function that saves the data to the file
-	void (*uninit_write)();     ///< function executed when writing is done
-};
-
-static const SaveLoadFormat _saveload_formats[] = {
-	{"memory", 0,                NULL,         NULL,       NULL,           InitMem,       WriteMem,    UnInitMem},
-	{"lzo",    TO_BE32X('OTTD'), InitLZO,      ReadLZO,    UninitLZO,      InitLZO,       WriteLZO,    UninitLZO},
-	{"none",   TO_BE32X('OTTN'), InitNoComp,   ReadNoComp, UninitNoComp,   InitNoComp,    WriteNoComp, UninitNoComp},
-#if defined(WITH_ZLIB)
-	{"zlib",   TO_BE32X('OTTZ'), InitReadZlib, ReadZlib,   UninitReadZlib, InitWriteZlib, WriteZlib,   UninitWriteZlib},
-#else
-	{"zlib",   TO_BE32X('OTTZ'), NULL,         NULL,       NULL,           NULL,          NULL,        NULL},
-#endif
-};
-
-/**
- * Return the savegameformat of the game. Whether it was create with ZLIB compression
- * uncompressed, or another type
- * @param s Name of the savegame format. If NULL it picks the first available one
- * @return Pointer to SaveLoadFormat struct giving all characteristics of this type of savegame
- */
-static const SaveLoadFormat *GetSavegameFormat(const char *s)
-{
-	const SaveLoadFormat *def = endof(_saveload_formats) - 1;
-
-	/* find default savegame format, the highest one with which files can be written */
-	while (!def->init_write) def--;
-
-	if (s != NULL && s[0] != '\0') {
-		const SaveLoadFormat *slf;
-		for (slf = &_saveload_formats[0]; slf != endof(_saveload_formats); slf++) {
-			if (slf->init_write != NULL && strcmp(s, slf->name) == 0)
-				return slf;
-		}
-
-		ShowInfoF("Savegame format '%s' is not available. Reverting to '%s'.", s, def->name);
-	}
-	return def;
-}
-
-/* actual loader/saver function */
-void InitializeGame(uint size_x, uint size_y, bool reset_date);
-extern bool AfterLoadGame();
-extern void SaveViewportBeforeSaveGame();
-extern bool LoadOldSaveGame(const char *file);
-
-/** Small helper function to close the to be loaded savegame an signal error */
-static inline SaveOrLoadResult AbortSaveLoad()
-{
-	if (_sl.fh != NULL) fclose(_sl.fh);
-
-	_sl.fh = NULL;
-	return SL_ERROR;
-}
-
-/** Update the gui accordingly when starting saving
- * and set locks on saveload. Also turn off fast-forward cause with that
- * saving takes Aaaaages */
-static void SaveFileStart()
-{
-	_ts.ff_state = _fast_forward;
-	_fast_forward = 0;
-	if (_cursor.sprite == SPR_CURSOR_MOUSE) SetMouseCursor(SPR_CURSOR_ZZZ, PAL_NONE);
-
-	InvalidateWindowData(WC_STATUS_BAR, 0, SBI_SAVELOAD_START);
-	_ts.saveinprogress = true;
-}
-
-/** Update the gui accordingly when saving is done and release locks
- * on saveload */
-static void SaveFileDone()
-{
-	if (_game_mode != GM_MENU) _fast_forward = _ts.ff_state;
-	if (_cursor.sprite == SPR_CURSOR_ZZZ) SetMouseCursor(SPR_CURSOR_MOUSE, PAL_NONE);
-
-	InvalidateWindowData(WC_STATUS_BAR, 0, SBI_SAVELOAD_FINISH);
-	_ts.saveinprogress = false;
-}
-
-/** Set the error message from outside of the actual loading/saving of the game (AfterLoadGame and friends) */
-void SetSaveLoadError(StringID str)
-{
-	_sl.error_str = str;
-}
-
-/** Get the string representation of the error message */
-const char *GetSaveLoadErrorString()
-{
-	SetDParam(0, _sl.error_str);
-	SetDParamStr(1, _sl.extra_msg);
-
-	static char err_str[512];
-	GetString(err_str, _sl.save ? STR_4007_GAME_SAVE_FAILED : STR_4009_GAME_LOAD_FAILED, lastof(err_str));
-	return err_str;
-}
-
-/** Show a gui message when saving has failed */
-static void SaveFileError()
-{
-	SetDParamStr(0, GetSaveLoadErrorString());
-	ShowErrorMessage(STR_JUST_RAW_STRING, STR_NULL, 0, 0);
-	SaveFileDone();
-}
-
-/** We have written the whole game into memory, _Savegame_pool, now find
- * and appropiate compressor and start writing to file.
- */
-static SaveOrLoadResult SaveFileToDisk(bool threaded)
-{
-	const SaveLoadFormat *fmt;
-	uint32 hdr[2];
-
-	_sl.excpt_uninit = NULL;
-	try {
-		fmt = GetSavegameFormat(_savegame_format);
-
-		/* We have written our stuff to memory, now write it to file! */
-		hdr[0] = fmt->tag;
-		hdr[1] = TO_BE32(SAVEGAME_VERSION << 16);
-		if (fwrite(hdr, sizeof(hdr), 1, _sl.fh) != 1) SlError(STR_GAME_SAVELOAD_ERROR_FILE_NOT_WRITEABLE);
-
-		if (!fmt->init_write()) SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR, "cannot initialize compressor");
-
-		{
-			uint i;
-			uint count = 1 << Savegame_POOL_BLOCK_SIZE_BITS;
-
-			if (_ts.count != _sl.offs_base) SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME, "Unexpected size of chunk");
-			for (i = 0; i != _Savegame_pool.GetBlockCount() - 1; i++) {
-				_sl.buf = _Savegame_pool.blocks[i];
-				fmt->writer(count);
-			}
-
-			/* The last block is (almost) always not fully filled, so only write away
-			 * as much data as it is in there */
-			_sl.buf = _Savegame_pool.blocks[i];
-			fmt->writer(_ts.count - (i * count));
-		}
-
-		fmt->uninit_write();
-		if (_ts.count != _sl.offs_base) SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME, "Unexpected size of chunk");
-		GetSavegameFormat("memory")->uninit_write(); // clean the memorypool
-		fclose(_sl.fh);
-
-		if (threaded) SetAsyncSaveFinish(SaveFileDone);
-
-		return SL_OK;
-	}
-	catch (...) {
-		AbortSaveLoad();
-		if (_sl.excpt_uninit != NULL) _sl.excpt_uninit();
-
-		/* Skip the "color" character */
-		DEBUG(sl, 0, GetSaveLoadErrorString() + 3);
-
-		if (threaded) {
-			SetAsyncSaveFinish(SaveFileError);
-		} else {
-			SaveFileError();
-		}
-		return SL_ERROR;
-	}
-}
-
-static void SaveFileToDiskThread(void *arg)
-{
-	SaveFileToDisk(true);
-}
-
-void WaitTillSaved()
-{
-	if (_save_thread == NULL) return;
-
-	_save_thread->Join();
-	delete _save_thread;
-	_save_thread = NULL;
-}
-
-/**
- * Main Save or Load function where the high-level saveload functions are
- * handled. It opens the savegame, selects format and checks versions
- * @param filename The name of the savegame being created/loaded
- * @param mode Save or load. Load can also be a TTD(Patch) game. Use SL_LOAD, SL_OLD_LOAD or SL_SAVE
- * @return Return the results of the action. SL_OK, SL_ERROR or SL_REINIT ("unload" the game)
- */
-SaveOrLoadResult SaveOrLoad(const char *filename, int mode, Subdirectory sb)
-{
-	uint32 hdr[2];
-	const SaveLoadFormat *fmt;
-
-	/* An instance of saving is already active, so don't go saving again */
-	if (_ts.saveinprogress && mode == SL_SAVE) {
-		/* if not an autosave, but a user action, show error message */
-		if (!_do_autosave) ShowErrorMessage(INVALID_STRING_ID, STR_SAVE_STILL_IN_PROGRESS, 0, 0);
-		return SL_OK;
-	}
-	WaitTillSaved();
-
-	_next_offs = 0;
-
-	/* Load a TTDLX or TTDPatch game */
-	if (mode == SL_OLD_LOAD) {
-		InitializeGame(256, 256, true); // set a mapsize of 256x256 for TTDPatch games or it might get confused
-		GamelogReset();
-		if (!LoadOldSaveGame(filename)) return SL_REINIT;
-		_sl_version = 0;
-		_sl_minor_version = 0;
-		GamelogStartAction(GLAT_LOAD);
-		if (!AfterLoadGame()) {
-			GamelogStopAction();
-			return SL_REINIT;
-		}
-		GamelogStopAction();
-		return SL_OK;
-	}
-
-	_sl.excpt_uninit = NULL;
-	try {
-		_sl.fh = (mode == SL_SAVE) ? FioFOpenFile(filename, "wb", sb) : FioFOpenFile(filename, "rb", sb);
-
-		/* Make it a little easier to load savegames from the console */
-		if (_sl.fh == NULL && mode == SL_LOAD) _sl.fh = FioFOpenFile(filename, "rb", SAVE_DIR);
-		if (_sl.fh == NULL && mode == SL_LOAD) _sl.fh = FioFOpenFile(filename, "rb", BASE_DIR);
-
-		if (_sl.fh == NULL) {
-			SlError(mode == SL_SAVE ? STR_GAME_SAVELOAD_ERROR_FILE_NOT_WRITEABLE : STR_GAME_SAVELOAD_ERROR_FILE_NOT_READABLE);
-		}
-
-		_sl.bufe = _sl.bufp = NULL;
-		_sl.offs_base = 0;
-		_sl.save = (mode != 0);
-		_sl.chs = _chunk_handlers;
-
-		/* General tactic is to first save the game to memory, then use an available writer
-		 * to write it to file, either in threaded mode if possible, or single-threaded */
-		if (mode == SL_SAVE) { /* SAVE game */
-			DEBUG(desync, 1, "save: %s\n", filename);
-			fmt = GetSavegameFormat("memory"); // write to memory
-
-			_sl.write_bytes = fmt->writer;
-			_sl.excpt_uninit = fmt->uninit_write;
-			if (!fmt->init_write()) {
-				DEBUG(sl, 0, "Initializing writer '%s' failed.", fmt->name);
-				return AbortSaveLoad();
-			}
-
-			_sl_version = SAVEGAME_VERSION;
-
-			SaveViewportBeforeSaveGame();
-			SlSaveChunks();
-			SlWriteFill(); // flush the save buffer
-
-			SaveFileStart();
-			if (_network_server ||
-						(_save_thread = ThreadObject::New(&SaveFileToDiskThread, NULL)) == NULL) {
-				if (!_network_server) DEBUG(sl, 1, "Cannot create savegame thread, reverting to single-threaded mode...");
-
-				SaveOrLoadResult result = SaveFileToDisk(false);
-				SaveFileDone();
-
-				return result;
-			}
-		} else { /* LOAD game */
-			assert(mode == SL_LOAD);
-			DEBUG(desync, 1, "load: %s\n", filename);
-
-			if (fread(hdr, sizeof(hdr), 1, _sl.fh) != 1) SlError(STR_GAME_SAVELOAD_ERROR_FILE_NOT_READABLE);
-
-			/* see if we have any loader for this type. */
-			for (fmt = _saveload_formats; ; fmt++) {
-				/* No loader found, treat as version 0 and use LZO format */
-				if (fmt == endof(_saveload_formats)) {
-					DEBUG(sl, 0, "Unknown savegame type, trying to load it as the buggy format");
-	#if defined(WINCE)
-					/* Of course some system had not to support rewind ;) */
-					fseek(_sl.fh, 0L, SEEK_SET);
-					clearerr(_sl.fh);
-	#else
-					rewind(_sl.fh);
-	#endif
-					_sl_version = 0;
-					_sl_minor_version = 0;
-					fmt = _saveload_formats + 1; // LZO
-					break;
-				}
-
-				if (fmt->tag == hdr[0]) {
-					/* check version number */
-					_sl_version = TO_BE32(hdr[1]) >> 16;
-					/* Minor is not used anymore from version 18.0, but it is still needed
-					 * in versions before that (4 cases) which can't be removed easy.
-					 * Therefor it is loaded, but never saved (or, it saves a 0 in any scenario).
-					 * So never EVER use this minor version again. -- TrueLight -- 22-11-2005 */
-					_sl_minor_version = (TO_BE32(hdr[1]) >> 8) & 0xFF;
-
-					DEBUG(sl, 1, "Loading savegame version %d", _sl_version);
-
-					/* Is the version higher than the current? */
-					if (_sl_version > SAVEGAME_VERSION) SlError(STR_GAME_SAVELOAD_ERROR_TOO_NEW_SAVEGAME);
-					break;
-				}
-			}
-
-			_sl.read_bytes = fmt->reader;
-			_sl.excpt_uninit = fmt->uninit_read;
-
-			/* loader for this savegame type is not implemented? */
-			if (fmt->init_read == NULL) {
-				char err_str[64];
-				snprintf(err_str, lengthof(err_str), "Loader for '%s' is not available.", fmt->name);
-				SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR, err_str);
-			}
-
-			if (!fmt->init_read()) {
-				char err_str[64];
-				snprintf(err_str, lengthof(err_str), "Initializing loader '%s' failed", fmt->name);
-				SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR, err_str);
-			}
-
-			/* 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(256, 256, true);
-
-			GamelogReset();
-
-			SlLoadChunks();
-			fmt->uninit_read();
-			fclose(_sl.fh);
-
-			GamelogStartAction(GLAT_LOAD);
-
-			_savegame_type = SGT_OTTD;
-
-			/* After loading fix up savegame for any internal changes that
-			 * might've occured since then. If it fails, load back the old game */
-			if (!AfterLoadGame()) {
-				GamelogStopAction();
-				return SL_REINIT;
-			}
-
-			GamelogStopAction();
-		}
-
-		return SL_OK;
-	}
-	catch (...) {
-		AbortSaveLoad();
-
-		/* deinitialize compressor. */
-		if (_sl.excpt_uninit != NULL) _sl.excpt_uninit();
-
-		/* Skip the "color" character */
-		DEBUG(sl, 0, GetSaveLoadErrorString() + 3);
-
-		/* A saver/loader exception!! reinitialize all variables to prevent crash! */
-		return (mode == SL_LOAD) ? SL_REINIT : SL_ERROR;
-	}
-}
-
-/** Do a save when exiting the game (patch option) _settings_client.gui.autosave_on_exit */
-void DoExitSave()
-{
-	SaveOrLoad("exit.sav", SL_SAVE, AUTOSAVE_DIR);
-}
-
-/**
- * Fill the buffer with the default name for a savegame *or* screenshot.
- * @param buf the buffer to write to.
- * @param last the last element in the buffer.
- */
-void GenerateDefaultSaveName(char *buf, const char *last)
-{
-	/* Check if we have a name for this map, which is the name of the first
-	 * available company. When there's no company available we'll use
-	 * 'Spectator' as "company" name. */
-	CompanyID cid = _local_company;
-	if (!IsValidCompanyID(cid)) {
-		const Company *c;
-		FOR_ALL_COMPANIES(c) {
-			cid = c->index;
-			break;
-		}
-	}
-
-	SetDParam(0, cid);
-
-	/* Insert current date */
-	switch (_settings_client.gui.date_format_in_default_names) {
-		case 0: SetDParam(1, STR_JUST_DATE_LONG); break;
-		case 1: SetDParam(1, STR_JUST_DATE_TINY); break;
-		case 2: SetDParam(1, STR_JUST_DATE_ISO); break;
-		default: NOT_REACHED();
-	}
-	SetDParam(2, _date);
-
-	/* Get the correct string (special string for when there's not company) */
-	GetString(buf, !IsValidCompanyID(cid) ? STR_GAME_SAVELOAD_SPECTATOR_SAVEGAME : STR_4004, last);
-	SanitizeFilename(buf);
-}
-
-#if 0
-/**
- * Function to get the type of the savegame by looking at the file header.
- * NOTICE: Not used right now, but could be used if extensions of savegames are garbled
- * @param file Savegame to be checked
- * @return SL_OLD_LOAD or SL_LOAD of the file
- */
-int GetSavegameType(char *file)
-{
-	const SaveLoadFormat *fmt;
-	uint32 hdr;
-	FILE *f;
-	int mode = SL_OLD_LOAD;
-
-	f = fopen(file, "rb");
-	if (fread(&hdr, sizeof(hdr), 1, f) != 1) {
-		DEBUG(sl, 0, "Savegame is obsolete or invalid format");
-		mode = SL_LOAD; // don't try to get filename, just show name as it is written
-	} else {
-		/* see if we have any loader for this type. */
-		for (fmt = _saveload_formats; fmt != endof(_saveload_formats); fmt++) {
-			if (fmt->tag == hdr) {
-				mode = SL_LOAD; // new type of savegame
-				break;
-			}
-		}
-	}
-
-	fclose(f);
-	return mode;
-}
-#endif
deleted file mode 100644
--- a/src/saveload.h
+++ /dev/null
@@ -1,332 +0,0 @@
-/* $Id$ */
-
-/** @file saveload.h Functions/types related to saving and loading games. */
-
-#ifndef SAVELOAD_H
-#define SAVELOAD_H
-
-#include "fileio_type.h"
-
-#ifdef SIZE_MAX
-#undef SIZE_MAX
-#endif
-
-#define SIZE_MAX ((size_t)-1)
-
-enum SaveOrLoadResult {
-	SL_OK     = 0, ///< completed successfully
-	SL_ERROR  = 1, ///< error that was caught before internal structures were modified
-	SL_REINIT = 2, ///< error that was caught in the middle of updating game state, need to clear it. (can only happen during load)
-};
-
-enum SaveOrLoadMode {
-	SL_INVALID  = -1,
-	SL_LOAD     =  0,
-	SL_SAVE     =  1,
-	SL_OLD_LOAD =  2,
-	SL_PNG      =  3,
-	SL_BMP      =  4,
-};
-
-enum SavegameType {
-	SGT_TTD,    ///< TTD  savegame (can be detected incorrectly)
-	SGT_TTDP1,  ///< TTDP savegame ( -//- ) (data at NW border)
-	SGT_TTDP2,  ///< TTDP savegame in new format (data at SE border)
-	SGT_OTTD    ///< OTTD savegame
-};
-
-void GenerateDefaultSaveName(char *buf, const char *last);
-void SetSaveLoadError(uint16 str);
-const char *GetSaveLoadErrorString();
-SaveOrLoadResult SaveOrLoad(const char *filename, int mode, Subdirectory sb);
-void WaitTillSaved();
-void DoExitSave();
-
-
-typedef void ChunkSaveLoadProc();
-typedef void AutolengthProc(void *arg);
-
-struct ChunkHandler {
-	uint32 id;
-	ChunkSaveLoadProc *save_proc;
-	ChunkSaveLoadProc *load_proc;
-	uint32 flags;
-};
-
-struct NullStruct {
-	byte null;
-};
-
-enum SLRefType {
-	REF_ORDER         = 0,
-	REF_VEHICLE       = 1,
-	REF_STATION       = 2,
-	REF_TOWN          = 3,
-	REF_VEHICLE_OLD   = 4,
-	REF_ROADSTOPS     = 5,
-	REF_ENGINE_RENEWS = 6,
-	REF_CARGO_PACKET  = 7,
-	REF_ORDERLIST     = 8,
-};
-
-#define SL_MAX_VERSION 255
-
-enum {
-	INC_VEHICLE_COMMON = 0,
-};
-
-enum {
-	CH_RIFF         =  0,
-	CH_ARRAY        =  1,
-	CH_SPARSE_ARRAY =  2,
-	CH_TYPE_MASK    =  3,
-	CH_LAST         =  8,
-	CH_AUTO_LENGTH  = 16,
-
-	CH_PRI_0          = 0 << 4,
-	CH_PRI_1          = 1 << 4,
-	CH_PRI_2          = 2 << 4,
-	CH_PRI_3          = 3 << 4,
-	CH_PRI_SHL        = 4,
-	CH_NUM_PRI_LEVELS = 4,
-};
-
-/** VarTypes is the general bitmasked magic type that tells us
- * certain characteristics about the variable it refers to. For example
- * SLE_FILE_* gives the size(type) as it would be in the savegame and
- * SLE_VAR_* the size(type) as it is in memory during runtime. These are
- * the first 8 bits (0-3 SLE_FILE, 4-7 SLE_VAR).
- * Bits 8-15 are reserved for various flags as explained below */
-enum VarTypes {
-	/* 4 bits allocated a maximum of 16 types for NumberType */
-	SLE_FILE_I8       = 0,
-	SLE_FILE_U8       = 1,
-	SLE_FILE_I16      = 2,
-	SLE_FILE_U16      = 3,
-	SLE_FILE_I32      = 4,
-	SLE_FILE_U32      = 5,
-	SLE_FILE_I64      = 6,
-	SLE_FILE_U64      = 7,
-	SLE_FILE_STRINGID = 8, ///< StringID offset into strings-array
-	SLE_FILE_STRING   = 9,
-	/* 6 more possible file-primitives */
-
-	/* 4 bits allocated a maximum of 16 types for NumberType */
-	SLE_VAR_BL    =  0 << 4,
-	SLE_VAR_I8    =  1 << 4,
-	SLE_VAR_U8    =  2 << 4,
-	SLE_VAR_I16   =  3 << 4,
-	SLE_VAR_U16   =  4 << 4,
-	SLE_VAR_I32   =  5 << 4,
-	SLE_VAR_U32   =  6 << 4,
-	SLE_VAR_I64   =  7 << 4,
-	SLE_VAR_U64   =  8 << 4,
-	SLE_VAR_NULL  =  9 << 4, ///< useful to write zeros in savegame.
-	SLE_VAR_STRB  = 10 << 4, ///< string (with pre-allocated buffer)
-	SLE_VAR_STRBQ = 11 << 4, ///< string enclosed in quotes (with pre-allocated buffer)
-	SLE_VAR_STR   = 12 << 4, ///< string pointer
-	SLE_VAR_STRQ  = 13 << 4, ///< string pointer enclosed in quotes
-	SLE_VAR_NAME  = 14 << 4, ///< old custom name to be converted to a char pointer
-	/* 1 more possible memory-primitives */
-
-	/* Shortcut values */
-	SLE_VAR_CHAR = SLE_VAR_I8,
-
-	/* Default combinations of variables. As savegames change, so can variables
-	 * and thus it is possible that the saved value and internal size do not
-	 * match and you need to specify custom combo. The defaults are listed here */
-	SLE_BOOL         = SLE_FILE_I8  | SLE_VAR_BL,
-	SLE_INT8         = SLE_FILE_I8  | SLE_VAR_I8,
-	SLE_UINT8        = SLE_FILE_U8  | SLE_VAR_U8,
-	SLE_INT16        = SLE_FILE_I16 | SLE_VAR_I16,
-	SLE_UINT16       = SLE_FILE_U16 | SLE_VAR_U16,
-	SLE_INT32        = SLE_FILE_I32 | SLE_VAR_I32,
-	SLE_UINT32       = SLE_FILE_U32 | SLE_VAR_U32,
-	SLE_INT64        = SLE_FILE_I64 | SLE_VAR_I64,
-	SLE_UINT64       = SLE_FILE_U64 | SLE_VAR_U64,
-	SLE_CHAR         = SLE_FILE_I8  | SLE_VAR_CHAR,
-	SLE_STRINGID     = SLE_FILE_STRINGID | SLE_VAR_U16,
-	SLE_STRINGBUF    = SLE_FILE_STRING   | SLE_VAR_STRB,
-	SLE_STRINGBQUOTE = SLE_FILE_STRING   | SLE_VAR_STRBQ,
-	SLE_STRING       = SLE_FILE_STRING   | SLE_VAR_STR,
-	SLE_STRINGQUOTE  = SLE_FILE_STRING   | SLE_VAR_STRQ,
-	SLE_NAME         = SLE_FILE_STRINGID | SLE_VAR_NAME,
-
-	/* Shortcut values */
-	SLE_UINT  = SLE_UINT32,
-	SLE_INT   = SLE_INT32,
-	SLE_STRB  = SLE_STRINGBUF,
-	SLE_STRBQ = SLE_STRINGBQUOTE,
-	SLE_STR   = SLE_STRING,
-	SLE_STRQ  = SLE_STRINGQUOTE,
-
-	/* 8 bits allocated for a maximum of 8 flags
-	 * Flags directing saving/loading of a variable */
-	SLF_SAVE_NO      = 1 <<  8, ///< do not save with savegame, basically client-based
-	SLF_CONFIG_NO    = 1 <<  9, ///< do not save to config file
-	SLF_NETWORK_NO   = 1 << 10, ///< do not synchronize over network (but it is saved if SSF_SAVE_NO is not set)
-	/* 5 more possible flags */
-};
-
-typedef uint32 VarType;
-
-enum SaveLoadTypes {
-	SL_VAR         =  0,
-	SL_REF         =  1,
-	SL_ARR         =  2,
-	SL_STR         =  3,
-	SL_LST         =  4,
-	// non-normal save-load types
-	SL_WRITEBYTE   =  8,
-	SL_VEH_INCLUDE =  9,
-	SL_END         = 15
-};
-
-typedef byte SaveLoadType;
-
-/** SaveLoad type struct. Do NOT use this directly but use the SLE_ macros defined just below! */
-struct SaveLoad {
-	bool global;         ///< should we load a global variable or a non-global one
-	SaveLoadType cmd;    ///< the action to take with the saved/loaded type, All types need different action
-	VarType conv;        ///< type of the variable to be saved, int
-	uint16 length;       ///< (conditional) length of the variable (eg. arrays) (max array size is 65536 elements)
-	uint16 version_from; ///< save/load the variable starting from this savegame version
-	uint16 version_to;   ///< save/load the variable until this savegame version
-	/* NOTE: This element either denotes the address of the variable for a global
-	 * variable, or the offset within a struct which is then bound to a variable
-	 * during runtime. Decision on which one to use is controlled by the function
-	 * that is called to save it. address: global=true, offset: global=false */
-	void *address;       ///< address of variable OR offset of variable in the struct (max offset is 65536)
-};
-
-/* Same as SaveLoad but global variables are used (for better readability); */
-typedef SaveLoad SaveLoadGlobVarList;
-
-/* Simple variables, references (pointers) and arrays */
-#define SLE_GENERAL(cmd, base, variable, type, length, from, to) {false, cmd, type, length, from, to, (void*)cpp_offsetof(base, variable)}
-#define SLE_CONDVAR(base, variable, type, from, to) SLE_GENERAL(SL_VAR, base, variable, type, 0, from, to)
-#define SLE_CONDREF(base, variable, type, from, to) SLE_GENERAL(SL_REF, base, variable, type, 0, from, to)
-#define SLE_CONDARR(base, variable, type, length, from, to) SLE_GENERAL(SL_ARR, base, variable, type, length, from, to)
-#define SLE_CONDSTR(base, variable, type, length, from, to) SLE_GENERAL(SL_STR, base, variable, type, length, from, to)
-#define SLE_CONDLST(base, variable, type, from, to) SLE_GENERAL(SL_LST, base, variable, type, 0, from, to)
-
-#define SLE_VAR(base, variable, type) SLE_CONDVAR(base, variable, type, 0, SL_MAX_VERSION)
-#define SLE_REF(base, variable, type) SLE_CONDREF(base, variable, type, 0, SL_MAX_VERSION)
-#define SLE_ARR(base, variable, type, length) SLE_CONDARR(base, variable, type, length, 0, SL_MAX_VERSION)
-#define SLE_STR(base, variable, type, length) SLE_CONDSTR(base, variable, type, length, 0, SL_MAX_VERSION)
-#define SLE_LST(base, variable, type) SLE_CONDLST(base, variable, type, 0, SL_MAX_VERSION)
-
-#define SLE_CONDNULL(length, from, to) SLE_CONDARR(NullStruct, null, SLE_FILE_U8 | SLE_VAR_NULL | SLF_CONFIG_NO, length, from, to)
-
-/* Translate values ingame to different values in the savegame and vv */
-#define SLE_WRITEBYTE(base, variable, value) SLE_GENERAL(SL_WRITEBYTE, base, variable, 0, 0, value, value)
-
-/* The same as the ones at the top, only the offset is given directly; used for unions */
-#define SLE_GENERALX(cmd, offset, type, length, param1, param2) {false, cmd, type, length, param1, param2, (void*)(offset)}
-#define SLE_CONDVARX(offset, type, from, to) SLE_GENERALX(SL_VAR, offset, type, 0, from, to)
-#define SLE_CONDARRX(offset, type, length, from, to) SLE_GENERALX(SL_ARR, offset, type, length, from, to)
-#define SLE_CONDREFX(offset, type, from, to) SLE_GENERALX(SL_REF, offset, type, 0, from, to)
-
-#define SLE_VARX(offset, type) SLE_CONDVARX(offset, type, 0, SL_MAX_VERSION)
-#define SLE_REFX(offset, type) SLE_CONDREFX(offset, type, 0, SL_MAX_VERSION)
-
-#define SLE_WRITEBYTEX(offset, something) SLE_GENERALX(SL_WRITEBYTE, offset, 0, 0, something, 0)
-#define SLE_VEH_INCLUDEX() SLE_GENERALX(SL_VEH_INCLUDE, 0, 0, 0, 0, SL_MAX_VERSION)
-
-/* End marker */
-#define SLE_END() {false, SL_END, 0, 0, 0, 0, NULL}
-
-/* Simple variables, references (pointers) and arrays, but for global variables */
-#define SLEG_GENERAL(cmd, variable, type, length, from, to) {true, cmd, type, length, from, to, (void*)&variable}
-
-#define SLEG_CONDVAR(variable, type, from, to) SLEG_GENERAL(SL_VAR, variable, type, 0, from, to)
-#define SLEG_CONDREF(variable, type, from, to) SLEG_GENERAL(SL_REF, variable, type, 0, from, to)
-#define SLEG_CONDARR(variable, type, length, from, to) SLEG_GENERAL(SL_ARR, variable, type, length, from, to)
-#define SLEG_CONDSTR(variable, type, length, from, to) SLEG_GENERAL(SL_STR, variable, type, length, from, to)
-#define SLEG_CONDLST(variable, type, from, to) SLEG_GENERAL(SL_LST, variable, type, 0, from, to)
-
-#define SLEG_VAR(variable, type) SLEG_CONDVAR(variable, type, 0, SL_MAX_VERSION)
-#define SLEG_REF(variable, type) SLEG_CONDREF(variable, type, 0, SL_MAX_VERSION)
-#define SLEG_ARR(variable, type) SLEG_CONDARR(variable, type, lengthof(variable), 0, SL_MAX_VERSION)
-#define SLEG_STR(variable, type) SLEG_CONDSTR(variable, type, lengthof(variable), 0, SL_MAX_VERSION)
-#define SLEG_LST(variable, type) SLEG_CONDLST(variable, type, 0, SL_MAX_VERSION)
-
-#define SLEG_CONDNULL(length, from, to) {true, SL_ARR, SLE_FILE_U8 | SLE_VAR_NULL | SLF_CONFIG_NO, length, from, to, (void*)NULL}
-
-#define SLEG_END() {true, SL_END, 0, 0, 0, 0, NULL}
-
-/** Checks if the savegame is below major.minor.
- */
-static inline bool CheckSavegameVersionOldStyle(uint16 major, byte minor)
-{
-	extern uint16 _sl_version;
-	extern byte   _sl_minor_version;
-	return (_sl_version < major) || (_sl_version == major && _sl_minor_version < minor);
-}
-
-/** Checks if the savegame is below version.
- */
-static inline bool CheckSavegameVersion(uint16 version)
-{
-	extern uint16 _sl_version;
-	return _sl_version < version;
-}
-
-/** Checks if some version from/to combination falls within the range of the
- * active savegame version */
-static inline bool SlIsObjectCurrentlyValid(uint16 version_from, uint16 version_to)
-{
-	extern const uint16 SAVEGAME_VERSION;
-	if (SAVEGAME_VERSION < version_from || SAVEGAME_VERSION > version_to) return false;
-
-	return true;
-}
-
-/* Get the NumberType of a setting. This describes the integer type
- * as it is represented in memory
- * @param type VarType holding information about the variable-type
- * @return return the SLE_VAR_* part of a variable-type description */
-static inline VarType GetVarMemType(VarType type)
-{
-	return type & 0xF0; // GB(type, 4, 4) << 4;
-}
-
-/* Get the FileType of a setting. This describes the integer type
- * as it is represented in a savegame/file
- * @param type VarType holding information about the variable-type
- * @param return the SLE_FILE_* part of a variable-type description */
-static inline VarType GetVarFileType(VarType type)
-{
-	return type & 0xF; // GB(type, 0, 4);
-}
-
-/** Get the address of the variable. Which one to pick depends on the object
- * pointer. If it is NULL we are dealing with global variables so the address
- * is taken. If non-null only the offset is stored in the union and we need
- * to add this to the address of the object */
-static inline void *GetVariableAddress(const void *object, const SaveLoad *sld)
-{
-	return (byte*)(sld->global ? NULL : object) + (ptrdiff_t)sld->address;
-}
-
-int64 ReadValue(const void *ptr, VarType conv);
-void WriteValue(void *ptr, VarType conv, int64 val);
-
-void SlSetArrayIndex(uint index);
-int SlIterateArray();
-
-void SlAutolength(AutolengthProc *proc, void *arg);
-size_t SlGetFieldLength();
-void SlSetLength(size_t length);
-size_t SlCalcObjMemberLength(const void *object, const SaveLoad *sld);
-size_t SlCalcObjLength(const void *object, const SaveLoad *sld);
-
-byte SlReadByte();
-void SlWriteByte(byte b);
-
-void SlGlobList(const SaveLoadGlobVarList *sldg);
-void SlArray(void *array, size_t length, VarType conv);
-void SlObject(void *object, const SaveLoad *sld);
-bool SlObjectMember(void *object, const SaveLoad *sld);
-
-#endif /* SAVELOAD_H */
new file mode 100644
--- /dev/null
+++ b/src/saveload/afterload.cpp
@@ -0,0 +1,1704 @@
+/* $Id$ */
+
+/** @file afterload.cpp Code updating data after game load */
+
+#include "../stdafx.h"
+#include "../strings_type.h"
+#include "../tile_type.h"
+#include "../tile_map.h"
+#include "../map_type.h"
+#include "../road_map.h"
+#include "../town.h"
+#include "../void_map.h"
+#include "../signs_base.h"
+#include "../window_func.h"
+#include "../station_func.h"
+#include "../company_base.h"
+#include "../fios.h"
+#include "../date_func.h"
+#include "../engine_func.h"
+#include "../train.h"
+#include "../string_func.h"
+#include "../newgrf_config.h"
+#include "../gamelog.h"
+#include "../waypoint.h"
+#include "../station_map.h"
+#include "../station_base.h"
+#include "../tunnelbridge_map.h"
+#include "../debug.h"
+#include "../network/network.h"
+#include "../openttd.h"
+#include "../gfxinit.h"
+#include "../gfx_func.h"
+#include "../functions.h"
+#include "../industry_map.h"
+#include "../town_map.h"
+#include "../clear_map.h"
+#include "../engine_base.h"
+#include "../landscape.h"
+#include "../vehicle_func.h"
+#include "../newgrf_station.h"
+#include "../yapf/yapf.hpp"
+#include "../elrail_func.h"
+#include "../signs_func.h"
+#include "../newgrf_house.h"
+#include "../aircraft.h"
+#include "../unmovable_map.h"
+#include "../tree_map.h"
+#include "../company_func.h"
+#include "../command_func.h"
+#include "../road_cmd.h"
+
+#include "table/strings.h"
+
+#include "saveload.h"
+#include "saveload_internal.h"
+
+#include <signal.h>
+
+extern StringID _switch_mode_errorstr;
+extern Company *DoStartupNewCompany(bool is_ai);
+extern void InitializeRailGUI();
+
+/**
+ * Makes a tile canal or water depending on the surroundings.
+ *
+ * Must only be used for converting old savegames. Use WaterClass now.
+ *
+ * This as for example docks and shipdepots do not store
+ * whether the tile used to be canal or 'normal' water.
+ * @param t the tile to change.
+ * @param o the owner of the new tile.
+ * @param include_invalid_water_class Also consider WATER_CLASS_INVALID, i.e. industry tiles on land
+ */
+void SetWaterClassDependingOnSurroundings(TileIndex t, bool include_invalid_water_class)
+{
+	/* If the slope is not flat, we always assume 'land' (if allowed). Also for one-corner-raised-shores.
+	 * Note: Wrt. autosloping under industry tiles this is the most fool-proof behaviour. */
+	if (GetTileSlope(t, NULL) != SLOPE_FLAT) {
+		if (include_invalid_water_class) {
+			SetWaterClass(t, WATER_CLASS_INVALID);
+			return;
+		} else {
+			NOT_REACHED();
+		}
+	}
+
+	/* Mark tile dirty in all cases */
+	MarkTileDirtyByTile(t);
+
+	if (TileX(t) == 0 || TileY(t) == 0 || TileX(t) == MapMaxX() - 1 || TileY(t) == MapMaxY() - 1) {
+		/* tiles at map borders are always WATER_CLASS_SEA */
+		SetWaterClass(t, WATER_CLASS_SEA);
+		return;
+	}
+
+	bool has_water = false;
+	bool has_canal = false;
+	bool has_river = false;
+
+	for (DiagDirection dir = DIAGDIR_BEGIN; dir < DIAGDIR_END; dir++) {
+		TileIndex neighbour = TileAddByDiagDir(t, dir);
+		switch (GetTileType(neighbour)) {
+			case MP_WATER:
+				/* clear water and shipdepots have already a WaterClass associated */
+				if (IsCoast(neighbour)) {
+					has_water = true;
+				} else if (!IsLock(neighbour)) {
+					switch (GetWaterClass(neighbour)) {
+						case WATER_CLASS_SEA:   has_water = true; break;
+						case WATER_CLASS_CANAL: has_canal = true; break;
+						case WATER_CLASS_RIVER: has_river = true; break;
+						default: NOT_REACHED();
+					}
+				}
+				break;
+
+			case MP_RAILWAY:
+				/* Shore or flooded halftile */
+				has_water |= (GetRailGroundType(neighbour) == RAIL_GROUND_WATER);
+				break;
+
+			case MP_TREES:
+				/* trees on shore */
+				has_water |= (GetTreeGround(neighbour) == TREE_GROUND_SHORE);
+				break;
+
+			default: break;
+		}
+	}
+
+	if (!has_water && !has_canal && !has_river && include_invalid_water_class) {
+		SetWaterClass(t, WATER_CLASS_INVALID);
+		return;
+	}
+
+	if (has_river && !has_canal) {
+		SetWaterClass(t, WATER_CLASS_RIVER);
+	} else if (has_canal || !has_water) {
+		SetWaterClass(t, WATER_CLASS_CANAL);
+	} else {
+		SetWaterClass(t, WATER_CLASS_SEA);
+	}
+}
+
+static void ConvertTownOwner()
+{
+	for (TileIndex tile = 0; tile != MapSize(); tile++) {
+		switch (GetTileType(tile)) {
+			case MP_ROAD:
+				if (GB(_m[tile].m5, 4, 2) == ROAD_TILE_CROSSING && HasBit(_m[tile].m3, 7)) {
+					_m[tile].m3 = OWNER_TOWN;
+				}
+				/* FALLTHROUGH */
+
+			case MP_TUNNELBRIDGE:
+				if (GetTileOwner(tile) & 0x80) SetTileOwner(tile, OWNER_TOWN);
+				break;
+
+			default: break;
+		}
+	}
+}
+
+/* since savegame version 4.1, exclusive transport rights are stored at towns */
+static void UpdateExclusiveRights()
+{
+	Town *t;
+
+	FOR_ALL_TOWNS(t) {
+		t->exclusivity = INVALID_COMPANY;
+	}
+
+	/* FIXME old exclusive rights status is not being imported (stored in s->blocked_months_obsolete)
+	 *   could be implemented this way:
+	 * 1.) Go through all stations
+	 *     Build an array town_blocked[ town_id ][ company_id ]
+	 *     that stores if at least one station in that town is blocked for a company
+	 * 2.) Go through that array, if you find a town that is not blocked for
+	 *     one company, but for all others, then give him exclusivity.
+	 */
+}
+
+static const byte convert_currency[] = {
+	 0,  1, 12,  8,  3,
+	10, 14, 19,  4,  5,
+	 9, 11, 13,  6, 17,
+	16, 22, 21,  7, 15,
+	18,  2, 20,
+};
+
+/* since savegame version 4.2 the currencies are arranged differently */
+static void UpdateCurrencies()
+{
+	_settings_game.locale.currency = convert_currency[_settings_game.locale.currency];
+}
+
+/* Up to revision 1413 the invisible tiles at the southern border have not been
+ * MP_VOID, even though they should have. This is fixed by this function
+ */
+static void UpdateVoidTiles()
+{
+	uint i;
+
+	for (i = 0; i < MapMaxY(); ++i) MakeVoid(i * MapSizeX() + MapMaxX());
+	for (i = 0; i < MapSizeX(); ++i) MakeVoid(MapSizeX() * MapMaxY() + i);
+}
+
+/* since savegame version 6.0 each sign has an "owner", signs without owner (from old games are set to 255) */
+static void UpdateSignOwner()
+{
+	Sign *si;
+
+	FOR_ALL_SIGNS(si) si->owner = OWNER_NONE;
+}
+
+static inline RailType UpdateRailType(RailType rt, RailType min)
+{
+	return rt >= min ? (RailType)(rt + 1): rt;
+}
+
+/**
+ * Initialization of the windows and several kinds of caches.
+ * This is not done directly in AfterLoadGame because these
+ * functions require that all saveload conversions have been
+ * done. As people tend to add savegame conversion stuff after
+ * the intialization of the windows and caches quite some bugs
+ * had been made.
+ * Moving this out of there is both cleaner and less bug-prone.
+ *
+ * @return true if everything went according to plan, otherwise false.
+ */
+static bool InitializeWindowsAndCaches()
+{
+	/* Initialize windows */
+	ResetWindowSystem();
+	SetupColorsAndInitialWindow();
+
+	ResetViewportAfterLoadGame();
+
+	/* Update coordinates of the signs. */
+	UpdateAllStationVirtCoord();
+	UpdateAllSignVirtCoords();
+	UpdateAllTownVirtCoords();
+	UpdateAllWaypointSigns();
+
+	Company *c;
+	FOR_ALL_COMPANIES(c) {
+		/* For each company, verify (while loading a scenario) that the inauguration date is the current year and set it
+		 * accordingly if it is not the case.  No need to set it on companies that are not been used already,
+		 * thus the MIN_YEAR (which is really nothing more than Zero, initialized value) test */
+		if (_file_to_saveload.filetype == FT_SCENARIO && c->inaugurated_year != MIN_YEAR) {
+			c->inaugurated_year = _cur_year;
+		}
+	}
+
+	SetCachedEngineCounts();
+
+	/* Towns have a noise controlled number of airports system
+	 * So each airport's noise value must be added to the town->noise_reached value
+	 * Reset each town's noise_reached value to '0' before. */
+	UpdateAirportsNoise();
+
+	CheckTrainsLengths();
+
+	return true;
+}
+
+/**
+ * Signal handler used to give a user a more useful report for crashes during
+ * the savegame loading process; especially when there's problems with the
+ * NewGRFs that are required by the savegame.
+ * @param unused well... unused
+ */
+void CDECL HandleSavegameLoadCrash(int unused)
+{
+	char buffer[8192];
+	char *p = buffer;
+	p += seprintf(p, lastof(buffer),
+			"Loading your savegame caused OpenTTD to crash.\n"
+			"This is most likely caused by a missing NewGRF or a NewGRF that has been\n"
+			"loaded as replacement for a missing NewGRF. OpenTTD cannot easily\n"
+			"determine whether a replacement NewGRF is of a newer or older version.\n"
+			"It will load a NewGRF with the same GRF ID as the missing NewGRF. This\n"
+			"means that if the author makes incompatible NewGRFs with the same GRF ID\n"
+			"OpenTTD cannot magically do the right thing. In most cases OpenTTD will\n"
+			"load the savegame and not crash, but this is an exception.\n"
+			"Please load the savegame with the appropriate NewGRFs. When loading a\n"
+			"savegame still crashes when all NewGRFs are found you should file a\n"
+			"bug report. The missing NewGRFs are:\n");
+
+	for (GRFConfig *c = _grfconfig; c != NULL; c = c->next) {
+		if (HasBit(c->flags, GCF_COMPATIBLE)) {
+			char buf[40];
+			md5sumToString(buf, lastof(buf), c->md5sum);
+			p += seprintf(p, lastof(buffer), "NewGRF %08X (%s) not found; checksum %s. Tried another NewGRF with same GRF ID\n", BSWAP32(c->grfid), c->filename, buf);
+		}
+		if (c->status == GCS_NOT_FOUND) {
+			char buf[40];
+			md5sumToString(buf, lastof(buf), c->md5sum);
+			p += seprintf(p, lastof(buffer), "NewGRF %08X (%s) not found; checksum %s\n", BSWAP32(c->grfid), c->filename, buf);
+		}
+	}
+
+	ShowInfo(buffer);
+}
+
+
+bool AfterLoadGame()
+{
+	typedef void (CDECL *SignalHandlerPointer)(int);
+	SignalHandlerPointer prev_segfault = signal(SIGSEGV, HandleSavegameLoadCrash);
+	SignalHandlerPointer prev_abort = signal(SIGABRT, HandleSavegameLoadCrash);
+
+	TileIndex map_size = MapSize();
+	Company *c;
+
+	if (CheckSavegameVersion(98)) GamelogOldver();
+
+	GamelogTestRevision();
+	GamelogTestMode();
+
+	if (CheckSavegameVersion(98)) GamelogGRFAddList(_grfconfig);
+
+	/* in very old versions, size of train stations was stored differently */
+	if (CheckSavegameVersion(2)) {
+		Station *st;
+		FOR_ALL_STATIONS(st) {
+			if (st->train_tile != 0 && st->trainst_h == 0) {
+				extern SavegameType _savegame_type;
+				uint n = _savegame_type == SGT_OTTD ? 4 : 3; // OTTD uses 4 bits per dimensions, TTD 3 bits
+				uint w = GB(st->trainst_w, n, n);
+				uint h = GB(st->trainst_w, 0, n);
+
+				if (GetRailStationAxis(st->train_tile) != AXIS_X) Swap(w, h);
+
+				st->trainst_w = w;
+				st->trainst_h = h;
+
+				assert(GetStationIndex(st->train_tile + TileDiffXY(w - 1, h - 1)) == st->index);
+			}
+		}
+	}
+
+	/* in version 2.1 of the savegame, town owner was unified. */
+	if (CheckSavegameVersionOldStyle(2, 1)) ConvertTownOwner();
+
+	/* from version 4.1 of the savegame, exclusive rights are stored at towns */
+	if (CheckSavegameVersionOldStyle(4, 1)) UpdateExclusiveRights();
+
+	/* from version 4.2 of the savegame, currencies are in a different order */
+	if (CheckSavegameVersionOldStyle(4, 2)) UpdateCurrencies();
+
+	/* from version 6.1 of the savegame, signs have an "owner" */
+	if (CheckSavegameVersionOldStyle(6, 1)) UpdateSignOwner();
+
+	/* In old version there seems to be a problem that water is owned by
+	 * OWNER_NONE, not OWNER_WATER.. I can't replicate it for the current
+	 * (4.3) version, so I just check when versions are older, and then
+	 * walk through the whole map.. */
+	if (CheckSavegameVersionOldStyle(4, 3)) {
+		for (TileIndex t = 0; t < map_size; t++) {
+			if (IsTileType(t, MP_WATER) && GetTileOwner(t) >= MAX_COMPANIES) {
+				SetTileOwner(t, OWNER_WATER);
+			}
+		}
+	}
+
+	if (CheckSavegameVersion(84)) {
+		FOR_ALL_COMPANIES(c) {
+			c->name = CopyFromOldName(c->name_1);
+			if (c->name != NULL) c->name_1 = STR_SV_UNNAMED;
+			c->president_name = CopyFromOldName(c->president_name_1);
+			if (c->president_name != NULL) c->president_name_1 = SPECSTR_PRESIDENT_NAME;
+		}
+
+		Station *st;
+		FOR_ALL_STATIONS(st) {
+			st->name = CopyFromOldName(st->string_id);
+			/* generating new name would be too much work for little effect, use the station name fallback */
+			if (st->name != NULL) st->string_id = STR_SV_STNAME_FALLBACK;
+		}
+
+		Town *t;
+		FOR_ALL_TOWNS(t) {
+			t->name = CopyFromOldName(t->townnametype);
+			if (t->name != NULL) t->townnametype = SPECSTR_TOWNNAME_START + _settings_game.game_creation.town_name;
+		}
+
+		Waypoint *wp;
+		FOR_ALL_WAYPOINTS(wp) {
+			wp->name = CopyFromOldName(wp->string);
+			wp->string = STR_EMPTY;
+		}
+
+		for (uint i = 0; i < GetSignPoolSize(); i++) {
+			/* invalid signs are determined by si->ower == INVALID_COMPANY now */
+			Sign *si = GetSign(i);
+			if (!si->IsValid() && si->name != NULL) {
+				si->owner = OWNER_NONE;
+			}
+		}
+	}
+
+	/* From this point the old names array is cleared. */
+	ResetOldNames();
+
+	if (CheckSavegameVersion(106)) {
+		/* no station is determined by 'tile == INVALID_TILE' now (instead of '0') */
+		Station *st;
+		FOR_ALL_STATIONS(st) {
+			if (st->airport_tile == 0) st->airport_tile = INVALID_TILE;
+			if (st->dock_tile    == 0) st->dock_tile    = INVALID_TILE;
+			if (st->train_tile   == 0) st->train_tile   = INVALID_TILE;
+		}
+
+		/* the same applies to Company::location_of_HQ */
+		Company *c;
+		FOR_ALL_COMPANIES(c) {
+			if (c->location_of_HQ == 0 || (CheckSavegameVersion(4) && c->location_of_HQ == 0xFFFF)) {
+				c->location_of_HQ = INVALID_TILE;
+			}
+		}
+	}
+
+	/* convert road side to my format. */
+	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();
+	if (_networking && gcf_res != GLC_ALL_GOOD) {
+		SetSaveLoadError(STR_NETWORK_ERR_CLIENT_NEWGRF_MISMATCH);
+		/* Restore the signals */
+		signal(SIGSEGV, prev_segfault);
+		signal(SIGABRT, prev_abort);
+		return false;
+	}
+
+	switch (gcf_res) {
+		case GLC_COMPATIBLE: _switch_mode_errorstr = STR_NEWGRF_COMPATIBLE_LOAD_WARNING; break;
+		case GLC_NOT_FOUND: _switch_mode_errorstr = STR_NEWGRF_DISABLED_WARNING; _pause_game = -1; break;
+		default: break;
+	}
+
+	/* Update current year
+	 * must be done before loading sprites as some newgrfs check it */
+	SetDate(_date);
+
+	/* Force dynamic engines off when loading older savegames */
+	if (CheckSavegameVersion(95)) _settings_game.vehicle.dynamic_engines = 0;
+
+	/* Load the sprites */
+	GfxLoadSprites();
+	LoadStringWidthTable();
+
+	/* Copy temporary data to Engine pool */
+	CopyTempEngineData();
+
+	/* Connect front and rear engines of multiheaded trains and converts
+	 * subtype to the new format */
+	if (CheckSavegameVersionOldStyle(17, 1)) ConvertOldMultiheadToNew();
+
+	/* Connect front and rear engines of multiheaded trains */
+	ConnectMultiheadedTrains();
+
+	/* reinit the landscape variables (landscape might have changed) */
+	InitializeLandscapeVariables(true);
+
+	/* Update all vehicles */
+	AfterLoadVehicles(true);
+
+	/* Update all waypoints */
+	if (CheckSavegameVersion(12)) FixOldWaypoints();
+
+	/* in version 2.2 of the savegame, we have new airports */
+	if (CheckSavegameVersionOldStyle(2, 2)) UpdateOldAircraft();
+
+	AfterLoadTown();
+
+	/* make sure there is a town in the game */
+	if (_game_mode == GM_NORMAL && !ClosestTownFromTile(0, UINT_MAX)) {
+		SetSaveLoadError(STR_NO_TOWN_IN_SCENARIO);
+		/* Restore the signals */
+		signal(SIGSEGV, prev_segfault);
+		signal(SIGABRT, prev_abort);
+		return false;
+	}
+
+	/* The void tiles on the southern border used to belong to a wrong class (pre 4.3).
+	 * This problem appears in savegame version 21 too, see r3455. But after loading the
+	 * savegame and saving again, the buggy map array could be converted to new savegame
+	 * version. It didn't show up before r12070. */
+	if (CheckSavegameVersion(87)) UpdateVoidTiles();
+
+	/* If Load Scenario / New (Scenario) Game is used,
+	 *  a company does not exist yet. So create one here.
+	 * 1 exeption: network-games. Those can have 0 companies
+	 *   But this exeption is not true for non dedicated network_servers! */
+	if (!IsValidCompanyID(COMPANY_FIRST) && (!_networking || (_networking && _network_server && !_network_dedicated)))
+		DoStartupNewCompany(false);
+
+	if (CheckSavegameVersion(72)) {
+		/* Locks/shiplifts in very old savegames had OWNER_WATER as owner */
+		for (TileIndex t = 0; t < MapSize(); t++) {
+			switch (GetTileType(t)) {
+				default: break;
+
+				case MP_WATER:
+					if (GetWaterTileType(t) == WATER_TILE_LOCK && GetTileOwner(t) == OWNER_WATER) SetTileOwner(t, OWNER_NONE);
+					break;
+
+				case MP_STATION: {
+					if (HasBit(_m[t].m6, 3)) SetBit(_m[t].m6, 2);
+					StationGfx gfx = GetStationGfx(t);
+					StationType st;
+					if (       IsInsideMM(gfx,   0,   8)) { // Railway station
+						st = STATION_RAIL;
+						SetStationGfx(t, gfx - 0);
+					} else if (IsInsideMM(gfx,   8,  67)) { // Airport
+						st = STATION_AIRPORT;
+						SetStationGfx(t, gfx - 8);
+					} else if (IsInsideMM(gfx,  67,  71)) { // Truck
+						st = STATION_TRUCK;
+						SetStationGfx(t, gfx - 67);
+					} else if (IsInsideMM(gfx,  71,  75)) { // Bus
+						st = STATION_BUS;
+						SetStationGfx(t, gfx - 71);
+					} else if (gfx == 75) {                    // Oil rig
+						st = STATION_OILRIG;
+						SetStationGfx(t, gfx - 75);
+					} else if (IsInsideMM(gfx,  76,  82)) { // Dock
+						st = STATION_DOCK;
+						SetStationGfx(t, gfx - 76);
+					} else if (gfx == 82) {                    // Buoy
+						st = STATION_BUOY;
+						SetStationGfx(t, gfx - 82);
+					} else if (IsInsideMM(gfx,  83, 168)) { // Extended airport
+						st = STATION_AIRPORT;
+						SetStationGfx(t, gfx - 83 + 67 - 8);
+					} else if (IsInsideMM(gfx, 168, 170)) { // Drive through truck
+						st = STATION_TRUCK;
+						SetStationGfx(t, gfx - 168 + GFX_TRUCK_BUS_DRIVETHROUGH_OFFSET);
+					} else if (IsInsideMM(gfx, 170, 172)) { // Drive through bus
+						st = STATION_BUS;
+						SetStationGfx(t, gfx - 170 + GFX_TRUCK_BUS_DRIVETHROUGH_OFFSET);
+					} else {
+						/* Restore the signals */
+						signal(SIGSEGV, prev_segfault);
+						signal(SIGABRT, prev_abort);
+						return false;
+					}
+					SB(_m[t].m6, 3, 3, st);
+				} break;
+			}
+		}
+	}
+
+	for (TileIndex t = 0; t < map_size; t++) {
+		switch (GetTileType(t)) {
+			case MP_STATION: {
+				Station *st = GetStationByTile(t);
+
+				/* Set up station spread; buoys do not have one */
+				if (!IsBuoy(t)) st->rect.BeforeAddTile(t, StationRect::ADD_FORCE);
+
+				switch (GetStationType(t)) {
+					case STATION_TRUCK:
+					case STATION_BUS:
+						if (CheckSavegameVersion(6)) {
+							/* From this version on there can be multiple road stops of the
+							 * same type per station. Convert the existing stops to the new
+							 * internal data structure. */
+							RoadStop *rs = new RoadStop(t);
+							if (rs == NULL) error("Too many road stops in savegame");
+
+							RoadStop **head =
+								IsTruckStop(t) ? &st->truck_stops : &st->bus_stops;
+							*head = rs;
+						}
+						break;
+
+					case STATION_OILRIG: {
+						/* Very old savegames sometimes have phantom oil rigs, i.e.
+						 * an oil rig which got shut down, but not completly removed from
+						 * the map
+						 */
+						TileIndex t1 = TILE_ADDXY(t, 0, 1);
+						if (IsTileType(t1, MP_INDUSTRY) &&
+								GetIndustryGfx(t1) == GFX_OILRIG_1) {
+							/* The internal encoding of oil rigs was changed twice.
+							 * It was 3 (till 2.2) and later 5 (till 5.1).
+							 * Setting it unconditionally does not hurt.
+							 */
+							GetStationByTile(t)->airport_type = AT_OILRIG;
+						} else {
+							DeleteOilRig(t);
+						}
+						break;
+					}
+
+					default: break;
+				}
+				break;
+			}
+
+			default: break;
+		}
+	}
+
+	/* In version 6.1 we put the town index in the map-array. To do this, we need
+	 *  to use m2 (16bit big), so we need to clean m2, and that is where this is
+	 *  all about ;) */
+	if (CheckSavegameVersionOldStyle(6, 1)) {
+		for (TileIndex t = 0; t < map_size; t++) {
+			switch (GetTileType(t)) {
+				case MP_HOUSE:
+					_m[t].m4 = _m[t].m2;
+					SetTownIndex(t, CalcClosestTownFromTile(t, UINT_MAX)->index);
+					break;
+
+				case MP_ROAD:
+					_m[t].m4 |= (_m[t].m2 << 4);
+					if ((GB(_m[t].m5, 4, 2) == ROAD_TILE_CROSSING ? (Owner)_m[t].m3 : GetTileOwner(t)) == OWNER_TOWN) {
+						SetTownIndex(t, CalcClosestTownFromTile(t, UINT_MAX)->index);
+					} else {
+						SetTownIndex(t, 0);
+					}
+					break;
+
+				default: break;
+			}
+		}
+	}
+
+	/* From version 9.0, we update the max passengers of a town (was sometimes negative
+	 *  before that. */
+	if (CheckSavegameVersion(9)) {
+		Town *t;
+		FOR_ALL_TOWNS(t) UpdateTownMaxPass(t);
+	}
+
+	/* From version 16.0, we included autorenew on engines, which are now saved, but
+	 *  of course, we do need to initialize them for older savegames. */
+	if (CheckSavegameVersion(16)) {
+		FOR_ALL_COMPANIES(c) {
+			c->engine_renew_list   = NULL;
+			c->engine_renew        = false;
+			c->engine_renew_months = -6;
+			c->engine_renew_money  = 100000;
+		}
+
+		/* When loading a game, _local_company is not yet set to the correct value.
+		 * However, in a dedicated server we are a spectator, so nothing needs to
+		 * happen. In case we are not a dedicated server, the local company always
+		 * becomes company 0, unless we are in the scenario editor where all the
+		 * companies are 'invalid'.
+		 */
+		if (!_network_dedicated && IsValidCompanyID(COMPANY_FIRST)) {
+			c = GetCompany(COMPANY_FIRST);
+			c->engine_renew        = _settings_client.gui.autorenew;
+			c->engine_renew_months = _settings_client.gui.autorenew_months;
+			c->engine_renew_money  = _settings_client.gui.autorenew_money;
+		}
+	}
+
+	if (CheckSavegameVersion(48)) {
+		for (TileIndex t = 0; t < map_size; t++) {
+			switch (GetTileType(t)) {
+				case MP_RAILWAY:
+					if (IsPlainRailTile(t)) {
+						/* Swap ground type and signal type for plain rail tiles, so the
+						 * ground type uses the same bits as for depots and waypoints. */
+						uint tmp = GB(_m[t].m4, 0, 4);
+						SB(_m[t].m4, 0, 4, GB(_m[t].m2, 0, 4));
+						SB(_m[t].m2, 0, 4, tmp);
+					} else if (HasBit(_m[t].m5, 2)) {
+						/* Split waypoint and depot rail type and remove the subtype. */
+						ClrBit(_m[t].m5, 2);
+						ClrBit(_m[t].m5, 6);
+					}
+					break;
+
+				case MP_ROAD:
+					/* Swap m3 and m4, so the track type for rail crossings is the
+					 * same as for normal rail. */
+					Swap(_m[t].m3, _m[t].m4);
+					break;
+
+				default: break;
+			}
+		}
+	}
+
+	if (CheckSavegameVersion(61)) {
+		/* Added the RoadType */
+		bool old_bridge = CheckSavegameVersion(42);
+		for (TileIndex t = 0; t < map_size; t++) {
+			switch(GetTileType(t)) {
+				case MP_ROAD:
+					SB(_m[t].m5, 6, 2, GB(_m[t].m5, 4, 2));
+					switch (GetRoadTileType(t)) {
+						default: NOT_REACHED();
+						case ROAD_TILE_NORMAL:
+							SB(_m[t].m4, 0, 4, GB(_m[t].m5, 0, 4));
+							SB(_m[t].m4, 4, 4, 0);
+							SB(_m[t].m6, 2, 4, 0);
+							break;
+						case ROAD_TILE_CROSSING:
+							SB(_m[t].m4, 5, 2, GB(_m[t].m5, 2, 2));
+							break;
+						case ROAD_TILE_DEPOT:    break;
+					}
+					SetRoadTypes(t, ROADTYPES_ROAD);
+					break;
+
+				case MP_STATION:
+					if (IsRoadStop(t)) SetRoadTypes(t, ROADTYPES_ROAD);
+					break;
+
+				case MP_TUNNELBRIDGE:
+					/* Middle part of "old" bridges */
+					if (old_bridge && IsBridge(t) && HasBit(_m[t].m5, 6)) break;
+					if (((old_bridge && IsBridge(t)) ? (TransportType)GB(_m[t].m5, 1, 2) : GetTunnelBridgeTransportType(t)) == TRANSPORT_ROAD) {
+						SetRoadTypes(t, ROADTYPES_ROAD);
+					}
+					break;
+
+				default: break;
+			}
+		}
+	}
+
+	if (CheckSavegameVersion(42)) {
+		Vehicle* v;
+
+		for (TileIndex t = 0; t < map_size; t++) {
+			if (MayHaveBridgeAbove(t)) ClearBridgeMiddle(t);
+			if (IsBridgeTile(t)) {
+				if (HasBit(_m[t].m5, 6)) { // middle part
+					Axis axis = (Axis)GB(_m[t].m5, 0, 1);
+
+					if (HasBit(_m[t].m5, 5)) { // transport route under bridge?
+						if (GB(_m[t].m5, 3, 2) == TRANSPORT_RAIL) {
+							MakeRailNormal(
+								t,
+								GetTileOwner(t),
+								axis == AXIS_X ? TRACK_BIT_Y : TRACK_BIT_X,
+								GetRailType(t)
+							);
+						} else {
+							TownID town = IsTileOwner(t, OWNER_TOWN) ? ClosestTownFromTile(t, UINT_MAX)->index : 0;
+
+							MakeRoadNormal(
+								t,
+								axis == AXIS_X ? ROAD_Y : ROAD_X,
+								ROADTYPES_ROAD,
+								town,
+								GetTileOwner(t), OWNER_NONE, OWNER_NONE
+							);
+						}
+					} else {
+						if (GB(_m[t].m5, 3, 2) == 0) {
+							MakeClear(t, CLEAR_GRASS, 3);
+						} else {
+							if (GetTileSlope(t, NULL) != SLOPE_FLAT) {
+								MakeShore(t);
+							} else {
+								if (GetTileOwner(t) == OWNER_WATER) {
+									MakeWater(t);
+								} else {
+									MakeCanal(t, GetTileOwner(t), Random());
+								}
+							}
+						}
+					}
+					SetBridgeMiddle(t, axis);
+				} else { // ramp
+					Axis axis = (Axis)GB(_m[t].m5, 0, 1);
+					uint north_south = GB(_m[t].m5, 5, 1);
+					DiagDirection dir = ReverseDiagDir(XYNSToDiagDir(axis, north_south));
+					TransportType type = (TransportType)GB(_m[t].m5, 1, 2);
+
+					_m[t].m5 = 1 << 7 | type << 2 | dir;
+				}
+			}
+		}
+
+		FOR_ALL_VEHICLES(v) {
+			if (v->type != VEH_TRAIN && v->type != VEH_ROAD) continue;
+			if (IsBridgeTile(v->tile)) {
+				DiagDirection dir = GetTunnelBridgeDirection(v->tile);
+
+				if (dir != DirToDiagDir(v->direction)) continue;
+				switch (dir) {
+					default: NOT_REACHED();
+					case DIAGDIR_NE: if ((v->x_pos & 0xF) !=  0)            continue; break;
+					case DIAGDIR_SE: if ((v->y_pos & 0xF) != TILE_SIZE - 1) continue; break;
+					case DIAGDIR_SW: if ((v->x_pos & 0xF) != TILE_SIZE - 1) continue; break;
+					case DIAGDIR_NW: if ((v->y_pos & 0xF) !=  0)            continue; break;
+				}
+			} else if (v->z_pos > GetSlopeZ(v->x_pos, v->y_pos)) {
+				v->tile = GetNorthernBridgeEnd(v->tile);
+			} else {
+				continue;
+			}
+			if (v->type == VEH_TRAIN) {
+				v->u.rail.track = TRACK_BIT_WORMHOLE;
+			} else {
+				v->u.road.state = RVSB_WORMHOLE;
+			}
+		}
+	}
+
+	/* Elrails got added in rev 24 */
+	if (CheckSavegameVersion(24)) {
+		Vehicle *v;
+		RailType min_rail = RAILTYPE_ELECTRIC;
+
+		FOR_ALL_VEHICLES(v) {
+			if (v->type == VEH_TRAIN) {
+				RailType rt = RailVehInfo(v->engine_type)->railtype;
+
+				v->u.rail.railtype = rt;
+				if (rt == RAILTYPE_ELECTRIC) min_rail = RAILTYPE_RAIL;
+			}
+		}
+
+		/* .. so we convert the entire map from normal to elrail (so maintain "fairness") */
+		for (TileIndex t = 0; t < map_size; t++) {
+			switch (GetTileType(t)) {
+				case MP_RAILWAY:
+					SetRailType(t, UpdateRailType(GetRailType(t), min_rail));
+					break;
+
+				case MP_ROAD:
+					if (IsLevelCrossing(t)) {
+						SetRailType(t, UpdateRailType(GetRailType(t), min_rail));
+					}
+					break;
+
+				case MP_STATION:
+					if (IsRailwayStation(t)) {
+						SetRailType(t, UpdateRailType(GetRailType(t), min_rail));
+					}
+					break;
+
+				case MP_TUNNELBRIDGE:
+					if (GetTunnelBridgeTransportType(t) == TRANSPORT_RAIL) {
+						SetRailType(t, UpdateRailType(GetRailType(t), min_rail));
+					}
+					break;
+
+				default:
+					break;
+			}
+		}
+
+		FOR_ALL_VEHICLES(v) {
+			if (v->type == VEH_TRAIN && (IsFrontEngine(v) || IsFreeWagon(v))) TrainConsistChanged(v, true);
+		}
+
+	}
+
+	/* In version 16.1 of the savegame a company can decide if trains, which get
+	 * replaced, shall keep their old length. In all prior versions, just default
+	 * to false */
+	if (CheckSavegameVersionOldStyle(16, 1)) {
+		FOR_ALL_COMPANIES(c) c->renew_keep_length = false;
+	}
+
+	/* In version 17, ground type is moved from m2 to m4 for depots and
+	 * waypoints to make way for storing the index in m2. The custom graphics
+	 * id which was stored in m4 is now saved as a grf/id reference in the
+	 * waypoint struct. */
+	if (CheckSavegameVersion(17)) {
+		Waypoint *wp;
+
+		FOR_ALL_WAYPOINTS(wp) {
+			if (wp->deleted == 0) {
+				const StationSpec *statspec = NULL;
+
+				if (HasBit(_m[wp->xy].m3, 4))
+					statspec = GetCustomStationSpec(STAT_CLASS_WAYP, _m[wp->xy].m4 + 1);
+
+				if (statspec != NULL) {
+					wp->stat_id = _m[wp->xy].m4 + 1;
+					wp->grfid = statspec->grffile->grfid;
+					wp->localidx = statspec->localidx;
+				} else {
+					/* No custom graphics set, so set to default. */
+					wp->stat_id = 0;
+					wp->grfid = 0;
+					wp->localidx = 0;
+				}
+
+				/* Move ground type bits from m2 to m4. */
+				_m[wp->xy].m4 = GB(_m[wp->xy].m2, 0, 4);
+				/* Store waypoint index in the tile. */
+				_m[wp->xy].m2 = wp->index;
+			}
+		}
+	} else {
+		/* As of version 17, we recalculate the custom graphic ID of waypoints
+		 * from the GRF ID / station index. */
+		AfterLoadWaypoints();
+	}
+
+	/* From version 15, we moved a semaphore bit from bit 2 to bit 3 in m4, making
+	 *  room for PBS. Now in version 21 move it back :P. */
+	if (CheckSavegameVersion(21) && !CheckSavegameVersion(15)) {
+		for (TileIndex t = 0; t < map_size; t++) {
+			switch (GetTileType(t)) {
+				case MP_RAILWAY:
+					if (HasSignals(t)) {
+						/* convert PBS signals to combo-signals */
+						if (HasBit(_m[t].m2, 2)) SetSignalType(t, TRACK_X, SIGTYPE_COMBO);
+
+						/* move the signal variant back */
+						SetSignalVariant(t, TRACK_X, HasBit(_m[t].m2, 3) ? SIG_SEMAPHORE : SIG_ELECTRIC);
+						ClrBit(_m[t].m2, 3);
+					}
+
+					/* Clear PBS reservation on track */
+					if (!IsRailDepotTile(t)) {
+						SB(_m[t].m4, 4, 4, 0);
+					} else {
+						ClrBit(_m[t].m3, 6);
+					}
+					break;
+
+				case MP_ROAD: /* Clear PBS reservation on crossing */
+					if (IsLevelCrossing(t)) ClrBit(_m[t].m5, 0);
+					break;
+
+				case MP_STATION: /* Clear PBS reservation on station */
+					ClrBit(_m[t].m3, 6);
+					break;
+
+				default: break;
+			}
+		}
+	}
+
+	if (CheckSavegameVersion(25)) {
+		Vehicle *v;
+		FOR_ALL_VEHICLES(v) {
+			if (v->type == VEH_ROAD) {
+				v->vehstatus &= ~0x40;
+				v->u.road.slot = NULL;
+				v->u.road.slot_age = 0;
+			}
+		}
+	} else {
+		Vehicle *v;
+		FOR_ALL_VEHICLES(v) {
+			if (v->type == VEH_ROAD && v->u.road.slot != NULL) v->u.road.slot->num_vehicles++;
+		}
+	}
+
+	if (CheckSavegameVersion(26)) {
+		Station *st;
+		FOR_ALL_STATIONS(st) {
+			st->last_vehicle_type = VEH_INVALID;
+		}
+	}
+
+	YapfNotifyTrackLayoutChange(INVALID_TILE, INVALID_TRACK);
+
+	if (CheckSavegameVersion(34)) FOR_ALL_COMPANIES(c) ResetCompanyLivery(c);
+
+	FOR_ALL_COMPANIES(c) {
+		c->avail_railtypes = GetCompanyRailtypes(c->index);
+		c->avail_roadtypes = GetCompanyRoadtypes(c->index);
+	}
+
+	if (!CheckSavegameVersion(27)) AfterLoadStations();
+
+	/* Time starts at 0 instead of 1920.
+	 * Account for this in older games by adding an offset */
+	if (CheckSavegameVersion(31)) {
+		Station *st;
+		Waypoint *wp;
+		Engine *e;
+		Industry *i;
+		Vehicle *v;
+
+		_date += DAYS_TILL_ORIGINAL_BASE_YEAR;
+		_cur_year += ORIGINAL_BASE_YEAR;
+
+		FOR_ALL_STATIONS(st)  st->build_date      += DAYS_TILL_ORIGINAL_BASE_YEAR;
+		FOR_ALL_WAYPOINTS(wp) wp->build_date      += DAYS_TILL_ORIGINAL_BASE_YEAR;
+		FOR_ALL_ENGINES(e)    e->intro_date       += DAYS_TILL_ORIGINAL_BASE_YEAR;
+		FOR_ALL_COMPANIES(c)  c->inaugurated_year += ORIGINAL_BASE_YEAR;
+		FOR_ALL_INDUSTRIES(i) i->last_prod_year   += ORIGINAL_BASE_YEAR;
+
+		FOR_ALL_VEHICLES(v) {
+			v->date_of_last_service += DAYS_TILL_ORIGINAL_BASE_YEAR;
+			v->build_year += ORIGINAL_BASE_YEAR;
+		}
+	}
+
+	/* From 32 on we save the industry who made the farmland.
+	 *  To give this prettyness to old savegames, we remove all farmfields and
+	 *  plant new ones. */
+	if (CheckSavegameVersion(32)) {
+		Industry *i;
+
+		for (TileIndex t = 0; t < map_size; t++) {
+			if (IsTileType(t, MP_CLEAR) && IsClearGround(t, CLEAR_FIELDS)) {
+				/* remove fields */
+				MakeClear(t, CLEAR_GRASS, 3);
+			} else if (IsTileType(t, MP_CLEAR) || IsTileType(t, MP_TREES)) {
+				/* remove fences around fields */
+				SetFenceSE(t, 0);
+				SetFenceSW(t, 0);
+			}
+		}
+
+		FOR_ALL_INDUSTRIES(i) {
+			uint j;
+
+			if (GetIndustrySpec(i->type)->behaviour & INDUSTRYBEH_PLANT_ON_BUILT) {
+				for (j = 0; j != 50; j++) PlantRandomFarmField(i);
+			}
+		}
+	}
+
+	/* Setting no refit flags to all orders in savegames from before refit in orders were added */
+	if (CheckSavegameVersion(36)) {
+		Order *order;
+		Vehicle *v;
+
+		FOR_ALL_ORDERS(order) {
+			order->SetRefit(CT_NO_REFIT);
+		}
+
+		FOR_ALL_VEHICLES(v) {
+			v->current_order.SetRefit(CT_NO_REFIT);
+		}
+	}
+
+	/* 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_game.vehicle.disable_elrails = false;
+	/* do the same as when elrails were enabled/disabled manually just now */
+	SettingsDisableElrail(_settings_game.vehicle.disable_elrails);
+	InitializeRailGUI();
+
+	/* From version 53, the map array was changed for house tiles to allow
+	 * space for newhouses grf features. A new byte, m7, was also added. */
+	if (CheckSavegameVersion(53)) {
+		for (TileIndex t = 0; t < map_size; t++) {
+			if (IsTileType(t, MP_HOUSE)) {
+				if (GB(_m[t].m3, 6, 2) != TOWN_HOUSE_COMPLETED) {
+					/* Move the construction stage from m3[7..6] to m5[5..4].
+					 * The construction counter does not have to move. */
+					SB(_m[t].m5, 3, 2, GB(_m[t].m3, 6, 2));
+					SB(_m[t].m3, 6, 2, 0);
+
+					/* The "house is completed" bit is now in m6[2]. */
+					SetHouseCompleted(t, false);
+				} else {
+					/* The "lift has destination" bit has been moved from
+					 * m5[7] to m7[0]. */
+					SB(_me[t].m7, 0, 1, HasBit(_m[t].m5, 7));
+					ClrBit(_m[t].m5, 7);
+
+					/* The "lift is moving" bit has been removed, as it does
+					 * the same job as the "lift has destination" bit. */
+					ClrBit(_m[t].m1, 7);
+
+					/* The position of the lift goes from m1[7..0] to m6[7..2],
+					 * making m1 totally free, now. The lift position does not
+					 * have to be a full byte since the maximum value is 36. */
+					SetLiftPosition(t, GB(_m[t].m1, 0, 6 ));
+
+					_m[t].m1 = 0;
+					_m[t].m3 = 0;
+					SetHouseCompleted(t, true);
+				}
+			}
+		}
+	}
+
+	/* Check and update house and town values */
+	UpdateHousesAndTowns();
+
+	if (CheckSavegameVersion(43)) {
+		for (TileIndex t = 0; t < map_size; t++) {
+			if (IsTileType(t, MP_INDUSTRY)) {
+				switch (GetIndustryGfx(t)) {
+					case GFX_POWERPLANT_SPARKS:
+						SetIndustryAnimationState(t, GB(_m[t].m1, 2, 5));
+						break;
+
+					case GFX_OILWELL_ANIMATED_1:
+					case GFX_OILWELL_ANIMATED_2:
+					case GFX_OILWELL_ANIMATED_3:
+						SetIndustryAnimationState(t, GB(_m[t].m1, 0, 2));
+						break;
+
+					case GFX_COAL_MINE_TOWER_ANIMATED:
+					case GFX_COPPER_MINE_TOWER_ANIMATED:
+					case GFX_GOLD_MINE_TOWER_ANIMATED:
+						 SetIndustryAnimationState(t, _m[t].m1);
+						 break;
+
+					default: /* No animation states to change */
+						break;
+				}
+			}
+		}
+	}
+
+	if (CheckSavegameVersion(44)) {
+		Vehicle *v;
+		/* If we remove a station while cargo from it is still enroute, payment calculation will assume
+		 * 0, 0 to be the source of the cargo, resulting in very high payments usually. v->source_xy
+		 * stores the coordinates, preserving them even if the station is removed. However, if a game is loaded
+		 * where this situation exists, the cargo-source information is lost. in this case, we set the source
+		 * to the current tile of the vehicle to prevent excessive profits
+		 */
+		FOR_ALL_VEHICLES(v) {
+			const CargoList::List *packets = v->cargo.Packets();
+			for (CargoList::List::const_iterator it = packets->begin(); it != packets->end(); it++) {
+				CargoPacket *cp = *it;
+				cp->source_xy = IsValidStationID(cp->source) ? GetStation(cp->source)->xy : v->tile;
+				cp->loaded_at_xy = cp->source_xy;
+			}
+			v->cargo.InvalidateCache();
+		}
+
+		/* Store position of the station where the goods come from, so there
+		 * are no very high payments when stations get removed. However, if the
+		 * station where the goods came from is already removed, the source
+		 * information is lost. In that case we set it to the position of this
+		 * station */
+		Station *st;
+		FOR_ALL_STATIONS(st) {
+			for (CargoID c = 0; c < NUM_CARGO; c++) {
+				GoodsEntry *ge = &st->goods[c];
+
+				const CargoList::List *packets = ge->cargo.Packets();
+				for (CargoList::List::const_iterator it = packets->begin(); it != packets->end(); it++) {
+					CargoPacket *cp = *it;
+					cp->source_xy = IsValidStationID(cp->source) ? GetStation(cp->source)->xy : st->xy;
+					cp->loaded_at_xy = cp->source_xy;
+				}
+			}
+		}
+	}
+
+	if (CheckSavegameVersion(45)) {
+		Vehicle *v;
+		/* Originally just the fact that some cargo had been paid for was
+		 * stored to stop people cheating and cashing in several times. This
+		 * wasn't enough though as it was cleared when the vehicle started
+		 * loading again, even if it didn't actually load anything, so now the
+		 * amount of cargo that has been paid for is stored. */
+		FOR_ALL_VEHICLES(v) {
+			const CargoList::List *packets = v->cargo.Packets();
+			for (CargoList::List::const_iterator it = packets->begin(); it != packets->end(); it++) {
+				CargoPacket *cp = *it;
+				cp->paid_for = HasBit(v->vehicle_flags, 2);
+			}
+			ClrBit(v->vehicle_flags, 2);
+			v->cargo.InvalidateCache();
+		}
+	}
+
+	/* Buoys do now store the owner of the previous water tile, which can never
+	 * be OWNER_NONE. So replace OWNER_NONE with OWNER_WATER. */
+	if (CheckSavegameVersion(46)) {
+		Station *st;
+		FOR_ALL_STATIONS(st) {
+			if (st->IsBuoy() && IsTileOwner(st->xy, OWNER_NONE) && TileHeight(st->xy) == 0) SetTileOwner(st->xy, OWNER_WATER);
+		}
+	}
+
+	if (CheckSavegameVersion(50)) {
+		Vehicle *v;
+		/* Aircraft units changed from 8 mph to 1 km/h */
+		FOR_ALL_VEHICLES(v) {
+			if (v->type == VEH_AIRCRAFT && v->subtype <= AIR_AIRCRAFT) {
+				const AircraftVehicleInfo *avi = AircraftVehInfo(v->engine_type);
+				v->cur_speed *= 129;
+				v->cur_speed /= 10;
+				v->max_speed = avi->max_speed;
+				v->acceleration = avi->acceleration;
+			}
+		}
+	}
+
+	if (CheckSavegameVersion(49)) FOR_ALL_COMPANIES(c) c->face = ConvertFromOldCompanyManagerFace(c->face);
+
+	if (CheckSavegameVersion(52)) {
+		for (TileIndex t = 0; t < map_size; t++) {
+			if (IsStatueTile(t)) {
+				_m[t].m2 = CalcClosestTownFromTile(t, UINT_MAX)->index;
+			}
+		}
+	}
+
+	/* A patch option containing the proportion of towns that grow twice as
+	 * fast was added in version 54. From version 56 this is now saved in the
+	 * town as cities can be built specifically in the scenario editor. */
+	if (CheckSavegameVersion(56)) {
+		Town *t;
+
+		FOR_ALL_TOWNS(t) {
+			if (_settings_game.economy.larger_towns != 0 && (t->index % _settings_game.economy.larger_towns) == 0) {
+				t->larger_town = true;
+			}
+		}
+	}
+
+	if (CheckSavegameVersion(57)) {
+		Vehicle *v;
+		/* Added a FIFO queue of vehicles loading at stations */
+		FOR_ALL_VEHICLES(v) {
+			if ((v->type != VEH_TRAIN || IsFrontEngine(v)) &&  // for all locs
+					!(v->vehstatus & (VS_STOPPED | VS_CRASHED)) && // not stopped or crashed
+					v->current_order.IsType(OT_LOADING)) {         // loading
+				GetStation(v->last_station_visited)->loading_vehicles.push_back(v);
+
+				/* The loading finished flag is *only* set when actually completely
+				 * finished. Because the vehicle is loading, it is not finished. */
+				ClrBit(v->vehicle_flags, VF_LOADING_FINISHED);
+			}
+		}
+	} else if (CheckSavegameVersion(59)) {
+		/* For some reason non-loading vehicles could be in the station's loading vehicle list */
+
+		Station *st;
+		FOR_ALL_STATIONS(st) {
+			std::list<Vehicle *>::iterator iter;
+			for (iter = st->loading_vehicles.begin(); iter != st->loading_vehicles.end();) {
+				Vehicle *v = *iter;
+				iter++;
+				if (!v->current_order.IsType(OT_LOADING)) st->loading_vehicles.remove(v);
+			}
+		}
+	}
+
+	if (CheckSavegameVersion(58)) {
+		/* patch difficulty number_industries other than zero get bumped to +1
+		 * since a new option (very low at position1) has been added */
+		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_game.difficulty.number_towns++;
+	}
+
+	if (CheckSavegameVersion(64)) {
+		/* copy the signal type/variant and move signal states bits */
+		for (TileIndex t = 0; t < map_size; t++) {
+			if (IsTileType(t, MP_RAILWAY) && HasSignals(t)) {
+				SetSignalStates(t, GB(_m[t].m2, 4, 4));
+				SetSignalVariant(t, INVALID_TRACK, GetSignalVariant(t, TRACK_X));
+				SetSignalType(t, INVALID_TRACK, GetSignalType(t, TRACK_X));
+				ClrBit(_m[t].m2, 7);
+			}
+		}
+	}
+
+	if (CheckSavegameVersion(69)) {
+		/* In some old savegames a bit was cleared when it should not be cleared */
+		Vehicle *v;
+		FOR_ALL_VEHICLES(v) {
+			if (v->type == VEH_ROAD && (v->u.road.state == 250 || v->u.road.state == 251)) {
+				SetBit(v->u.road.state, RVS_IS_STOPPING);
+			}
+		}
+	}
+
+	if (CheckSavegameVersion(70)) {
+		/* Added variables to support newindustries */
+		Industry *i;
+		FOR_ALL_INDUSTRIES(i) i->founder = OWNER_NONE;
+	}
+
+	/* From version 82, old style canals (above sealevel (0), WATER owner) are no longer supported.
+	    Replace the owner for those by OWNER_NONE. */
+	if (CheckSavegameVersion(82)) {
+		for (TileIndex t = 0; t < map_size; t++) {
+			if (IsTileType(t, MP_WATER) &&
+					GetWaterTileType(t) == WATER_TILE_CLEAR &&
+					GetTileOwner(t) == OWNER_WATER &&
+					TileHeight(t) != 0) {
+				SetTileOwner(t, OWNER_NONE);
+			}
+		}
+	}
+
+	/*
+	 * Add the 'previous' owner to the ship depots so we can reset it with
+	 * the correct values when it gets destroyed. This prevents that
+	 * someone can remove canals owned by somebody else and it prevents
+	 * making floods using the removal of ship depots.
+	 */
+	if (CheckSavegameVersion(83)) {
+		for (TileIndex t = 0; t < map_size; t++) {
+			if (IsTileType(t, MP_WATER) && IsShipDepot(t)) {
+				_m[t].m4 = (TileHeight(t) == 0) ? OWNER_WATER : OWNER_NONE;
+			}
+		}
+	}
+
+	if (CheckSavegameVersion(74)) {
+		Station *st;
+		FOR_ALL_STATIONS(st) {
+			for (CargoID c = 0; c < NUM_CARGO; c++) {
+				st->goods[c].last_speed = 0;
+				if (st->goods[c].cargo.Count() != 0) SetBit(st->goods[c].acceptance_pickup, GoodsEntry::PICKUP);
+			}
+		}
+	}
+
+	if (CheckSavegameVersion(78)) {
+		Industry *i;
+		uint j;
+		FOR_ALL_INDUSTRIES(i) {
+			const IndustrySpec *indsp = GetIndustrySpec(i->type);
+			for (j = 0; j < lengthof(i->produced_cargo); j++) {
+				i->produced_cargo[j] = indsp->produced_cargo[j];
+			}
+			for (j = 0; j < lengthof(i->accepts_cargo); j++) {
+				i->accepts_cargo[j] = indsp->accepts_cargo[j];
+			}
+		}
+	}
+
+	/* Before version 81, the density of grass was always stored as zero, and
+	 * grassy trees were always drawn fully grassy. Furthermore, trees on rough
+	 * land used to have zero density, now they have full density. Therefore,
+	 * make all grassy/rough land trees have a density of 3. */
+	if (CheckSavegameVersion(81)) {
+		for (TileIndex t = 0; t < map_size; t++) {
+			if (GetTileType(t) == MP_TREES) {
+				TreeGround groundType = GetTreeGround(t);
+				if (groundType != TREE_GROUND_SNOW_DESERT) SetTreeGroundDensity(t, groundType, 3);
+			}
+		}
+	}
+
+
+	if (CheckSavegameVersion(93)) {
+		/* Rework of orders. */
+		Order *order;
+		FOR_ALL_ORDERS(order) order->ConvertFromOldSavegame();
+
+		Vehicle *v;
+		FOR_ALL_VEHICLES(v) {
+			if (v->orders.list != NULL && v->orders.list->GetFirstOrder() != NULL && !v->orders.list->GetFirstOrder()->IsValid()) {
+				v->orders.list->FreeChain();
+				v->orders.list = NULL;
+			}
+
+			v->current_order.ConvertFromOldSavegame();
+			if (v->type == VEH_ROAD && v->IsPrimaryVehicle() && v->FirstShared() == v) {
+				FOR_VEHICLE_ORDERS(v, order) order->SetNonStopType(ONSF_NO_STOP_AT_INTERMEDIATE_STATIONS);
+			}
+		}
+	} else if (CheckSavegameVersion(94)) {
+		/* Unload and transfer are now mutual exclusive. */
+		Order *order;
+		FOR_ALL_ORDERS(order) {
+			if ((order->GetUnloadType() & (OUFB_UNLOAD | OUFB_TRANSFER)) == (OUFB_UNLOAD | OUFB_TRANSFER)) {
+				order->SetUnloadType(OUFB_TRANSFER);
+				order->SetLoadType(OLFB_NO_LOAD);
+			}
+		}
+
+		Vehicle *v;
+		FOR_ALL_VEHICLES(v) {
+			if ((v->current_order.GetUnloadType() & (OUFB_UNLOAD | OUFB_TRANSFER)) == (OUFB_UNLOAD | OUFB_TRANSFER)) {
+				v->current_order.SetUnloadType(OUFB_TRANSFER);
+				v->current_order.SetLoadType(OLFB_NO_LOAD);
+			}
+		}
+	}
+
+	if (CheckSavegameVersion(84)) {
+		/* Update go to buoy orders because they are just waypoints */
+		Order *order;
+		FOR_ALL_ORDERS(order) {
+			if (order->IsType(OT_GOTO_STATION) && GetStation(order->GetDestination())->IsBuoy()) {
+				order->SetLoadType(OLF_LOAD_IF_POSSIBLE);
+				order->SetUnloadType(OUF_UNLOAD_IF_POSSIBLE);
+			}
+		}
+
+		/* Set all share owners to INVALID_COMPANY for
+		 * 1) all inactive companies
+		 *     (when inactive companies were stored in the savegame - TTD, TTDP and some
+		 *      *really* old revisions of OTTD; else it is already set in InitializeCompanies())
+		 * 2) shares that are owned by inactive companies or self
+		 *     (caused by cheating clients in earlier revisions) */
+		FOR_ALL_COMPANIES(c) {
+			for (uint i = 0; i < 4; i++) {
+				CompanyID company = c->share_owners[i];
+				if (company == INVALID_COMPANY) continue;
+				if (!IsValidCompanyID(company) || company == c->index) c->share_owners[i] = INVALID_COMPANY;
+			}
+		}
+	}
+
+	if (CheckSavegameVersion(86)) {
+		for (TileIndex t = 0; t < map_size; t++) {
+			/* Move river flag and update canals to use water class */
+			if (IsTileType(t, MP_WATER)) {
+				if (GetWaterClass(t) != WATER_CLASS_RIVER) {
+					if (IsWater(t)) {
+						Owner o = GetTileOwner(t);
+						if (o == OWNER_WATER) {
+							MakeWater(t);
+						} else {
+							MakeCanal(t, o, Random());
+						}
+					} else if (IsShipDepot(t)) {
+						Owner o = (Owner)_m[t].m4; // Original water owner
+						SetWaterClass(t, o == OWNER_WATER ? WATER_CLASS_SEA : WATER_CLASS_CANAL);
+					}
+				}
+			}
+		}
+
+		/* Update locks, depots, docks and buoys to have a water class based
+		 * on its neighbouring tiles. Done after river and canal updates to
+		 * ensure neighbours are correct. */
+		for (TileIndex t = 0; t < map_size; t++) {
+			if (GetTileSlope(t, NULL) != SLOPE_FLAT) continue;
+
+			if (IsTileType(t, MP_WATER) && IsLock(t)) SetWaterClassDependingOnSurroundings(t, false);
+			if (IsTileType(t, MP_STATION) && (IsDock(t) || IsBuoy(t))) SetWaterClassDependingOnSurroundings(t, false);
+		}
+	}
+
+	if (CheckSavegameVersion(87)) {
+		for (TileIndex t = 0; t < map_size; t++) {
+			/* skip oil rigs at borders! */
+			if ((IsTileType(t, MP_WATER) || IsBuoyTile(t)) &&
+					(TileX(t) == 0 || TileY(t) == 0 || TileX(t) == MapMaxX() - 1 || TileY(t) == MapMaxY() - 1)) {
+				/* Some version 86 savegames have wrong water class at map borders (under buoy, or after removing buoy).
+				 * This conversion has to be done before buoys with invalid owner are removed. */
+				SetWaterClass(t, WATER_CLASS_SEA);
+			}
+
+			if (IsBuoyTile(t) || IsDriveThroughStopTile(t) || IsTileType(t, MP_WATER)) {
+				Owner o = GetTileOwner(t);
+				if (o < MAX_COMPANIES && !IsValidCompanyID(o)) {
+					_current_company = o;
+					ChangeTileOwner(t, o, INVALID_OWNER);
+				}
+				if (IsBuoyTile(t)) {
+					/* reset buoy owner to OWNER_NONE in the station struct
+					 * (even if it is owned by active company) */
+					GetStationByTile(t)->owner = OWNER_NONE;
+				}
+			} else if (IsTileType(t, MP_ROAD)) {
+				/* works for all RoadTileType */
+				for (RoadType rt = ROADTYPE_ROAD; rt < ROADTYPE_END; rt++) {
+					/* update even non-existing road types to update tile owner too */
+					Owner o = GetRoadOwner(t, rt);
+					if (o < MAX_COMPANIES && !IsValidCompanyID(o)) SetRoadOwner(t, rt, OWNER_NONE);
+				}
+				if (IsLevelCrossing(t)) {
+					Owner o = GetTileOwner(t);
+					if (!IsValidCompanyID(o)) {
+						/* remove leftover rail piece from crossing (from very old savegames) */
+						_current_company = o;
+						DoCommand(t, 0, GetCrossingRailTrack(t), DC_EXEC | DC_BANKRUPT, CMD_REMOVE_SINGLE_RAIL);
+					}
+				}
+			}
+		}
+
+		/* Convert old PF settings to new */
+		if (_settings_game.pf.yapf.rail_use_yapf || CheckSavegameVersion(28)) {
+			_settings_game.pf.pathfinder_for_trains = VPF_YAPF;
+		} else {
+			_settings_game.pf.pathfinder_for_trains = (_settings_game.pf.new_pathfinding_all ? VPF_NPF : VPF_NTP);
+		}
+
+		if (_settings_game.pf.yapf.road_use_yapf || CheckSavegameVersion(28)) {
+			_settings_game.pf.pathfinder_for_roadvehs = VPF_YAPF;
+		} else {
+			_settings_game.pf.pathfinder_for_roadvehs = (_settings_game.pf.new_pathfinding_all ? VPF_NPF : VPF_OPF);
+		}
+
+		if (_settings_game.pf.yapf.ship_use_yapf) {
+			_settings_game.pf.pathfinder_for_ships = VPF_YAPF;
+		} else {
+			_settings_game.pf.pathfinder_for_ships = (_settings_game.pf.new_pathfinding_all ? VPF_NPF : VPF_OPF);
+		}
+	}
+
+	if (CheckSavegameVersion(88)) {
+		/* Profits are now with 8 bit fract */
+		Vehicle *v;
+		FOR_ALL_VEHICLES(v) {
+			v->profit_this_year <<= 8;
+			v->profit_last_year <<= 8;
+			v->running_ticks = 0;
+		}
+	}
+
+	if (CheckSavegameVersion(91)) {
+		/* Increase HouseAnimationFrame from 5 to 7 bits */
+		for (TileIndex t = 0; t < map_size; t++) {
+			if (IsTileType(t, MP_HOUSE) && GetHouseType(t) >= NEW_HOUSE_OFFSET) {
+				SetHouseAnimationFrame(t, GB(_m[t].m6, 3, 5));
+			}
+		}
+	}
+
+	if (CheckSavegameVersion(62)) {
+		/* Remove all trams from savegames without tram support.
+		 * There would be trams without tram track under causing crashes sooner or later. */
+		Vehicle *v;
+		FOR_ALL_VEHICLES(v) {
+			if (v->type == VEH_ROAD && v->First() == v &&
+					HasBit(EngInfo(v->engine_type)->misc_flags, EF_ROAD_TRAM)) {
+				if (_switch_mode_errorstr == INVALID_STRING_ID || _switch_mode_errorstr == STR_NEWGRF_COMPATIBLE_LOAD_WARNING) {
+					_switch_mode_errorstr = STR_LOADGAME_REMOVED_TRAMS;
+				}
+				delete v;
+			}
+		}
+	}
+
+	if (CheckSavegameVersion(99)) {
+		for (TileIndex t = 0; t < map_size; t++) {
+			/* Set newly introduced WaterClass of industry tiles */
+			if (IsTileType(t, MP_STATION) && IsOilRig(t)) {
+				SetWaterClassDependingOnSurroundings(t, true);
+			}
+			if (IsTileType(t, MP_INDUSTRY)) {
+				if ((GetIndustrySpec(GetIndustryType(t))->behaviour & INDUSTRYBEH_BUILT_ONWATER) != 0) {
+					SetWaterClassDependingOnSurroundings(t, true);
+				} else {
+					SetWaterClass(t, WATER_CLASS_INVALID);
+				}
+			}
+
+			/* Replace "house construction year" with "house age" */
+			if (IsTileType(t, MP_HOUSE) && IsHouseCompleted(t)) {
+				_m[t].m5 = Clamp(_cur_year - (_m[t].m5 + ORIGINAL_BASE_YEAR), 0, 0xFF);
+			}
+		}
+	}
+
+	/* Move the signal variant back up one bit for PBS. We don't convert the old PBS
+	 * format here, as an old layout wouldn't work properly anyway. To be safe, we
+	 * clear any possible PBS reservations as well. */
+	if (CheckSavegameVersion(100)) {
+		for (TileIndex t = 0; t < map_size; t++) {
+			switch (GetTileType(t)) {
+				case MP_RAILWAY:
+					if (HasSignals(t)) {
+						/* move the signal variant */
+						SetSignalVariant(t, TRACK_UPPER, HasBit(_m[t].m2, 2) ? SIG_SEMAPHORE : SIG_ELECTRIC);
+						SetSignalVariant(t, TRACK_LOWER, HasBit(_m[t].m2, 6) ? SIG_SEMAPHORE : SIG_ELECTRIC);
+						ClrBit(_m[t].m2, 2);
+						ClrBit(_m[t].m2, 6);
+					}
+
+					/* Clear PBS reservation on track */
+					if (IsRailDepot(t) ||IsRailWaypoint(t)) {
+						SetDepotWaypointReservation(t, false);
+					} else {
+						SetTrackReservation(t, TRACK_BIT_NONE);
+					}
+					break;
+
+				case MP_ROAD: /* Clear PBS reservation on crossing */
+					if (IsLevelCrossing(t)) SetCrossingReservation(t, false);
+					break;
+
+				case MP_STATION: /* Clear PBS reservation on station */
+					if (IsRailwayStation(t)) SetRailwayStationReservation(t, false);
+					break;
+
+				case MP_TUNNELBRIDGE: /* Clear PBS reservation on tunnels/birdges */
+					if (GetTunnelBridgeTransportType(t) == TRANSPORT_RAIL) SetTunnelBridgeReservation(t, false);
+					break;
+
+				default: break;
+			}
+		}
+	}
+
+	/* Reserve all tracks trains are currently on. */
+	if (CheckSavegameVersion(101)) {
+		Vehicle *v;
+		FOR_ALL_VEHICLES(v) {
+			if (v->type == VEH_TRAIN) {
+				if ((v->u.rail.track & TRACK_BIT_WORMHOLE) == TRACK_BIT_WORMHOLE) {
+					TryReserveRailTrack(v->tile, DiagDirToDiagTrack(GetTunnelBridgeDirection(v->tile)));
+				} else if ((v->u.rail.track & TRACK_BIT_MASK) != TRACK_BIT_NONE) {
+					TryReserveRailTrack(v->tile, TrackBitsToTrack(v->u.rail.track));
+				}
+			}
+		}
+
+		/* Give owners to waypoints, based on rail tracks it is sitting on.
+		 * If none is available, specify OWNER_NONE */
+		Waypoint *wp;
+		FOR_ALL_WAYPOINTS(wp) {
+			Owner owner = (IsRailWaypointTile(wp->xy) ? GetTileOwner(wp->xy) : OWNER_NONE);
+			wp->owner = IsValidCompanyID(owner) ? owner : OWNER_NONE;
+		}
+	}
+
+	if (CheckSavegameVersion(102)) {
+		for (TileIndex t = 0; t < map_size; t++) {
+			/* Now all crossings should be in correct state */
+			if (IsLevelCrossingTile(t)) UpdateLevelCrossing(t, false);
+		}
+	}
+
+	if (CheckSavegameVersion(103)) {
+		/* Non-town-owned roads now store the closest town */
+		UpdateNearestTownForRoadTiles(false);
+
+		/* signs with invalid owner left from older savegames */
+		Sign *si;
+		FOR_ALL_SIGNS(si) {
+			if (si->owner != OWNER_NONE && !IsValidCompanyID(si->owner)) si->owner = OWNER_NONE;
+		}
+
+		/* Station can get named based on an industry type, but the current ones
+		 * are not, so mark them as if they are not named by an industry. */
+		Station *st;
+		FOR_ALL_STATIONS(st) {
+			st->indtype = IT_INVALID;
+		}
+	}
+
+	if (CheckSavegameVersion(104)) {
+		Vehicle *v;
+		FOR_ALL_VEHICLES(v) {
+			/* Set engine_type of shadow and rotor */
+			if (v->type == VEH_AIRCRAFT && !IsNormalAircraft(v)) {
+				v->engine_type = v->First()->engine_type;
+			}
+		}
+
+		/* More companies ... */
+		Company *c;
+		FOR_ALL_COMPANIES(c) {
+			if (c->bankrupt_asked == 0xFF) c->bankrupt_asked = 0xFFFF;
+		}
+
+		Engine *e;
+		FOR_ALL_ENGINES(e) {
+			if (e->company_avail == 0xFF) e->company_avail = 0xFFFF;
+		}
+
+		Town *t;
+		FOR_ALL_TOWNS(t) {
+			if (t->have_ratings == 0xFF) t->have_ratings = 0xFFFF;
+			for (uint i = 8; i != MAX_COMPANIES; i++) t->ratings[i] = RATING_INITIAL;
+		}
+	}
+
+	GamelogPrintDebug(1);
+
+	bool ret = InitializeWindowsAndCaches();
+	/* Restore the signals */
+	signal(SIGSEGV, prev_segfault);
+	signal(SIGABRT, prev_abort);
+	return ret;
+}
+
+/** Reload all NewGRF files during a running game. This is a cut-down
+ * version of AfterLoadGame().
+ * XXX - We need to reset the vehicle position hash because with a non-empty
+ * hash AfterLoadVehicles() will loop infinitely. We need AfterLoadVehicles()
+ * to recalculate vehicle data as some NewGRF vehicle sets could have been
+ * removed or added and changed statistics */
+void ReloadNewGRFData()
+{
+	/* reload grf data */
+	GfxLoadSprites();
+	LoadStringWidthTable();
+	ResetEconomy();
+	/* reload vehicles */
+	ResetVehiclePosHash();
+	AfterLoadVehicles(false);
+	StartupEngines();
+	SetCachedEngineCounts();
+	/* update station and waypoint graphics */
+	AfterLoadWaypoints();
+	AfterLoadStations();
+	/* Check and update house and town values */
+	UpdateHousesAndTowns();
+	/* Update livery selection windows */
+	for (CompanyID i = COMPANY_FIRST; i < MAX_COMPANIES; i++) InvalidateWindowData(WC_COMPANY_COLOR, i, _loaded_newgrf_features.has_2CC);
+	/* redraw the whole screen */
+	MarkWholeScreenDirty();
+	CheckTrainsLengths();
+}
new file mode 100644
--- /dev/null
+++ b/src/saveload/ai_sl.cpp
@@ -0,0 +1,79 @@
+/* $Id$ */
+
+/** @file ai_sl.cpp Code handling saving and loading of old AI + new AI initialisation after game load */
+
+#include "../stdafx.h"
+#include "../ai/ai.h"
+#include "../ai/default/default.h"
+
+#include "saveload.h"
+
+static const SaveLoad _company_ai_desc[] = {
+	    SLE_VAR(CompanyAI, state,             SLE_UINT8),
+	    SLE_VAR(CompanyAI, tick,              SLE_UINT8),
+	SLE_CONDVAR(CompanyAI, state_counter,     SLE_FILE_U16 | SLE_VAR_U32,  0, 12),
+	SLE_CONDVAR(CompanyAI, state_counter,     SLE_UINT32,                 13, SL_MAX_VERSION),
+	    SLE_VAR(CompanyAI, timeout_counter,   SLE_UINT16),
+
+	    SLE_VAR(CompanyAI, state_mode,        SLE_UINT8),
+	    SLE_VAR(CompanyAI, banned_tile_count, SLE_UINT8),
+	    SLE_VAR(CompanyAI, railtype_to_use,   SLE_UINT8),
+
+	    SLE_VAR(CompanyAI, cargo_type,        SLE_UINT8),
+	    SLE_VAR(CompanyAI, num_wagons,        SLE_UINT8),
+	    SLE_VAR(CompanyAI, build_kind,        SLE_UINT8),
+	    SLE_VAR(CompanyAI, num_build_rec,     SLE_UINT8),
+	    SLE_VAR(CompanyAI, num_loco_to_build, SLE_UINT8),
+	    SLE_VAR(CompanyAI, num_want_fullload, SLE_UINT8),
+
+	    SLE_VAR(CompanyAI, route_type_mask,   SLE_UINT8),
+
+	SLE_CONDVAR(CompanyAI, start_tile_a,      SLE_FILE_U16 | SLE_VAR_U32,  0,  5),
+	SLE_CONDVAR(CompanyAI, start_tile_a,      SLE_UINT32,                  6, SL_MAX_VERSION),
+	SLE_CONDVAR(CompanyAI, cur_tile_a,        SLE_FILE_U16 | SLE_VAR_U32,  0,  5),
+	SLE_CONDVAR(CompanyAI, cur_tile_a,        SLE_UINT32,                  6, SL_MAX_VERSION),
+	    SLE_VAR(CompanyAI, start_dir_a,       SLE_UINT8),
+	    SLE_VAR(CompanyAI, cur_dir_a,         SLE_UINT8),
+
+	SLE_CONDVAR(CompanyAI, start_tile_b,      SLE_FILE_U16 | SLE_VAR_U32,  0,  5),
+	SLE_CONDVAR(CompanyAI, start_tile_b,      SLE_UINT32,                  6, SL_MAX_VERSION),
+	SLE_CONDVAR(CompanyAI, cur_tile_b,        SLE_FILE_U16 | SLE_VAR_U32,  0,  5),
+	SLE_CONDVAR(CompanyAI, cur_tile_b,        SLE_UINT32,                  6, SL_MAX_VERSION),
+	    SLE_VAR(CompanyAI, start_dir_b,       SLE_UINT8),
+	    SLE_VAR(CompanyAI, cur_dir_b,         SLE_UINT8),
+
+	    SLE_REF(CompanyAI, cur_veh,           REF_VEHICLE),
+
+	    SLE_ARR(CompanyAI, wagon_list,        SLE_UINT16, 9),
+	    SLE_ARR(CompanyAI, order_list_blocks, SLE_UINT8, 20),
+	    SLE_ARR(CompanyAI, banned_tiles,      SLE_UINT16, 16),
+
+	SLE_CONDNULL(64, 2, SL_MAX_VERSION),
+	SLE_END()
+};
+
+static const SaveLoad _company_ai_build_rec_desc[] = {
+	SLE_CONDVAR(AiBuildRec, spec_tile,         SLE_FILE_U16 | SLE_VAR_U32, 0, 5),
+	SLE_CONDVAR(AiBuildRec, spec_tile,         SLE_UINT32,                 6, SL_MAX_VERSION),
+	SLE_CONDVAR(AiBuildRec, use_tile,          SLE_FILE_U16 | SLE_VAR_U32, 0, 5),
+	SLE_CONDVAR(AiBuildRec, use_tile,          SLE_UINT32,                 6, SL_MAX_VERSION),
+	    SLE_VAR(AiBuildRec, rand_rng,          SLE_UINT8),
+	    SLE_VAR(AiBuildRec, cur_building_rule, SLE_UINT8),
+	    SLE_VAR(AiBuildRec, unk6,              SLE_UINT8),
+	    SLE_VAR(AiBuildRec, unk7,              SLE_UINT8),
+	    SLE_VAR(AiBuildRec, buildcmd_a,        SLE_UINT8),
+	    SLE_VAR(AiBuildRec, buildcmd_b,        SLE_UINT8),
+	    SLE_VAR(AiBuildRec, direction,         SLE_UINT8),
+	    SLE_VAR(AiBuildRec, cargo,             SLE_UINT8),
+	SLE_END()
+};
+
+
+void SaveLoad_AI(CompanyID company)
+{
+	CompanyAI *cai = &_companies_ai[company];
+	SlObject(cai, _company_ai_desc);
+	for (int i = 0; i != cai->num_build_rec; i++) {
+		SlObject(&cai->src + i, _company_ai_build_rec_desc);
+	}
+}
new file mode 100644
--- /dev/null
+++ b/src/saveload/animated_tile_sl.cpp
@@ -0,0 +1,56 @@
+/* $Id$ */
+
+/** @file animated_tile_sl.cpp Code handling saving and loading of animated tiles */
+
+#include "../stdafx.h"
+#include "../tile_type.h"
+#include "../core/alloc_func.hpp"
+
+#include "saveload.h"
+
+extern TileIndex *_animated_tile_list;
+extern uint _animated_tile_count;
+extern uint _animated_tile_allocated;
+
+/**
+ * Save the ANIT chunk.
+ */
+static void Save_ANIT()
+{
+	SlSetLength(_animated_tile_count * sizeof(*_animated_tile_list));
+	SlArray(_animated_tile_list, _animated_tile_count, SLE_UINT32);
+}
+
+/**
+ * Load the ANIT chunk; the chunk containing the animated tiles.
+ */
+static void Load_ANIT()
+{
+	/* Before version 80 we did NOT have a variable length animated tile table */
+	if (CheckSavegameVersion(80)) {
+		/* In pre version 6, we has 16bit per tile, now we have 32bit per tile, convert it ;) */
+		SlArray(_animated_tile_list, 256, CheckSavegameVersion(6) ? (SLE_FILE_U16 | SLE_VAR_U32) : SLE_UINT32);
+
+		for (_animated_tile_count = 0; _animated_tile_count < 256; _animated_tile_count++) {
+			if (_animated_tile_list[_animated_tile_count] == 0) break;
+		}
+		return;
+	}
+
+	_animated_tile_count = (uint)SlGetFieldLength() / sizeof(*_animated_tile_list);
+
+	/* Determine a nice rounded size for the amount of allocated tiles */
+	_animated_tile_allocated = 256;
+	while (_animated_tile_allocated < _animated_tile_count) _animated_tile_allocated *= 2;
+
+	_animated_tile_list = ReallocT<TileIndex>(_animated_tile_list, _animated_tile_allocated);
+	SlArray(_animated_tile_list, _animated_tile_count, SLE_UINT32);
+}
+
+/**
+ * "Definition" imported by the saveload code to be able to load and save
+ * the animated tile table.
+ */
+extern const ChunkHandler _animated_tile_chunk_handlers[] = {
+	{ 'ANIT', Save_ANIT, Load_ANIT, CH_RIFF | CH_LAST},
+};
new file mode 100644
--- /dev/null
+++ b/src/saveload/autoreplace_sl.cpp
@@ -0,0 +1,51 @@
+/* $Id$ */
+
+/** @file autoreplace_sl.cpp Code handling saving and loading of autoreplace rules */
+
+#include "../stdafx.h"
+#include "../autoreplace_type.h"
+#include "../engine_type.h"
+#include "../group_type.h"
+#include "../autoreplace_base.h"
+
+#include "saveload.h"
+
+static const SaveLoad _engine_renew_desc[] = {
+	    SLE_VAR(EngineRenew, from,     SLE_UINT16),
+	    SLE_VAR(EngineRenew, to,       SLE_UINT16),
+
+	    SLE_REF(EngineRenew, next,     REF_ENGINE_RENEWS),
+	SLE_CONDVAR(EngineRenew, group_id, SLE_UINT16, 60, SL_MAX_VERSION),
+	SLE_END()
+};
+
+static void Save_ERNW()
+{
+	EngineRenew *er;
+
+	FOR_ALL_ENGINE_RENEWS(er) {
+		SlSetArrayIndex(er->index);
+		SlObject(er, _engine_renew_desc);
+	}
+}
+
+static void Load_ERNW()
+{
+	int index;
+
+	while ((index = SlIterateArray()) != -1) {
+		EngineRenew *er = new (index) EngineRenew();
+		SlObject(er, _engine_renew_desc);
+
+		/* Advanced vehicle lists, ungrouped vehicles got added */
+		if (CheckSavegameVersion(60)) {
+			er->group_id = ALL_GROUP;
+		} else if (CheckSavegameVersion(71)) {
+			if (er->group_id == DEFAULT_GROUP) er->group_id = ALL_GROUP;
+		}
+	}
+}
+
+extern const ChunkHandler _autoreplace_chunk_handlers[] = {
+	{ 'ERNW', Save_ERNW,     Load_ERNW,     CH_ARRAY | CH_LAST},
+};
new file mode 100644
--- /dev/null
+++ b/src/saveload/cargopacket_sl.cpp
@@ -0,0 +1,45 @@
+/* $Id$ */
+
+/** @file cargopacket_sl.cpp Code handling saving and loading of cargo packets */
+
+#include "../stdafx.h"
+#include "../openttd.h"
+#include "../cargopacket.h"
+
+#include "saveload.h"
+
+static const SaveLoad _cargopacket_desc[] = {
+	SLE_VAR(CargoPacket, source,          SLE_UINT16),
+	SLE_VAR(CargoPacket, source_xy,       SLE_UINT32),
+	SLE_VAR(CargoPacket, loaded_at_xy,    SLE_UINT32),
+	SLE_VAR(CargoPacket, count,           SLE_UINT16),
+	SLE_VAR(CargoPacket, days_in_transit, SLE_UINT8),
+	SLE_VAR(CargoPacket, feeder_share,    SLE_INT64),
+	SLE_VAR(CargoPacket, paid_for,        SLE_BOOL),
+
+	SLE_END()
+};
+
+static void Save_CAPA()
+{
+	CargoPacket *cp;
+
+	FOR_ALL_CARGOPACKETS(cp) {
+		SlSetArrayIndex(cp->index);
+		SlObject(cp, _cargopacket_desc);
+	}
+}
+
+static void Load_CAPA()
+{
+	int index;
+
+	while ((index = SlIterateArray()) != -1) {
+		CargoPacket *cp = new (index) CargoPacket();
+		SlObject(cp, _cargopacket_desc);
+	}
+}
+
+extern const ChunkHandler _cargopacket_chunk_handlers[] = {
+	{ 'CAPA', Save_CAPA, Load_CAPA, CH_ARRAY | CH_LAST},
+};
new file mode 100644
--- /dev/null
+++ b/src/saveload/cheat_sl.cpp
@@ -0,0 +1,37 @@
+/* $Id$ */
+
+/** @file cheat_sl.cpp Code handling saving and loading of cheats */
+
+#include "../stdafx.h"
+#include "../cheat_type.h"
+
+#include "saveload.h"
+
+static void Save_CHTS()
+{
+	/* Cannot use lengthof because _cheats is of type Cheats, not Cheat */
+	byte count = sizeof(_cheats) / sizeof(Cheat);
+	Cheat *cht = (Cheat*) &_cheats;
+	Cheat *cht_last = &cht[count];
+
+	SlSetLength(count * 2);
+	for (; cht != cht_last; cht++) {
+		SlWriteByte(cht->been_used);
+		SlWriteByte(cht->value);
+	}
+}
+
+static void Load_CHTS()
+{
+	Cheat *cht = (Cheat*)&_cheats;
+	size_t count = SlGetFieldLength() / 2;
+
+	for (uint i = 0; i < count; i++) {
+		cht[i].been_used = (SlReadByte() != 0);
+		cht[i].value     = (SlReadByte() != 0);
+	}
+}
+
+extern const ChunkHandler _cheat_chunk_handlers[] = {
+	{ 'CHTS', Save_CHTS,     Load_CHTS,     CH_RIFF | CH_LAST}
+};
new file mode 100644
--- /dev/null
+++ b/src/saveload/company_sl.cpp
@@ -0,0 +1,240 @@
+/* $Id$ */
+
+/** @file company_sl.cpp Code handling saving and loading of company data */
+
+#include "../stdafx.h"
+#include "../company_base.h"
+#include "../company_func.h"
+#include "../network/network.h"
+#include "../ai/ai.h"
+#include "../ai/trolly/trolly.h"
+#include "../company_manager_face.h"
+
+#include "saveload.h"
+
+/**
+ * Converts an old company manager's face format to the new company manager's face format
+ *
+ * Meaning of the bits in the old face (some bits are used in several times):
+ * - 4 and 5: chin
+ * - 6 to 9: eyebrows
+ * - 10 to 13: nose
+ * - 13 to 15: lips (also moustache for males)
+ * - 16 to 19: hair
+ * - 20 to 22: eye color
+ * - 20 to 27: tie, ear rings etc.
+ * - 28 to 30: glasses
+ * - 19, 26 and 27: race (bit 27 set and bit 19 equal to bit 26 = black, otherwise white)
+ * - 31: gender (0 = male, 1 = female)
+ *
+ * @param face the face in the old format
+ * @return the face in the new format
+ */
+CompanyManagerFace ConvertFromOldCompanyManagerFace(uint32 face)
+{
+	CompanyManagerFace cmf = 0;
+	GenderEthnicity ge = GE_WM;
+
+	if (HasBit(face, 31)) SetBit(ge, GENDER_FEMALE);
+	if (HasBit(face, 27) && (HasBit(face, 26) == HasBit(face, 19))) SetBit(ge, ETHNICITY_BLACK);
+
+	SetCompanyManagerFaceBits(cmf, CMFV_GEN_ETHN,    ge, ge);
+	SetCompanyManagerFaceBits(cmf, CMFV_HAS_GLASSES, ge, GB(face, 28, 3) <= 1);
+	SetCompanyManagerFaceBits(cmf, CMFV_EYE_COLOUR,  ge, HasBit(ge, ETHNICITY_BLACK) ? 0 : ClampU(GB(face, 20, 3), 5, 7) - 5);
+	SetCompanyManagerFaceBits(cmf, CMFV_CHIN,        ge, ScaleCompanyManagerFaceValue(CMFV_CHIN,     ge, GB(face,  4, 2)));
+	SetCompanyManagerFaceBits(cmf, CMFV_EYEBROWS,    ge, ScaleCompanyManagerFaceValue(CMFV_EYEBROWS, ge, GB(face,  6, 4)));
+	SetCompanyManagerFaceBits(cmf, CMFV_HAIR,        ge, ScaleCompanyManagerFaceValue(CMFV_HAIR,     ge, GB(face, 16, 4)));
+	SetCompanyManagerFaceBits(cmf, CMFV_JACKET,      ge, ScaleCompanyManagerFaceValue(CMFV_JACKET,   ge, GB(face, 20, 2)));
+	SetCompanyManagerFaceBits(cmf, CMFV_COLLAR,      ge, ScaleCompanyManagerFaceValue(CMFV_COLLAR,   ge, GB(face, 22, 2)));
+	SetCompanyManagerFaceBits(cmf, CMFV_GLASSES,     ge, GB(face, 28, 1));
+
+	uint lips = GB(face, 10, 4);
+	if (!HasBit(ge, GENDER_FEMALE) && lips < 4) {
+		SetCompanyManagerFaceBits(cmf, CMFV_HAS_MOUSTACHE, ge, true);
+		SetCompanyManagerFaceBits(cmf, CMFV_MOUSTACHE,     ge, max(lips, 1U) - 1);
+	} else {
+		if (!HasBit(ge, GENDER_FEMALE)) {
+			lips = lips * 15 / 16;
+			lips -= 3;
+			if (HasBit(ge, ETHNICITY_BLACK) && lips > 8) lips = 0;
+		} else {
+			lips = ScaleCompanyManagerFaceValue(CMFV_LIPS, ge, lips);
+		}
+		SetCompanyManagerFaceBits(cmf, CMFV_LIPS, ge, lips);
+
+		uint nose = GB(face, 13, 3);
+		if (ge == GE_WF) {
+			nose = (nose * 3 >> 3) * 3 >> 2; // There is 'hole' in the nose sprites for females
+		} else {
+			nose = ScaleCompanyManagerFaceValue(CMFV_NOSE, ge, nose);
+		}
+		SetCompanyManagerFaceBits(cmf, CMFV_NOSE, ge, nose);
+	}
+
+	uint tie_earring = GB(face, 24, 4);
+	if (!HasBit(ge, GENDER_FEMALE) || tie_earring < 3) { // Not all females have an earring
+		if (HasBit(ge, GENDER_FEMALE)) SetCompanyManagerFaceBits(cmf, CMFV_HAS_TIE_EARRING, ge, true);
+		SetCompanyManagerFaceBits(cmf, CMFV_TIE_EARRING, ge, HasBit(ge, GENDER_FEMALE) ? tie_earring : ScaleCompanyManagerFaceValue(CMFV_TIE_EARRING, ge, tie_earring / 2));
+	}
+
+	return cmf;
+}
+
+
+
+/* Save/load of companies */
+static const SaveLoad _company_desc[] = {
+	    SLE_VAR(Company, name_2,          SLE_UINT32),
+	    SLE_VAR(Company, name_1,          SLE_STRINGID),
+	SLE_CONDSTR(Company, name,            SLE_STR, 0,                       84, SL_MAX_VERSION),
+
+	    SLE_VAR(Company, president_name_1, SLE_UINT16),
+	    SLE_VAR(Company, president_name_2, SLE_UINT32),
+	SLE_CONDSTR(Company, president_name,  SLE_STR, 0,                       84, SL_MAX_VERSION),
+
+	    SLE_VAR(Company, face,            SLE_UINT32),
+
+	/* money was changed to a 64 bit field in savegame version 1. */
+	SLE_CONDVAR(Company, money,                 SLE_VAR_I64 | SLE_FILE_I32,  0, 0),
+	SLE_CONDVAR(Company, money,                 SLE_INT64,                   1, SL_MAX_VERSION),
+
+	SLE_CONDVAR(Company, current_loan,          SLE_VAR_I64 | SLE_FILE_I32,  0, 64),
+	SLE_CONDVAR(Company, current_loan,          SLE_INT64,                  65, SL_MAX_VERSION),
+
+	    SLE_VAR(Company, colour,                SLE_UINT8),
+	    SLE_VAR(Company, money_fraction,        SLE_UINT8),
+	SLE_CONDVAR(Company, avail_railtypes,       SLE_UINT8,                   0, 57),
+	    SLE_VAR(Company, block_preview,         SLE_UINT8),
+
+	SLE_CONDVAR(Company, cargo_types,           SLE_FILE_U16 | SLE_VAR_U32,  0, 93),
+	SLE_CONDVAR(Company, cargo_types,           SLE_UINT32,                 94, SL_MAX_VERSION),
+	SLE_CONDVAR(Company, location_of_HQ,        SLE_FILE_U16 | SLE_VAR_U32,  0,  5),
+	SLE_CONDVAR(Company, location_of_HQ,        SLE_UINT32,                  6, SL_MAX_VERSION),
+	SLE_CONDVAR(Company, last_build_coordinate, SLE_FILE_U16 | SLE_VAR_U32,  0,  5),
+	SLE_CONDVAR(Company, last_build_coordinate, SLE_UINT32,                  6, SL_MAX_VERSION),
+	SLE_CONDVAR(Company, inaugurated_year,      SLE_FILE_U8  | SLE_VAR_I32,  0, 30),
+	SLE_CONDVAR(Company, inaugurated_year,      SLE_INT32,                  31, SL_MAX_VERSION),
+
+	    SLE_ARR(Company, share_owners,          SLE_UINT8, 4),
+
+	    SLE_VAR(Company, num_valid_stat_ent,    SLE_UINT8),
+
+	    SLE_VAR(Company, quarters_of_bankrupcy, SLE_UINT8),
+	SLE_CONDVAR(Company, bankrupt_asked,        SLE_FILE_U8  | SLE_VAR_U16,  0, 103),
+	SLE_CONDVAR(Company, bankrupt_asked,        SLE_UINT16,                104, SL_MAX_VERSION),
+	    SLE_VAR(Company, bankrupt_timeout,      SLE_INT16),
+	SLE_CONDVAR(Company, bankrupt_value,        SLE_VAR_I64 | SLE_FILE_I32,  0, 64),
+	SLE_CONDVAR(Company, bankrupt_value,        SLE_INT64,                  65, SL_MAX_VERSION),
+
+	/* yearly expenses was changed to 64-bit in savegame version 2. */
+	SLE_CONDARR(Company, yearly_expenses,       SLE_FILE_I32 | SLE_VAR_I64, 3 * 13, 0, 1),
+	SLE_CONDARR(Company, yearly_expenses,       SLE_INT64, 3 * 13,                  2, SL_MAX_VERSION),
+
+	SLE_CONDVAR(Company, is_ai,                 SLE_BOOL, 2, SL_MAX_VERSION),
+	SLE_CONDNULL(1, 4, 99),
+
+	/* Engine renewal settings */
+	SLE_CONDNULL(512, 16, 18),
+	SLE_CONDREF(Company, engine_renew_list,     REF_ENGINE_RENEWS,          19, SL_MAX_VERSION),
+	SLE_CONDVAR(Company, engine_renew,          SLE_BOOL,                   16, SL_MAX_VERSION),
+	SLE_CONDVAR(Company, engine_renew_months,   SLE_INT16,                  16, SL_MAX_VERSION),
+	SLE_CONDVAR(Company, engine_renew_money,    SLE_UINT32,                 16, SL_MAX_VERSION),
+	SLE_CONDVAR(Company, renew_keep_length,     SLE_BOOL,                    2, SL_MAX_VERSION), // added with 16.1, but was blank since 2
+
+	/* reserve extra space in savegame here. (currently 63 bytes) */
+	SLE_CONDNULL(63, 2, SL_MAX_VERSION),
+
+	SLE_END()
+};
+
+static const SaveLoad _company_economy_desc[] = {
+	/* these were changed to 64-bit in savegame format 2 */
+	SLE_CONDVAR(CompanyEconomyEntry, income,              SLE_FILE_I32 | SLE_VAR_I64, 0, 1),
+	SLE_CONDVAR(CompanyEconomyEntry, income,              SLE_INT64,                  2, SL_MAX_VERSION),
+	SLE_CONDVAR(CompanyEconomyEntry, expenses,            SLE_FILE_I32 | SLE_VAR_I64, 0, 1),
+	SLE_CONDVAR(CompanyEconomyEntry, expenses,            SLE_INT64,                  2, SL_MAX_VERSION),
+	SLE_CONDVAR(CompanyEconomyEntry, company_value,       SLE_FILE_I32 | SLE_VAR_I64, 0, 1),
+	SLE_CONDVAR(CompanyEconomyEntry, company_value,       SLE_INT64,                  2, SL_MAX_VERSION),
+
+	    SLE_VAR(CompanyEconomyEntry, delivered_cargo,     SLE_INT32),
+	    SLE_VAR(CompanyEconomyEntry, performance_history, SLE_INT32),
+
+	SLE_END()
+};
+
+static const SaveLoad _company_livery_desc[] = {
+	SLE_CONDVAR(Livery, in_use,  SLE_BOOL,  34, SL_MAX_VERSION),
+	SLE_CONDVAR(Livery, colour1, SLE_UINT8, 34, SL_MAX_VERSION),
+	SLE_CONDVAR(Livery, colour2, SLE_UINT8, 34, SL_MAX_VERSION),
+	SLE_END()
+};
+
+static void SaveLoad_PLYR(Company *c)
+{
+	int i;
+
+	SlObject(c, _company_desc);
+
+	/* Write AI? */
+	if (!IsHumanCompany(c->index)) {
+		extern void SaveLoad_AI(CompanyID company);
+		SaveLoad_AI(c->index);
+	}
+
+	/* Write economy */
+	SlObject(&c->cur_economy, _company_economy_desc);
+
+	/* Write old economy entries. */
+	for (i = 0; i < c->num_valid_stat_ent; i++) {
+		SlObject(&c->old_economy[i], _company_economy_desc);
+	}
+
+	/* Write each livery entry. */
+	int num_liveries = CheckSavegameVersion(63) ? LS_END - 4 : (CheckSavegameVersion(85) ? LS_END - 2: LS_END);
+	for (i = 0; i < num_liveries; i++) {
+		SlObject(&c->livery[i], _company_livery_desc);
+	}
+
+	if (num_liveries < LS_END) {
+		/* We want to insert some liveries somewhere in between. This means some have to be moved. */
+		memmove(&c->livery[LS_FREIGHT_WAGON], &c->livery[LS_PASSENGER_WAGON_MONORAIL], (LS_END - LS_FREIGHT_WAGON) * sizeof(c->livery[0]));
+		c->livery[LS_PASSENGER_WAGON_MONORAIL] = c->livery[LS_MONORAIL];
+		c->livery[LS_PASSENGER_WAGON_MAGLEV]   = c->livery[LS_MAGLEV];
+	}
+
+	if (num_liveries == LS_END - 4) {
+		/* Copy bus/truck liveries over to trams */
+		c->livery[LS_PASSENGER_TRAM] = c->livery[LS_BUS];
+		c->livery[LS_FREIGHT_TRAM]   = c->livery[LS_TRUCK];
+	}
+}
+
+static void Save_PLYR()
+{
+	Company *c;
+	FOR_ALL_COMPANIES(c) {
+		SlSetArrayIndex(c->index);
+		SlAutolength((AutolengthProc*)SaveLoad_PLYR, c);
+	}
+}
+
+static void Load_PLYR()
+{
+	int index;
+	while ((index = SlIterateArray()) != -1) {
+		Company *c = new (index) Company();
+		SaveLoad_PLYR(c);
+		_company_colours[index] = c->colour;
+
+		/* This is needed so an AI is attached to a loaded AI */
+		if (c->is_ai && (!_networking || _network_server) && _ai.enabled) {
+			/* Clear the memory of the new AI, otherwise we might be doing wrong things. */
+			memset(&_companies_ainew[index], 0, sizeof(CompanyAiNew));
+			AI_StartNewAI(c->index);
+		}
+	}
+}
+
+extern const ChunkHandler _company_chunk_handlers[] = {
+	{ 'PLYR', Save_PLYR, Load_PLYR, CH_ARRAY | CH_LAST},
+};
new file mode 100644
--- /dev/null
+++ b/src/saveload/depot_sl.cpp
@@ -0,0 +1,39 @@
+/* $Id$ */
+
+/** @file depot_sl.cpp Code handling saving and loading of depots */
+
+#include "../stdafx.h"
+#include "../depot_base.h"
+
+#include "saveload.h"
+
+static const SaveLoad _depot_desc[] = {
+	SLE_CONDVAR(Depot, xy,         SLE_FILE_U16 | SLE_VAR_U32, 0, 5),
+	SLE_CONDVAR(Depot, xy,         SLE_UINT32,                 6, SL_MAX_VERSION),
+	    SLE_VAR(Depot, town_index, SLE_UINT16),
+	SLE_END()
+};
+
+static void Save_DEPT()
+{
+	Depot *depot;
+
+	FOR_ALL_DEPOTS(depot) {
+		SlSetArrayIndex(depot->index);
+		SlObject(depot, _depot_desc);
+	}
+}
+
+static void Load_DEPT()
+{
+	int index;
+
+	while ((index = SlIterateArray()) != -1) {
+		Depot *depot = new (index) Depot();
+		SlObject(depot, _depot_desc);
+	}
+}
+
+extern const ChunkHandler _depot_chunk_handlers[] = {
+	{ 'DEPT', Save_DEPT, Load_DEPT, CH_ARRAY | CH_LAST},
+};
new file mode 100644
--- /dev/null
+++ b/src/saveload/economy_sl.cpp
@@ -0,0 +1,58 @@
+/* $Id$ */
+
+/** @file economy_sl.cpp Code handling saving and loading of economy data */
+
+#include "../stdafx.h"
+#include "../economy_func.h"
+
+#include "saveload.h"
+
+/** Prices */
+static void SaveLoad_PRIC()
+{
+	int vt = CheckSavegameVersion(65) ? (SLE_FILE_I32 | SLE_VAR_I64) : SLE_INT64;
+	SlArray(&_price,      NUM_PRICES, vt);
+	SlArray(&_price_frac, NUM_PRICES, SLE_UINT16);
+}
+
+/** Cargo payment rates */
+static void SaveLoad_CAPR()
+{
+	uint num_cargo = CheckSavegameVersion(55) ? 12 : NUM_CARGO;
+	int vt = CheckSavegameVersion(65) ? (SLE_FILE_I32 | SLE_VAR_I64) : SLE_INT64;
+	SlArray(&_cargo_payment_rates,      num_cargo, vt);
+	SlArray(&_cargo_payment_rates_frac, num_cargo, SLE_UINT16);
+}
+
+static const SaveLoad _economy_desc[] = {
+	SLE_CONDVAR(Economy, max_loan,                      SLE_FILE_I32 | SLE_VAR_I64,  0, 64),
+	SLE_CONDVAR(Economy, max_loan,                      SLE_INT64,                  65, SL_MAX_VERSION),
+	SLE_CONDVAR(Economy, max_loan_unround,              SLE_FILE_I32 | SLE_VAR_I64,  0, 64),
+	SLE_CONDVAR(Economy, max_loan_unround,              SLE_INT64,                  65, SL_MAX_VERSION),
+	SLE_CONDVAR(Economy, max_loan_unround_fract,        SLE_UINT16,                 70, SL_MAX_VERSION),
+	    SLE_VAR(Economy, fluct,                         SLE_INT16),
+	    SLE_VAR(Economy, interest_rate,                 SLE_UINT8),
+	    SLE_VAR(Economy, infl_amount,                   SLE_UINT8),
+	    SLE_VAR(Economy, infl_amount_pr,                SLE_UINT8),
+	SLE_CONDVAR(Economy, industry_daily_change_counter, SLE_UINT32,                102, SL_MAX_VERSION),
+	    SLE_END()
+};
+
+/** Economy variables */
+static void Save_ECMY()
+{
+	SlObject(&_economy, _economy_desc);
+}
+
+/** Economy variables */
+static void Load_ECMY()
+{
+	SlObject(&_economy, _economy_desc);
+	StartupIndustryDailyChanges(CheckSavegameVersion(102));  // old savegames will need to be initialized
+}
+
+extern const ChunkHandler _economy_chunk_handlers[] = {
+	{ 'PRIC', SaveLoad_PRIC, SaveLoad_PRIC, CH_RIFF | CH_AUTO_LENGTH},
+	{ 'CAPR', SaveLoad_CAPR, SaveLoad_CAPR, CH_RIFF | CH_AUTO_LENGTH},
+	{ 'ECMY', Save_ECMY,     Load_ECMY,     CH_RIFF | CH_LAST},
+};
new file mode 100644
--- /dev/null
+++ b/src/saveload/engine_sl.cpp
@@ -0,0 +1,118 @@
+/* $Id$ */
+
+/** @file engine_sl.cpp Code handling saving and loading of engines */
+
+#include "../stdafx.h"
+#include "saveload.h"
+#include "saveload_internal.h"
+#include "../engine_base.h"
+#include <map>
+
+static const SaveLoad _engine_desc[] = {
+	SLE_CONDVAR(Engine, intro_date,          SLE_FILE_U16 | SLE_VAR_I32,  0,  30),
+	SLE_CONDVAR(Engine, intro_date,          SLE_INT32,                  31, SL_MAX_VERSION),
+	SLE_CONDVAR(Engine, age,                 SLE_FILE_U16 | SLE_VAR_I32,  0,  30),
+	SLE_CONDVAR(Engine, age,                 SLE_INT32,                  31, SL_MAX_VERSION),
+	    SLE_VAR(Engine, reliability,         SLE_UINT16),
+	    SLE_VAR(Engine, reliability_spd_dec, SLE_UINT16),
+	    SLE_VAR(Engine, reliability_start,   SLE_UINT16),
+	    SLE_VAR(Engine, reliability_max,     SLE_UINT16),
+	    SLE_VAR(Engine, reliability_final,   SLE_UINT16),
+	    SLE_VAR(Engine, duration_phase_1,    SLE_UINT16),
+	    SLE_VAR(Engine, duration_phase_2,    SLE_UINT16),
+	    SLE_VAR(Engine, duration_phase_3,    SLE_UINT16),
+
+	    SLE_VAR(Engine, lifelength,          SLE_UINT8),
+	    SLE_VAR(Engine, flags,               SLE_UINT8),
+	    SLE_VAR(Engine, preview_company_rank,SLE_UINT8),
+	    SLE_VAR(Engine, preview_wait,        SLE_UINT8),
+	SLE_CONDNULL(1, 0, 44),
+	SLE_CONDVAR(Engine, company_avail,       SLE_FILE_U8  | SLE_VAR_U16,  0, 103),
+	SLE_CONDVAR(Engine, company_avail,       SLE_UINT16,                104, SL_MAX_VERSION),
+	SLE_CONDSTR(Engine, name,                SLE_STR, 0,                 84, SL_MAX_VERSION),
+
+	/* reserve extra space in savegame here. (currently 16 bytes) */
+	SLE_CONDNULL(16, 2, SL_MAX_VERSION),
+
+	SLE_END()
+};
+
+static std::map<EngineID, Engine> _temp_engine;
+
+Engine *GetTempDataEngine(EngineID index)
+{
+	return &_temp_engine[index];
+}
+
+static void Save_ENGN()
+{
+	Engine *e;
+	FOR_ALL_ENGINES(e) {
+		SlSetArrayIndex(e->index);
+		SlObject(e, _engine_desc);
+	}
+}
+
+static void Load_ENGN()
+{
+	/* As engine data is loaded before engines are initialized we need to load
+	 * this information into a temporary array. This is then copied into the
+	 * engine pool after processing NewGRFs by CopyTempEngineData(). */
+	int index;
+	while ((index = SlIterateArray()) != -1) {
+		Engine *e = GetTempDataEngine(index);
+		SlObject(e, _engine_desc);
+	}
+}
+
+/**
+ * Copy data from temporary engine array into the real engine pool.
+ */
+void CopyTempEngineData()
+{
+	Engine *e;
+	FOR_ALL_ENGINES(e) {
+		if (e->index >= _temp_engine.size()) break;
+
+		const Engine *se = GetTempDataEngine(e->index);
+		e->intro_date          = se->intro_date;
+		e->age                 = se->age;
+		e->reliability         = se->reliability;
+		e->reliability_spd_dec = se->reliability_spd_dec;
+		e->reliability_start   = se->reliability_start;
+		e->reliability_max     = se->reliability_max;
+		e->reliability_final   = se->reliability_final;
+		e->duration_phase_1    = se->duration_phase_1;
+		e->duration_phase_2    = se->duration_phase_2;
+		e->duration_phase_3    = se->duration_phase_3;
+		e->lifelength          = se->lifelength;
+		e->flags               = se->flags;
+		e->preview_company_rank= se->preview_company_rank;
+		e->preview_wait        = se->preview_wait;
+		e->company_avail       = se->company_avail;
+		if (se->name != NULL) e->name = strdup(se->name);
+	}
+
+	/* Get rid of temporary data */
+	_temp_engine.clear();
+}
+
+static void Load_ENGS()
+{
+	/* Load old separate String ID list into a temporary array. This
+	 * was always 256 entries. */
+	StringID names[256];
+
+	SlArray(names, lengthof(names), SLE_STRINGID);
+
+	/* Copy each string into the temporary engine array. */
+	for (EngineID engine = 0; engine < lengthof(names); engine++) {
+		Engine *e = GetTempDataEngine(engine);
+		e->name = CopyFromOldName(names[engine]);
+	}
+}
+
+extern const ChunkHandler _engine_chunk_handlers[] = {
+	{ 'ENGN', Save_ENGN,     Load_ENGN,     CH_ARRAY          },
+	{ 'ENGS', NULL,          Load_ENGS,     CH_RIFF | CH_LAST },
+};
new file mode 100644
--- /dev/null
+++ b/src/saveload/gamelog_sl.cpp
@@ -0,0 +1,161 @@
+/* $Id$ */
+
+/** @file gamelog_sl.cpp Code handling saving and loading of gamelog data */
+
+#include "../stdafx.h"
+#include "../gamelog.h"
+#include "../gamelog_internal.h"
+#include "../core/alloc_func.hpp"
+
+#include "saveload.h"
+
+static const SaveLoad _glog_action_desc[] = {
+	SLE_VAR(LoggedAction, tick,              SLE_UINT16),
+	SLE_END()
+};
+
+static const SaveLoad _glog_mode_desc[] = {
+	SLE_VAR(LoggedChange, mode.mode,         SLE_UINT8),
+	SLE_VAR(LoggedChange, mode.landscape,    SLE_UINT8),
+	SLE_END()
+};
+
+static const SaveLoad _glog_revision_desc[] = {
+	SLE_ARR(LoggedChange, revision.text,     SLE_UINT8,  NETWORK_REVISION_LENGTH),
+	SLE_VAR(LoggedChange, revision.newgrf,   SLE_UINT32),
+	SLE_VAR(LoggedChange, revision.slver,    SLE_UINT16),
+	SLE_VAR(LoggedChange, revision.modified, SLE_UINT8),
+	SLE_END()
+};
+
+static const SaveLoad _glog_oldver_desc[] = {
+	SLE_VAR(LoggedChange, oldver.type,       SLE_UINT32),
+	SLE_VAR(LoggedChange, oldver.version,    SLE_UINT32),
+	SLE_END()
+};
+
+static const SaveLoad _glog_patch_desc[] = {
+	SLE_STR(LoggedChange, patch.name,        SLE_STR,    128),
+	SLE_VAR(LoggedChange, patch.oldval,      SLE_INT32),
+	SLE_VAR(LoggedChange, patch.newval,      SLE_INT32),
+	SLE_END()
+};
+
+static const SaveLoad _glog_grfadd_desc[] = {
+	SLE_VAR(LoggedChange, grfadd.grfid,      SLE_UINT32    ),
+	SLE_ARR(LoggedChange, grfadd.md5sum,     SLE_UINT8,  16),
+	SLE_END()
+};
+
+static const SaveLoad _glog_grfrem_desc[] = {
+	SLE_VAR(LoggedChange, grfrem.grfid,      SLE_UINT32),
+	SLE_END()
+};
+
+static const SaveLoad _glog_grfcompat_desc[] = {
+	SLE_VAR(LoggedChange, grfcompat.grfid,   SLE_UINT32    ),
+	SLE_ARR(LoggedChange, grfcompat.md5sum,  SLE_UINT8,  16),
+	SLE_END()
+};
+
+static const SaveLoad _glog_grfparam_desc[] = {
+	SLE_VAR(LoggedChange, grfparam.grfid,    SLE_UINT32),
+	SLE_END()
+};
+
+static const SaveLoad _glog_grfmove_desc[] = {
+	SLE_VAR(LoggedChange, grfmove.grfid,     SLE_UINT32),
+	SLE_VAR(LoggedChange, grfmove.offset,    SLE_INT32),
+	SLE_END()
+};
+
+static const SaveLoad _glog_grfbug_desc[] = {
+	SLE_VAR(LoggedChange, grfbug.data,       SLE_UINT64),
+	SLE_VAR(LoggedChange, grfbug.grfid,      SLE_UINT32),
+	SLE_VAR(LoggedChange, grfbug.bug,        SLE_UINT8),
+	SLE_END()
+};
+
+static const SaveLoad *_glog_desc[] = {
+	_glog_mode_desc,
+	_glog_revision_desc,
+	_glog_oldver_desc,
+	_glog_patch_desc,
+	_glog_grfadd_desc,
+	_glog_grfrem_desc,
+	_glog_grfcompat_desc,
+	_glog_grfparam_desc,
+	_glog_grfmove_desc,
+	_glog_grfbug_desc,
+};
+
+assert_compile(lengthof(_glog_desc) == GLCT_END);
+
+static void Load_GLOG()
+{
+	assert(_gamelog_action == NULL);
+	assert(_gamelog_actions == 0);
+
+	GamelogActionType at;
+	while ((at = (GamelogActionType)SlReadByte()) != GLAT_NONE) {
+		_gamelog_action = ReallocT(_gamelog_action, _gamelog_actions + 1);
+		LoggedAction *la = &_gamelog_action[_gamelog_actions++];
+
+		la->at = at;
+
+		SlObject(la, _glog_action_desc); // has to be saved after 'DATE'!
+		la->change = NULL;
+		la->changes = 0;
+
+		GamelogChangeType ct;
+		while ((ct = (GamelogChangeType)SlReadByte()) != GLCT_NONE) {
+			la->change = ReallocT(la->change, la->changes + 1);
+
+			LoggedChange *lc = &la->change[la->changes++];
+			/* for SLE_STR, pointer has to be valid! so make it NULL */
+			memset(lc, 0, sizeof(*lc));
+			lc->ct = ct;
+
+			assert((uint)ct < GLCT_END);
+
+			SlObject(lc, _glog_desc[ct]);
+		}
+	}
+}
+
+static void Save_GLOG()
+{
+	const LoggedAction *laend = &_gamelog_action[_gamelog_actions];
+	size_t length = 0;
+
+	for (const LoggedAction *la = _gamelog_action; la != laend; la++) {
+		const LoggedChange *lcend = &la->change[la->changes];
+		for (LoggedChange *lc = la->change; lc != lcend; lc++) {
+			assert((uint)lc->ct < lengthof(_glog_desc));
+			length += SlCalcObjLength(lc, _glog_desc[lc->ct]) + 1;
+		}
+		length += 4;
+	}
+	length++;
+
+	SlSetLength(length);
+
+	for (LoggedAction *la = _gamelog_action; la != laend; la++) {
+		SlWriteByte(la->at);
+		SlObject(la, _glog_action_desc);
+
+		const LoggedChange *lcend = &la->change[la->changes];
+		for (LoggedChange *lc = la->change; lc != lcend; lc++) {
+			SlWriteByte(lc->ct);
+			assert((uint)lc->ct < GLCT_END);
+			SlObject(lc, _glog_desc[lc->ct]);
+		}
+		SlWriteByte(GLCT_NONE);
+	}
+	SlWriteByte(GLAT_NONE);
+}
+
+
+extern const ChunkHandler _gamelog_chunk_handlers[] = {
+	{ 'GLOG', Save_GLOG, Load_GLOG, CH_RIFF | CH_LAST }
+};
new file mode 100644
--- /dev/null
+++ b/src/saveload/group_sl.cpp
@@ -0,0 +1,43 @@
+/* $Id$ */
+
+/** @file group_sl.cpp Code handling saving and loading of economy data */
+
+#include "../stdafx.h"
+#include "../group.h"
+
+#include "saveload.h"
+
+static const SaveLoad _group_desc[] = {
+  SLE_CONDVAR(Group, name,           SLE_NAME,    0, 83),
+  SLE_CONDSTR(Group, name,           SLE_STR, 0, 84, SL_MAX_VERSION),
+  SLE_VAR(Group, num_vehicle,        SLE_UINT16),
+  SLE_VAR(Group, owner,              SLE_UINT8),
+  SLE_VAR(Group, vehicle_type,       SLE_UINT8),
+  SLE_VAR(Group, replace_protection, SLE_BOOL),
+  SLE_END()
+};
+
+static void Save_GRPS(void)
+{
+	Group *g;
+
+	FOR_ALL_GROUPS(g) {
+		SlSetArrayIndex(g->index);
+		SlObject(g, _group_desc);
+	}
+}
+
+
+static void Load_GRPS(void)
+{
+	int index;
+
+	while ((index = SlIterateArray()) != -1) {
+		Group *g = new (index) Group();
+		SlObject(g, _group_desc);
+	}
+}
+
+extern const ChunkHandler _group_chunk_handlers[] = {
+	{ 'GRPS', Save_GRPS, Load_GRPS, CH_ARRAY | CH_LAST},
+};
new file mode 100644
--- /dev/null
+++ b/src/saveload/industry_sl.cpp
@@ -0,0 +1,155 @@
+/* $Id$ */
+
+/** @file industry_sl.cpp Code handling saving and loading of industries */
+
+#include "../stdafx.h"
+#include "../tile_type.h"
+#include "../strings_type.h"
+#include "../company_type.h"
+#include "../industry.h"
+#include "../newgrf_commons.h"
+
+#include "saveload.h"
+
+static const SaveLoad _industry_desc[] = {
+	SLE_CONDVAR(Industry, xy,                         SLE_FILE_U16 | SLE_VAR_U32,  0, 5),
+	SLE_CONDVAR(Industry, xy,                         SLE_UINT32,                  6, SL_MAX_VERSION),
+	    SLE_VAR(Industry, width,                      SLE_UINT8),
+	    SLE_VAR(Industry, height,                     SLE_UINT8),
+	    SLE_REF(Industry, town,                       REF_TOWN),
+	SLE_CONDNULL( 2, 0, 60),       ///< used to be industry's produced_cargo
+	SLE_CONDARR(Industry, produced_cargo,             SLE_UINT8,  2,              78, SL_MAX_VERSION),
+	SLE_CONDARR(Industry, incoming_cargo_waiting,     SLE_UINT16, 3,              70, SL_MAX_VERSION),
+	    SLE_ARR(Industry, produced_cargo_waiting,     SLE_UINT16, 2),
+	    SLE_ARR(Industry, production_rate,            SLE_UINT8,  2),
+	SLE_CONDNULL( 3, 0, 60),       ///< used to be industry's accepts_cargo
+	SLE_CONDARR(Industry, accepts_cargo,              SLE_UINT8,  3,              78, SL_MAX_VERSION),
+	    SLE_VAR(Industry, prod_level,                 SLE_UINT8),
+	    SLE_ARR(Industry, this_month_production,      SLE_UINT16, 2),
+	    SLE_ARR(Industry, this_month_transported,     SLE_UINT16, 2),
+	    SLE_ARR(Industry, last_month_pct_transported, SLE_UINT8,  2),
+	    SLE_ARR(Industry, last_month_production,      SLE_UINT16, 2),
+	    SLE_ARR(Industry, last_month_transported,     SLE_UINT16, 2),
+
+	    SLE_VAR(Industry, counter,                    SLE_UINT16),
+
+	    SLE_VAR(Industry, type,                       SLE_UINT8),
+	    SLE_VAR(Industry, owner,                      SLE_UINT8),
+	    SLE_VAR(Industry, random_color,               SLE_UINT8),
+	SLE_CONDVAR(Industry, last_prod_year,             SLE_FILE_U8 | SLE_VAR_I32,  0, 30),
+	SLE_CONDVAR(Industry, last_prod_year,             SLE_INT32,                 31, SL_MAX_VERSION),
+	    SLE_VAR(Industry, was_cargo_delivered,        SLE_UINT8),
+
+	SLE_CONDVAR(Industry, founder,                    SLE_UINT8,                 70, SL_MAX_VERSION),
+	SLE_CONDVAR(Industry, construction_date,          SLE_INT32,                 70, SL_MAX_VERSION),
+	SLE_CONDVAR(Industry, construction_type,          SLE_UINT8,                 70, SL_MAX_VERSION),
+	SLE_CONDVAR(Industry, last_cargo_accepted_at,     SLE_INT32,                 70, SL_MAX_VERSION),
+	SLE_CONDVAR(Industry, selected_layout,            SLE_UINT8,                 73, SL_MAX_VERSION),
+
+	SLE_CONDARRX(cpp_offsetof(Industry, psa) + cpp_offsetof(Industry::PersistentStorage, storage), SLE_UINT32, 16, 76, SL_MAX_VERSION),
+
+	SLE_CONDVAR(Industry, random_triggers,            SLE_UINT8,                 82, SL_MAX_VERSION),
+	SLE_CONDVAR(Industry, random,                     SLE_UINT16,                82, SL_MAX_VERSION),
+
+	/* reserve extra space in savegame here. (currently 32 bytes) */
+	SLE_CONDNULL(32, 2, SL_MAX_VERSION),
+
+	SLE_END()
+};
+
+static void Save_INDY()
+{
+	Industry *ind;
+
+	/* Write the industries */
+	FOR_ALL_INDUSTRIES(ind) {
+		SlSetArrayIndex(ind->index);
+		SlObject(ind, _industry_desc);
+	}
+}
+
+/* Save and load the mapping between the industry/tile id on the map, and the grf file
+ * it came from. */
+static const SaveLoad _industries_id_mapping_desc[] = {
+	SLE_VAR(EntityIDMapping, grfid,         SLE_UINT32),
+	SLE_VAR(EntityIDMapping, entity_id,     SLE_UINT8),
+	SLE_VAR(EntityIDMapping, substitute_id, SLE_UINT8),
+	SLE_END()
+};
+
+static void Save_IIDS()
+{
+	uint i;
+	uint j = _industry_mngr.GetMaxMapping();
+
+	for (i = 0; i < j; i++) {
+		SlSetArrayIndex(i);
+		SlObject(&_industry_mngr.mapping_ID[i], _industries_id_mapping_desc);
+	}
+}
+
+static void Save_TIDS()
+{
+	uint i;
+	uint j = _industile_mngr.GetMaxMapping();
+
+	for (i = 0; i < j; i++) {
+		SlSetArrayIndex(i);
+		SlObject(&_industile_mngr.mapping_ID[i], _industries_id_mapping_desc);
+	}
+}
+
+static void Load_INDY()
+{
+	int index;
+
+	ResetIndustryCounts();
+
+	while ((index = SlIterateArray()) != -1) {
+		Industry *i = new (index) Industry();
+		SlObject(i, _industry_desc);
+		IncIndustryTypeCount(i->type);
+	}
+}
+
+static void Load_IIDS()
+{
+	int index;
+	uint max_id;
+
+	/* clear the current mapping stored.
+	 * This will create the manager if ever it is not yet done */
+	_industry_mngr.ResetMapping();
+
+	/* get boundary for the temporary map loader NUM_INDUSTRYTYPES? */
+	max_id = _industry_mngr.GetMaxMapping();
+
+	while ((index = SlIterateArray()) != -1) {
+		if ((uint)index >= max_id) break;
+		SlObject(&_industry_mngr.mapping_ID[index], _industries_id_mapping_desc);
+	}
+}
+
+static void Load_TIDS()
+{
+	int index;
+	uint max_id;
+
+	/* clear the current mapping stored.
+	 * This will create the manager if ever it is not yet done */
+	_industile_mngr.ResetMapping();
+
+	/* get boundary for the temporary map loader NUM_INDUSTILES? */
+	max_id = _industile_mngr.GetMaxMapping();
+
+	while ((index = SlIterateArray()) != -1) {
+		if ((uint)index >= max_id) break;
+		SlObject(&_industile_mngr.mapping_ID[index], _industries_id_mapping_desc);
+	}
+}
+
+extern const ChunkHandler _industry_chunk_handlers[] = {
+	{ 'INDY', Save_INDY, Load_INDY, CH_ARRAY},
+	{ 'IIDS', Save_IIDS, Load_IIDS, CH_ARRAY},
+	{ 'TIDS', Save_TIDS, Load_TIDS, CH_ARRAY | CH_LAST},
+};
new file mode 100644
--- /dev/null
+++ b/src/saveload/map_sl.cpp
@@ -0,0 +1,249 @@
+/* $Id$ */
+
+/** @file map_sl.cpp Code handling saving and loading of map */
+
+#include "../stdafx.h"
+#include "../tile_type.h"
+#include "../map_func.h"
+#include "../core/alloc_type.hpp"
+#include "../core/bitmath_func.hpp"
+
+#include "saveload.h"
+
+static uint32 _map_dim_x;
+static uint32 _map_dim_y;
+
+static const SaveLoadGlobVarList _map_dimensions[] = {
+	SLEG_CONDVAR(_map_dim_x, SLE_UINT32, 6, SL_MAX_VERSION),
+	SLEG_CONDVAR(_map_dim_y, SLE_UINT32, 6, SL_MAX_VERSION),
+	    SLEG_END()
+};
+
+static void Save_MAPS()
+{
+	_map_dim_x = MapSizeX();
+	_map_dim_y = MapSizeY();
+	SlGlobList(_map_dimensions);
+}
+
+static void Load_MAPS()
+{
+	SlGlobList(_map_dimensions);
+	AllocateMap(_map_dim_x, _map_dim_y);
+}
+
+enum {
+	MAP_SL_BUF_SIZE = 4096
+};
+
+static void Load_MAPT()
+{
+	SmallStackSafeStackAlloc<byte, MAP_SL_BUF_SIZE> buf;
+	TileIndex size = MapSize();
+
+	for (TileIndex i = 0; i != size;) {
+		SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8);
+		for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _m[i++].type_height = buf[j];
+	}
+}
+
+static void Save_MAPT()
+{
+	SmallStackSafeStackAlloc<byte, MAP_SL_BUF_SIZE> buf;
+	TileIndex size = MapSize();
+
+	SlSetLength(size);
+	for (TileIndex i = 0; i != size;) {
+		for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = _m[i++].type_height;
+		SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8);
+	}
+}
+
+static void Load_MAP1()
+{
+	SmallStackSafeStackAlloc<byte, MAP_SL_BUF_SIZE> buf;
+	TileIndex size = MapSize();
+
+	for (TileIndex i = 0; i != size;) {
+		SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8);
+		for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _m[i++].m1 = buf[j];
+	}
+}
+
+static void Save_MAP1()
+{
+	SmallStackSafeStackAlloc<byte, MAP_SL_BUF_SIZE> buf;
+	TileIndex size = MapSize();
+
+	SlSetLength(size);
+	for (TileIndex i = 0; i != size;) {
+		for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = _m[i++].m1;
+		SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8);
+	}
+}
+
+static void Load_MAP2()
+{
+	SmallStackSafeStackAlloc<uint16, MAP_SL_BUF_SIZE> buf;
+	TileIndex size = MapSize();
+
+	for (TileIndex i = 0; i != size;) {
+		SlArray(buf, MAP_SL_BUF_SIZE,
+			/* In those versions the m2 was 8 bits */
+			CheckSavegameVersion(5) ? SLE_FILE_U8 | SLE_VAR_U16 : SLE_UINT16
+		);
+		for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _m[i++].m2 = buf[j];
+	}
+}
+
+static void Save_MAP2()
+{
+	SmallStackSafeStackAlloc<uint16, MAP_SL_BUF_SIZE> buf;
+	TileIndex size = MapSize();
+
+	SlSetLength(size * sizeof(uint16));
+	for (TileIndex i = 0; i != size;) {
+		for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = _m[i++].m2;
+		SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT16);
+	}
+}
+
+static void Load_MAP3()
+{
+	SmallStackSafeStackAlloc<byte, MAP_SL_BUF_SIZE> buf;
+	TileIndex size = MapSize();
+
+	for (TileIndex i = 0; i != size;) {
+		SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8);
+		for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _m[i++].m3 = buf[j];
+	}
+}
+
+static void Save_MAP3()
+{
+	SmallStackSafeStackAlloc<byte, MAP_SL_BUF_SIZE> buf;
+	TileIndex size = MapSize();
+
+	SlSetLength(size);
+	for (TileIndex i = 0; i != size;) {
+		for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = _m[i++].m3;
+		SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8);
+	}
+}
+
+static void Load_MAP4()
+{
+	SmallStackSafeStackAlloc<byte, MAP_SL_BUF_SIZE> buf;
+	TileIndex size = MapSize();
+
+	for (TileIndex i = 0; i != size;) {
+		SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8);
+		for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _m[i++].m4 = buf[j];
+	}
+}
+
+static void Save_MAP4()
+{
+	SmallStackSafeStackAlloc<byte, MAP_SL_BUF_SIZE> buf;
+	TileIndex size = MapSize();
+
+	SlSetLength(size);
+	for (TileIndex i = 0; i != size;) {
+		for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = _m[i++].m4;
+		SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8);
+	}
+}
+
+static void Load_MAP5()
+{
+	SmallStackSafeStackAlloc<byte, MAP_SL_BUF_SIZE> buf;
+	TileIndex size = MapSize();
+
+	for (TileIndex i = 0; i != size;) {
+		SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8);
+		for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _m[i++].m5 = buf[j];
+	}
+}
+
+static void Save_MAP5()
+{
+	SmallStackSafeStackAlloc<byte, MAP_SL_BUF_SIZE> buf;
+	TileIndex size = MapSize();
+
+	SlSetLength(size);
+	for (TileIndex i = 0; i != size;) {
+		for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = _m[i++].m5;
+		SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8);
+	}
+}
+
+static void Load_MAP6()
+{
+	SmallStackSafeStackAlloc<byte, MAP_SL_BUF_SIZE> buf;
+	TileIndex size = MapSize();
+
+	if (CheckSavegameVersion(42)) {
+		for (TileIndex i = 0; i != size;) {
+			/* 1024, otherwise we overflow on 64x64 maps! */
+			SlArray(buf, 1024, SLE_UINT8);
+			for (uint j = 0; j != 1024; j++) {
+				_m[i++].m6 = GB(buf[j], 0, 2);
+				_m[i++].m6 = GB(buf[j], 2, 2);
+				_m[i++].m6 = GB(buf[j], 4, 2);
+				_m[i++].m6 = GB(buf[j], 6, 2);
+			}
+		}
+	} else {
+		for (TileIndex i = 0; i != size;) {
+			SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8);
+			for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _m[i++].m6 = buf[j];
+		}
+	}
+}
+
+static void Save_MAP6()
+{
+	SmallStackSafeStackAlloc<byte, MAP_SL_BUF_SIZE> buf;
+	TileIndex size = MapSize();
+
+	SlSetLength(size);
+	for (TileIndex i = 0; i != size;) {
+		for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = _m[i++].m6;
+		SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8);
+	}
+}
+
+static void Load_MAP7()
+{
+	SmallStackSafeStackAlloc<byte, MAP_SL_BUF_SIZE> buf;
+	TileIndex size = MapSize();
+
+	for (TileIndex i = 0; i != size;) {
+		SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8);
+		for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _me[i++].m7 = buf[j];
+	}
+}
+
+static void Save_MAP7()
+{
+	SmallStackSafeStackAlloc<byte, MAP_SL_BUF_SIZE> buf;
+	TileIndex size = MapSize();
+
+	SlSetLength(size);
+	for (TileIndex i = 0; i != size;) {
+		for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = _me[i++].m7;
+		SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8);
+	}
+}
+
+extern const ChunkHandler _map_chunk_handlers[] = {
+	{ 'MAPS', Save_MAPS,     Load_MAPS,     CH_RIFF },
+	{ 'MAPT', Save_MAPT,     Load_MAPT,     CH_RIFF },
+	{ 'MAPO', Save_MAP1,     Load_MAP1,     CH_RIFF },
+	{ 'MAP2', Save_MAP2,     Load_MAP2,     CH_RIFF },
+	{ 'M3LO', Save_MAP3,     Load_MAP3,     CH_RIFF },
+	{ 'M3HI', Save_MAP4,     Load_MAP4,     CH_RIFF },
+	{ 'MAP5', Save_MAP5,     Load_MAP5,     CH_RIFF },
+	{ 'MAPE', Save_MAP6,     Load_MAP6,     CH_RIFF },
+	{ 'MAP7', Save_MAP7,     Load_MAP7,     CH_RIFF },
+};
new file mode 100644
--- /dev/null
+++ b/src/saveload/misc_sl.cpp
@@ -0,0 +1,105 @@
+/* $Id$ */
+
+/** @file misc_sl.cpp Saving and loading of things that didn't fit anywhere else */
+
+#include "../stdafx.h"
+#include "../date_func.h"
+#include "../variables.h"
+#include "../core/random_func.hpp"
+#include "../openttd.h"
+#include "../tile_type.h"
+#include "../zoom_func.h"
+#include "../vehicle_func.h"
+#include "../window_gui.h"
+#include "../window_func.h"
+#include "../viewport_func.h"
+#include "../gfx_func.h"
+
+#include "saveload.h"
+
+extern TileIndex _cur_tileloop_tile;
+
+/* Keep track of current game position */
+int _saved_scrollpos_x;
+int _saved_scrollpos_y;
+
+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();
+}
+
+
+static const SaveLoadGlobVarList _date_desc[] = {
+	SLEG_CONDVAR(_date,                   SLE_FILE_U16 | SLE_VAR_I32,  0,  30),
+	SLEG_CONDVAR(_date,                   SLE_INT32,                  31, SL_MAX_VERSION),
+	    SLEG_VAR(_date_fract,             SLE_UINT16),
+	    SLEG_VAR(_tick_counter,           SLE_UINT16),
+	    SLEG_VAR(_vehicle_id_ctr_day,     SLE_UINT16),
+	    SLEG_VAR(_age_cargo_skip_counter, SLE_UINT8),
+	SLE_CONDNULL(1, 0, 45),
+	SLEG_CONDVAR(_cur_tileloop_tile,      SLE_FILE_U16 | SLE_VAR_U32,  0, 5),
+	SLEG_CONDVAR(_cur_tileloop_tile,      SLE_UINT32,                  6, SL_MAX_VERSION),
+	    SLEG_VAR(_disaster_delay,         SLE_UINT16),
+	    SLEG_VAR(_station_tick_ctr,       SLE_UINT16),
+	    SLEG_VAR(_random.state[0],        SLE_UINT32),
+	    SLEG_VAR(_random.state[1],        SLE_UINT32),
+	SLEG_CONDVAR(_cur_town_ctr,           SLE_FILE_U8  | SLE_VAR_U32,  0, 9),
+	SLEG_CONDVAR(_cur_town_ctr,           SLE_UINT32,                 10, SL_MAX_VERSION),
+	    SLEG_VAR(_cur_company_tick_index, SLE_FILE_U8  | SLE_VAR_U32),
+	    SLEG_VAR(_next_competitor_start,  SLE_FILE_U16 | SLE_VAR_U32),
+	    SLEG_VAR(_trees_tick_ctr,         SLE_UINT8),
+	SLEG_CONDVAR(_pause_game,             SLE_UINT8,                   4, SL_MAX_VERSION),
+	SLEG_CONDVAR(_cur_town_iter,          SLE_UINT32,                 11, SL_MAX_VERSION),
+	    SLEG_END()
+};
+
+/* Save load date related variables as well as persistent tick counters
+ * XXX: currently some unrelated stuff is just put here */
+static void SaveLoad_DATE()
+{
+	SlGlobList(_date_desc);
+}
+
+
+static const SaveLoadGlobVarList _view_desc[] = {
+	SLEG_CONDVAR(_saved_scrollpos_x,    SLE_FILE_I16 | SLE_VAR_I32, 0, 5),
+	SLEG_CONDVAR(_saved_scrollpos_x,    SLE_INT32,                  6, SL_MAX_VERSION),
+	SLEG_CONDVAR(_saved_scrollpos_y,    SLE_FILE_I16 | SLE_VAR_I32, 0, 5),
+	SLEG_CONDVAR(_saved_scrollpos_y,    SLE_INT32,                  6, SL_MAX_VERSION),
+	    SLEG_VAR(_saved_scrollpos_zoom, SLE_UINT8),
+	    SLEG_END()
+};
+
+static void SaveLoad_VIEW()
+{
+	SlGlobList(_view_desc);
+}
+
+extern const ChunkHandler _misc_chunk_handlers[] = {
+	{ 'DATE', SaveLoad_DATE, SaveLoad_DATE, CH_RIFF},
+	{ 'VIEW', SaveLoad_VIEW, SaveLoad_VIEW, CH_RIFF | CH_LAST},
+};
new file mode 100644
--- /dev/null
+++ b/src/saveload/newgrf_sl.cpp
@@ -0,0 +1,52 @@
+/* $Id$ */
+
+/** @file newgrf_sl.cpp Code handling saving and loading of newgrf config */
+
+#include "../stdafx.h"
+#include "../newgrf_config.h"
+#include "../core/bitmath_func.hpp"
+#include "../core/alloc_func.hpp"
+#include "../gfx_func.h"
+
+#include "saveload.h"
+
+static const SaveLoad _grfconfig_desc[] = {
+	    SLE_STR(GRFConfig, filename,         SLE_STR,    0x40),
+	    SLE_VAR(GRFConfig, grfid,            SLE_UINT32),
+	    SLE_ARR(GRFConfig, md5sum,           SLE_UINT8,  16),
+	    SLE_ARR(GRFConfig, param,            SLE_UINT32, 0x80),
+	    SLE_VAR(GRFConfig, num_params,       SLE_UINT8),
+	SLE_CONDVAR(GRFConfig, windows_paletted, SLE_BOOL,   101, SL_MAX_VERSION),
+	SLE_END()
+};
+
+
+static void Save_NGRF()
+{
+	int index = 0;
+
+	for (GRFConfig *c = _grfconfig; c != NULL; c = c->next) {
+		if (HasBit(c->flags, GCF_STATIC)) continue;
+		SlSetArrayIndex(index++);
+		SlObject(c, _grfconfig_desc);
+	}
+}
+
+
+static void Load_NGRF()
+{
+	ClearGRFConfigList(&_grfconfig);
+	while (SlIterateArray() != -1) {
+		GRFConfig *c = CallocT<GRFConfig>(1);
+		SlObject(c, _grfconfig_desc);
+		if (CheckSavegameVersion(101)) c->windows_paletted = (_use_palette == PAL_WINDOWS);
+		AppendToGRFConfigList(&_grfconfig, c);
+	}
+
+	/* Append static NewGRF configuration */
+	AppendStaticGRFConfigs(&_grfconfig);
+}
+
+extern const ChunkHandler _newgrf_chunk_handlers[] = {
+	{ 'NGRF', Save_NGRF, Load_NGRF, CH_ARRAY | CH_LAST }
+};
new file mode 100644
--- /dev/null
+++ b/src/saveload/oldloader.cpp
@@ -0,0 +1,1736 @@
+/* $Id$ */
+
+/** @file oldloader.cpp Loading of old TTD(patch) savegames. */
+
+#include "../stdafx.h"
+#include "../openttd.h"
+#include "../station_map.h"
+#include "../town.h"
+#include "../industry.h"
+#include "../company_func.h"
+#include "../company_base.h"
+#include "../aircraft.h"
+#include "../roadveh.h"
+#include "../ship.h"
+#include "../train.h"
+#include "../signs_base.h"
+#include "../debug.h"
+#include "../depot_base.h"
+#include "../newgrf_config.h"
+#include "../ai/ai.h"
+#include "../ai/default/default.h"
+#include "../zoom_func.h"
+#include "../functions.h"
+#include "../date_func.h"
+#include "../vehicle_func.h"
+#include "../variables.h"
+#include "../strings_func.h"
+#include "../effectvehicle_base.h"
+
+#include "table/strings.h"
+
+#include "saveload.h"
+#include "saveload_internal.h"
+
+enum {
+	HEADER_SIZE = 49,
+	BUFFER_SIZE = 4096,
+
+	OLD_MAP_SIZE = 256 * 256
+};
+
+struct LoadgameState {
+	FILE *file;
+
+	uint chunk_size;
+
+	bool decoding;
+	byte decode_char;
+
+	uint buffer_count;
+	uint buffer_cur;
+	byte buffer[BUFFER_SIZE];
+
+	uint total_read;
+	bool failed;
+};
+
+/* OldChunk-Type */
+enum OldChunkType {
+	OC_SIMPLE    = 0,
+	OC_NULL      = 1,
+	OC_CHUNK     = 2,
+	OC_ASSERT    = 3,
+	/* 8 bits allocated (256 max) */
+
+	OC_VAR_I8    = 1 << 8,
+	OC_VAR_U8    = 2 << 8,
+	OC_VAR_I16   = 3 << 8,
+	OC_VAR_U16   = 4 << 8,
+	OC_VAR_I32   = 5 << 8,
+	OC_VAR_U32   = 6 << 8,
+	OC_VAR_I64   = 7 << 8,
+	/* 8 bits allocated (256 max) */
+
+	OC_FILE_I8   = 1 << 16,
+	OC_FILE_U8   = 2 << 16,
+	OC_FILE_I16  = 3 << 16,
+	OC_FILE_U16  = 4 << 16,
+	OC_FILE_I32  = 5 << 16,
+	OC_FILE_U32  = 6 << 16,
+	/* 8 bits allocated (256 max) */
+
+	OC_INT8      = OC_VAR_I8   | OC_FILE_I8,
+	OC_UINT8     = OC_VAR_U8   | OC_FILE_U8,
+	OC_INT16     = OC_VAR_I16  | OC_FILE_I16,
+	OC_UINT16    = OC_VAR_U16  | OC_FILE_U16,
+	OC_INT32     = OC_VAR_I32  | OC_FILE_I32,
+	OC_UINT32    = OC_VAR_U32  | OC_FILE_U32,
+
+	OC_TILE      = OC_VAR_U32  | OC_FILE_U16,
+
+	/**
+	 * Dereference the pointer once before writing to it,
+	 * so we do not have to use big static arrays.
+	 */
+	OC_DEREFERENCE_POINTER = 1 << 31,
+
+	OC_END       = 0 ///< End of the whole chunk, all 32 bits set to zero
+};
+
+DECLARE_ENUM_AS_BIT_SET(OldChunkType);
+
+typedef bool OldChunkProc(LoadgameState *ls, int num);
+
+struct OldChunks {
+	OldChunkType type;   ///< Type of field
+	uint32 amount;       ///< Amount of fields
+
+	void *ptr;           ///< Pointer where to save the data (may only be set if offset is 0)
+	uint offset;         ///< Offset from basepointer (may only be set if ptr is NULL)
+	OldChunkProc *proc;  ///< Pointer to function that is called with OC_CHUNK
+};
+
+/* If it fails, check lines above.. */
+assert_compile(sizeof(TileIndex) == 4);
+
+extern SavegameType _savegame_type;
+extern uint32 _ttdp_version;
+
+static uint32 _bump_assert_value;
+static bool   _read_ttdpatch_flags;
+
+static OldChunkType GetOldChunkType(OldChunkType type)     {return (OldChunkType)GB(type, 0, 8);}
+static OldChunkType GetOldChunkVarType(OldChunkType type)  {return (OldChunkType)(GB(type, 8, 8) << 8);}
+static OldChunkType GetOldChunkFileType(OldChunkType type) {return (OldChunkType)(GB(type, 16, 8) << 16);}
+
+static inline byte CalcOldVarLen(OldChunkType type)
+{
+	static const byte type_mem_size[] = {0, 1, 1, 2, 2, 4, 4, 8};
+	byte length = GB(type, 8, 8);
+	assert(length != 0 && length < lengthof(type_mem_size));
+	return type_mem_size[length];
+}
+
+/**
+ *
+ * Reads a byte from a file (do not call yourself, use ReadByte())
+ *
+ */
+static byte ReadByteFromFile(LoadgameState *ls)
+{
+	/* To avoid slow reads, we read BUFFER_SIZE of bytes per time
+	and just return a byte per time */
+	if (ls->buffer_cur >= ls->buffer_count) {
+		/* Read some new bytes from the file */
+		int count = (int)fread(ls->buffer, 1, BUFFER_SIZE, ls->file);
+
+		/* We tried to read, but there is nothing in the file anymore.. */
+		if (count == 0) {
+			DEBUG(oldloader, 0, "Read past end of file, loading failed");
+			ls->failed = true;
+		}
+
+		ls->buffer_count = count;
+		ls->buffer_cur   = 0;
+	}
+
+	return ls->buffer[ls->buffer_cur++];
+}
+
+/**
+ *
+ * Reads a byte from the buffer and decompress if needed
+ *
+ */
+static byte ReadByte(LoadgameState *ls)
+{
+	/* Old savegames have a nice compression algorithm (RLE)
+	which means that we have a chunk, which starts with a length
+	byte. If that byte is negative, we have to repeat the next byte
+	that many times ( + 1). Else, we need to read that amount of bytes.
+	Works pretty good if you have many zero's behind eachother */
+
+	if (ls->chunk_size == 0) {
+		/* Read new chunk */
+		int8 new_byte = ReadByteFromFile(ls);
+
+		if (new_byte < 0) {
+			/* Repeat next char for new_byte times */
+			ls->decoding    = true;
+			ls->decode_char = ReadByteFromFile(ls);
+			ls->chunk_size  = -new_byte + 1;
+		} else {
+			ls->decoding    = false;
+			ls->chunk_size  = new_byte + 1;
+		}
+	}
+
+	ls->total_read++;
+	ls->chunk_size--;
+
+	return ls->decoding ? ls->decode_char : ReadByteFromFile(ls);
+}
+
+static inline uint16 ReadUint16(LoadgameState *ls)
+{
+	byte x = ReadByte(ls);
+	return x | ReadByte(ls) << 8;
+}
+
+static inline uint32 ReadUint32(LoadgameState *ls)
+{
+	uint16 x = ReadUint16(ls);
+	return x | ReadUint16(ls) << 16;
+}
+
+/**
+ *
+ * Loads a chunk from the old savegame
+ *
+ */
+static bool LoadChunk(LoadgameState *ls, void *base, const OldChunks *chunks)
+{
+	const OldChunks *chunk = chunks;
+	byte *base_ptr = (byte*)base;
+
+	while (chunk->type != OC_END) {
+		byte *ptr = (byte*)chunk->ptr;
+		if ((chunk->type & OC_DEREFERENCE_POINTER) != 0) ptr = *(byte**)ptr;
+
+		for (uint i = 0; i < chunk->amount; i++) {
+			if (ls->failed) return false;
+
+			/* Handle simple types */
+			if (GetOldChunkType(chunk->type) != 0) {
+				switch (GetOldChunkType(chunk->type)) {
+					/* Just read the byte and forget about it */
+					case OC_NULL: ReadByte(ls); break;
+
+					case OC_CHUNK:
+						/* Call function, with 'i' as parameter to tell which item we
+						 * are going to read */
+						if (!chunk->proc(ls, i)) return false;
+						break;
+
+					case OC_ASSERT:
+						DEBUG(oldloader, 4, "Assert point: 0x%X / 0x%X", ls->total_read, chunk->offset + _bump_assert_value);
+						if (ls->total_read != chunk->offset + _bump_assert_value) ls->failed = true;
+					default: break;
+				}
+			} else {
+				uint64 res = 0;
+
+				/* Reading from the file: bits 16 to 23 have the FILE type */
+				switch (GetOldChunkFileType(chunk->type)) {
+					case OC_FILE_I8:  res = (int8)ReadByte(ls); break;
+					case OC_FILE_U8:  res = ReadByte(ls); break;
+					case OC_FILE_I16: res = (int16)ReadUint16(ls); break;
+					case OC_FILE_U16: res = ReadUint16(ls); break;
+					case OC_FILE_I32: res = (int32)ReadUint32(ls); break;
+					case OC_FILE_U32: res = ReadUint32(ls); break;
+					default: NOT_REACHED();
+				}
+
+				/* Sanity check */
+				assert(base_ptr != NULL || chunk->ptr != NULL);
+
+				/* Writing to the var: bits 8 to 15 have the VAR type */
+				if (chunk->ptr == NULL) ptr = base_ptr + chunk->offset;
+
+				/* Write the data */
+				switch (GetOldChunkVarType(chunk->type)) {
+					case OC_VAR_I8: *(int8  *)ptr = GB(res, 0, 8); break;
+					case OC_VAR_U8: *(uint8 *)ptr = GB(res, 0, 8); break;
+					case OC_VAR_I16:*(int16 *)ptr = GB(res, 0, 16); break;
+					case OC_VAR_U16:*(uint16*)ptr = GB(res, 0, 16); break;
+					case OC_VAR_I32:*(int32 *)ptr = res; break;
+					case OC_VAR_U32:*(uint32*)ptr = res; break;
+					case OC_VAR_I64:*(int64 *)ptr = res; break;
+					default: NOT_REACHED();
+				}
+
+				/* Increase pointer base for arrays when looping */
+				if (chunk->amount > 1 && chunk->ptr != NULL) ptr += CalcOldVarLen(chunk->type);
+			}
+		}
+
+		chunk++;
+	}
+
+	return true;
+}
+
+/**
+ *
+ * Initialize some data before reading
+ *
+ */
+static void InitLoading(LoadgameState *ls)
+{
+	ls->chunk_size   = 0;
+	ls->total_read   = 0;
+	ls->failed       = false;
+
+	ls->decoding     = false;
+	ls->decode_char  = 0;
+
+	ls->buffer_cur   = 0;
+	ls->buffer_count = 0;
+	memset(ls->buffer, 0, BUFFER_SIZE);
+
+	_bump_assert_value = 0;
+
+	_savegame_type   = SGT_TTD;
+	_ttdp_version    = 0;
+
+	_read_ttdpatch_flags = false;
+}
+
+
+/*
+ * Begin -- Stuff to fix the savegames to be OpenTTD compatible
+ */
+
+extern uint32 GetOldTownName(uint32 townnameparts, byte old_town_name_type);
+
+static void FixOldTowns()
+{
+	Town *town;
+
+	/* Convert town-names if needed */
+	FOR_ALL_TOWNS(town) {
+		if (IsInsideMM(town->townnametype, 0x20C1, 0x20C3)) {
+			town->townnametype = SPECSTR_TOWNNAME_ENGLISH + _settings_game.game_creation.town_name;
+			town->townnameparts = GetOldTownName(town->townnameparts, _settings_game.game_creation.town_name);
+		}
+	}
+}
+
+static StringID *_old_vehicle_names = NULL;
+
+static void FixOldVehicles()
+{
+	Vehicle* v;
+
+	FOR_ALL_VEHICLES(v) {
+		v->name = CopyFromOldName(_old_vehicle_names[v->index]);
+
+		/* We haven't used this bit for stations for ages */
+		if (v->type == VEH_ROAD &&
+				v->u.road.state != RVSB_IN_DEPOT &&
+				v->u.road.state != RVSB_WORMHOLE) {
+			ClrBit(v->u.road.state, RVS_IS_STOPPING);
+		}
+
+		/* The subtype should be 0, but it sometimes isn't :( */
+		if (v->type == VEH_ROAD) v->subtype = 0;
+
+		/* Sometimes primary vehicles would have a nothing (invalid) order
+		 * or vehicles that could not have an order would still have a
+		 * (loading) order which causes assertions and the like later on.
+		 */
+		if (!IsCompanyBuildableVehicleType(v) ||
+				(v->IsPrimaryVehicle() && v->current_order.IsType(OT_NOTHING))) {
+			v->current_order.MakeDummy();
+		}
+
+		/* Shared orders are fixed in AfterLoadVehicles now */
+	}
+}
+
+/*
+ * End -- Stuff to fix the savegames to be OpenTTD compatible
+ */
+
+
+/* Help:
+ *  - OCL_SVAR: load 'type' to offset 'offset' in a struct of type 'base', which must also
+ *       be given via base in LoadChunk() as real pointer
+ *  - OCL_VAR: load 'type' to a global var
+ *  - OCL_END: every struct must end with this
+ *  - OCL_NULL: read 'amount' of bytes and send them to /dev/null or something
+ *  - OCL_CHUNK: load an other proc to load a part of the savegame, 'amount' times
+ *  - OCL_ASSERT: to check if we are really at the place we expect to be.. because old savegames are too binary to be sure ;)
+ */
+#define OCL_SVAR(type, base, offset)         { type,          1, NULL,    (uint)cpp_offsetof(base, offset), NULL }
+#define OCL_VAR(type, amount, pointer)       { type,     amount, pointer, 0,                      NULL }
+#define OCL_END()                                   { OC_END,        0, NULL,    0,                      NULL }
+#define OCL_NULL(amount)                            { OC_NULL,  amount, NULL,    0,                      NULL }
+#define OCL_CHUNK(amount, proc)                     { OC_CHUNK, amount, NULL,    0,                      proc }
+#define OCL_ASSERT(size)                            { OC_ASSERT,     1, NULL, size,                      NULL }
+
+/* The savegames has some hard-coded pointers, because it always enters the same
+    piece of memory.. we don't.. so we need to remap ;)
+   Old Towns are 94 bytes big
+   Old Orders are 2 bytes big */
+#define REMAP_TOWN_IDX(x) ((x) - (0x0459154 - 0x0458EF0)) / 94
+#define REMAP_ORDER_IDX(x) ((x) - (0x045AB08 - 0x0458EF0)) / 2
+
+extern TileIndex *_animated_tile_list;
+extern uint _animated_tile_count;
+extern char *_old_name_array;
+
+static byte   _old_vehicle_multiplier;
+static uint8  *_old_map3;
+static uint32 _old_town_index;
+static uint16 _old_string_id;
+static uint16 _old_string_id_2;
+static uint16 _old_extra_chunk_nums;
+
+static void ReadTTDPatchFlags()
+{
+	if (_read_ttdpatch_flags) return;
+
+	_read_ttdpatch_flags = true;
+
+	/* TTDPatch misuses _old_map3 for flags.. read them! */
+	_old_vehicle_multiplier = _old_map3[0];
+	/* Somehow.... there was an error in some savegames, so 0 becomes 1
+	and 1 becomes 2. The rest of the values are okay */
+	if (_old_vehicle_multiplier < 2) _old_vehicle_multiplier++;
+
+	_old_vehicle_names = MallocT<StringID>(_old_vehicle_multiplier * 850);
+
+	/* TTDPatch increases the Vehicle-part in the middle of the game,
+	so if the multipler is anything else but 1, the assert fails..
+	bump the assert value so it doesn't!
+	(1 multipler == 850 vehicles
+	1 vehicle   == 128 bytes */
+	_bump_assert_value = (_old_vehicle_multiplier - 1) * 850 * 128;
+
+	for (uint i = 0; i < 17; i++) { // check tile 0, too
+		if (_old_map3[i] != 0) _savegame_type = SGT_TTDP1;
+	}
+
+	/* Check if we have a modern TTDPatch savegame (has extra data all around) */
+	if (memcmp(&_old_map3[0x1FFFA], "TTDp", 4) == 0) _savegame_type = SGT_TTDP2;
+
+	_old_extra_chunk_nums = _old_map3[_savegame_type == SGT_TTDP2 ? 0x1FFFE : 0x2];
+
+	/* Clean the misused places */
+	for (uint i = 0;       i < 17;      i++) _old_map3[i] = 0;
+	for (uint i = 0x1FE00; i < 0x20000; i++) _old_map3[i] = 0;
+
+	if (_savegame_type == SGT_TTDP2) DEBUG(oldloader, 2, "Found TTDPatch game");
+
+	DEBUG(oldloader, 3, "Vehicle-multiplier is set to %d (%d vehicles)", _old_vehicle_multiplier, _old_vehicle_multiplier * 850);
+}
+
+static const OldChunks town_chunk[] = {
+	OCL_SVAR(   OC_TILE, Town, xy ),
+	OCL_NULL( 2 ),         ///< population,        no longer in use
+	OCL_SVAR( OC_UINT16, Town, townnametype ),
+	OCL_SVAR( OC_UINT32, Town, townnameparts ),
+	OCL_SVAR(  OC_UINT8, Town, grow_counter ),
+	OCL_NULL( 1 ),         ///< sort_index,        no longer in use
+	OCL_NULL( 4 ),         ///< sign-coordinates,  no longer in use
+	OCL_NULL( 2 ),         ///< namewidth,         no longer in use
+	OCL_SVAR( OC_UINT16, Town, flags12 ),
+	OCL_NULL( 10 ),        ///< radius,            no longer in use
+
+	OCL_SVAR( OC_UINT16, Town, ratings[0] ),
+	OCL_SVAR( OC_UINT16, Town, ratings[1] ),
+	OCL_SVAR( OC_UINT16, Town, ratings[2] ),
+	OCL_SVAR( OC_UINT16, Town, ratings[3] ),
+	OCL_SVAR( OC_UINT16, Town, ratings[4] ),
+	OCL_SVAR( OC_UINT16, Town, ratings[5] ),
+	OCL_SVAR( OC_UINT16, Town, ratings[6] ),
+	OCL_SVAR( OC_UINT16, Town, ratings[7] ),
+
+	/* XXX - This is pretty odd.. we read 32bit, but only write 16bit.. sure there is
+	nothing changed ? ? */
+	OCL_SVAR( OC_FILE_U32 | OC_VAR_U16, Town, have_ratings ),
+	OCL_SVAR( OC_FILE_U32 | OC_VAR_U16, Town, statues ),
+	OCL_NULL( 2 ),         ///< num_houses,        no longer in use
+	OCL_SVAR(  OC_UINT8, Town, time_until_rebuild ),
+	OCL_SVAR(  OC_UINT8, Town, growth_rate ),
+
+	OCL_SVAR( OC_UINT16, Town, new_max_pass ),
+	OCL_SVAR( OC_UINT16, Town, new_max_mail ),
+	OCL_SVAR( OC_UINT16, Town, new_act_pass ),
+	OCL_SVAR( OC_UINT16, Town, new_act_mail ),
+	OCL_SVAR( OC_UINT16, Town, max_pass ),
+	OCL_SVAR( OC_UINT16, Town, max_mail ),
+	OCL_SVAR( OC_UINT16, Town, act_pass ),
+	OCL_SVAR( OC_UINT16, Town, act_mail ),
+
+	OCL_SVAR(  OC_UINT8, Town, pct_pass_transported ),
+	OCL_SVAR(  OC_UINT8, Town, pct_mail_transported ),
+
+	OCL_SVAR( OC_UINT16, Town, new_act_food ),
+	OCL_SVAR( OC_UINT16, Town, new_act_water ),
+	OCL_SVAR( OC_UINT16, Town, act_food ),
+	OCL_SVAR( OC_UINT16, Town, act_water ),
+
+	OCL_SVAR(  OC_UINT8, Town, road_build_months ),
+	OCL_SVAR(  OC_UINT8, Town, fund_buildings_months ),
+
+	OCL_NULL( 8 ),         ///< some junk at the end of the record
+
+	OCL_END()
+};
+static bool LoadOldTown(LoadgameState *ls, int num)
+{
+	Town *t = new (num) Town();
+	if (!LoadChunk(ls, t, town_chunk)) return false;
+
+	if (t->xy == 0) t->xy = INVALID_TILE;
+
+	return true;
+}
+
+static uint16 _old_order;
+static const OldChunks order_chunk[] = {
+	OCL_VAR ( OC_UINT16,   1, &_old_order ),
+	OCL_END()
+};
+
+static bool LoadOldOrder(LoadgameState *ls, int num)
+{
+	if (!LoadChunk(ls, NULL, order_chunk)) return false;
+
+	new (num) Order(UnpackOldOrder(_old_order));
+
+	/* Relink the orders to eachother (in TTD(Patch) the orders for one
+	vehicle are behind eachother, with an invalid order (OT_NOTHING) as indication that
+	it is the last order */
+	if (num > 0 && GetOrder(num)->IsValid())
+		GetOrder(num - 1)->next = GetOrder(num);
+
+	return true;
+}
+
+static bool LoadOldAnimTileList(LoadgameState *ls, int num)
+{
+	/* This is sligthly hackish - we must load a chunk into an array whose
+	 * address isn't static, but instead pointed to by _animated_tile_list.
+	 * To achieve that, create an OldChunks list on the stack on the fly.
+	 * The list cannot be static because the value of _animated_tile_list
+	 * can change between calls. */
+
+	const OldChunks anim_chunk[] = {
+		OCL_VAR (   OC_TILE, 256, _animated_tile_list ),
+		OCL_END ()
+	};
+
+	if (!LoadChunk(ls, NULL, anim_chunk)) return false;
+
+	/* Update the animated tile counter by counting till the first zero in the array */
+	for (_animated_tile_count = 0; _animated_tile_count < 256; _animated_tile_count++) {
+		if (_animated_tile_list[_animated_tile_count] == 0) break;
+	}
+
+	return true;
+}
+
+static const OldChunks depot_chunk[] = {
+	OCL_SVAR(   OC_TILE, Depot, xy ),
+	OCL_VAR ( OC_UINT32,   1, &_old_town_index ),
+	OCL_END()
+};
+
+static bool LoadOldDepot(LoadgameState *ls, int num)
+{
+	Depot *d = new (num) Depot();
+	if (!LoadChunk(ls, d, depot_chunk)) return false;
+
+	if (d->xy != 0) {
+		GetDepot(num)->town_index = REMAP_TOWN_IDX(_old_town_index);
+	} else {
+		d->xy = INVALID_TILE;
+	}
+
+	return true;
+}
+
+static int32 _old_price;
+static uint16 _old_price_frac;
+static const OldChunks price_chunk[] = {
+	OCL_VAR (  OC_INT32,   1, &_old_price ),
+	OCL_VAR ( OC_UINT16,   1, &_old_price_frac ),
+	OCL_END()
+};
+
+static bool LoadOldPrice(LoadgameState *ls, int num)
+{
+	if (!LoadChunk(ls, NULL, price_chunk)) return false;
+
+	/* We use a struct to store the prices, but they are ints in a row..
+	so just access the struct as an array of int32's */
+	((Money*)&_price)[num] = _old_price;
+	_price_frac[num] = _old_price_frac;
+
+	return true;
+}
+
+static const OldChunks cargo_payment_rate_chunk[] = {
+	OCL_VAR (  OC_INT32,   1, &_old_price ),
+	OCL_VAR ( OC_UINT16,   1, &_old_price_frac ),
+
+	OCL_NULL( 2 ),         ///< Junk
+	OCL_END()
+};
+
+static bool LoadOldCargoPaymentRate(LoadgameState *ls, int num)
+{
+	if (!LoadChunk(ls, NULL, cargo_payment_rate_chunk)) return false;
+
+	_cargo_payment_rates[num] = -_old_price;
+	_cargo_payment_rates_frac[num] = _old_price_frac;
+
+	return true;
+}
+
+static uint   _current_station_id;
+static uint16 _waiting_acceptance;
+static uint8  _cargo_source;
+static uint8  _cargo_days;
+
+static const OldChunks goods_chunk[] = {
+	OCL_VAR ( OC_UINT16, 1,          &_waiting_acceptance ),
+	OCL_SVAR(  OC_UINT8, GoodsEntry, days_since_pickup ),
+	OCL_SVAR(  OC_UINT8, GoodsEntry, rating ),
+	OCL_VAR (  OC_UINT8, 1,          &_cargo_source ),
+	OCL_VAR (  OC_UINT8, 1,          &_cargo_days ),
+	OCL_SVAR(  OC_UINT8, GoodsEntry, last_speed ),
+	OCL_SVAR(  OC_UINT8, GoodsEntry, last_age ),
+
+	OCL_END()
+};
+
+static bool LoadOldGood(LoadgameState *ls, int num)
+{
+	Station *st = GetStation(_current_station_id);
+	GoodsEntry *ge = &st->goods[num];
+	bool ret = LoadChunk(ls, ge, goods_chunk);
+	if (!ret) return false;
+
+	SB(ge->acceptance_pickup, GoodsEntry::ACCEPTANCE, 1, HasBit(_waiting_acceptance, 15));
+	SB(ge->acceptance_pickup, GoodsEntry::PICKUP, 1, _cargo_source != 0xFF);
+	if (GB(_waiting_acceptance, 0, 12) != 0) {
+		CargoPacket *cp = new CargoPacket();
+		cp->source          = (_cargo_source == 0xFF) ? INVALID_STATION : _cargo_source;
+		cp->count           = GB(_waiting_acceptance, 0, 12);
+		cp->days_in_transit = _cargo_days;
+		ge->cargo.Append(cp);
+	}
+	return ret;
+}
+
+static const OldChunks station_chunk[] = {
+	OCL_SVAR(   OC_TILE, Station, xy ),
+	OCL_VAR ( OC_UINT32,   1, &_old_town_index ),
+
+	OCL_NULL( 4 ), ///< bus/lorry tile
+	OCL_SVAR(   OC_TILE, Station, train_tile ),
+	OCL_SVAR(   OC_TILE, Station, airport_tile ),
+	OCL_SVAR(   OC_TILE, Station, dock_tile ),
+	OCL_SVAR(  OC_UINT8, Station, trainst_w ),
+
+	OCL_NULL( 1 ),         ///< sort-index, no longer in use
+	OCL_NULL( 2 ),         ///< sign-width, no longer in use
+
+	OCL_VAR ( OC_UINT16,   1, &_old_string_id ),
+
+	OCL_NULL( 4 ),         ///< sign left/top, no longer in use
+
+	OCL_SVAR( OC_UINT16, Station, had_vehicle_of_type ),
+
+	OCL_CHUNK( 12, LoadOldGood ),
+
+	OCL_SVAR(  OC_UINT8, Station, time_since_load ),
+	OCL_SVAR(  OC_UINT8, Station, time_since_unload ),
+	OCL_SVAR(  OC_UINT8, Station, delete_ctr ),
+	OCL_SVAR(  OC_UINT8, Station, owner ),
+	OCL_SVAR(  OC_UINT8, Station, facilities ),
+	OCL_SVAR(  OC_UINT8, Station, airport_type ),
+	/* Bus/truck status, no longer in use
+	 * Blocked months
+	 * Unknown
+	 */
+	OCL_NULL( 4 ),
+	OCL_SVAR( OC_FILE_U16 | OC_VAR_U32, Station, airport_flags ),
+	OCL_NULL( 2 ),         ///< last_vehicle. now last_vehicle_type
+
+	OCL_NULL( 4 ),         ///< Junk at end of chunk
+
+	OCL_END()
+};
+static bool LoadOldStation(LoadgameState *ls, int num)
+{
+	Station *st = new (num) Station();
+	_current_station_id = num;
+
+	if (!LoadChunk(ls, st, station_chunk))
+		return false;
+
+	if (st->xy != 0) {
+		st->town    = GetTown(REMAP_TOWN_IDX(_old_town_index));
+		st->string_id = RemapOldStringID(_old_string_id);
+	} else {
+		st->xy = INVALID_TILE;
+	}
+
+	return true;
+}
+
+static const OldChunks industry_chunk[] = {
+	OCL_SVAR(   OC_TILE, Industry, xy ),
+	OCL_VAR ( OC_UINT32,   1, &_old_town_index ),
+	OCL_SVAR(  OC_UINT8, Industry, width ),
+	OCL_SVAR(  OC_UINT8, Industry, height ),
+	OCL_NULL( 2 ),  ///< used to be industry's produced_cargo
+
+	OCL_SVAR( OC_UINT16, Industry, produced_cargo_waiting[0] ),
+	OCL_SVAR( OC_UINT16, Industry, produced_cargo_waiting[1] ),
+
+	OCL_SVAR(  OC_UINT8, Industry, production_rate[0] ),
+	OCL_SVAR(  OC_UINT8, Industry, production_rate[1] ),
+
+	OCL_NULL( 3 ),  ///< used to be industry's accepts_cargo
+
+	OCL_SVAR(  OC_UINT8, Industry, prod_level ),
+
+	OCL_SVAR( OC_UINT16, Industry, this_month_production[0] ),
+	OCL_SVAR( OC_UINT16, Industry, this_month_production[1] ),
+	OCL_SVAR( OC_UINT16, Industry, this_month_transported[0] ),
+	OCL_SVAR( OC_UINT16, Industry, this_month_transported[1] ),
+
+	OCL_SVAR(  OC_UINT8, Industry, last_month_pct_transported[0] ),
+	OCL_SVAR(  OC_UINT8, Industry, last_month_pct_transported[1] ),
+
+	OCL_SVAR( OC_UINT16, Industry, last_month_production[0] ),
+	OCL_SVAR( OC_UINT16, Industry, last_month_production[1] ),
+	OCL_SVAR( OC_UINT16, Industry, last_month_transported[0] ),
+	OCL_SVAR( OC_UINT16, Industry, last_month_transported[1] ),
+
+	OCL_SVAR(  OC_UINT8, Industry, type ),
+	OCL_SVAR(  OC_UINT8, Industry, owner ),
+	OCL_SVAR(  OC_UINT8, Industry, random_color ),
+	OCL_SVAR( OC_FILE_U8 | OC_VAR_I32, Industry, last_prod_year ),
+	OCL_SVAR( OC_UINT16, Industry, counter ),
+	OCL_SVAR(  OC_UINT8, Industry, was_cargo_delivered ),
+
+	OCL_NULL( 9 ), ///< Random junk at the end of this chunk
+
+	OCL_END()
+};
+
+static bool LoadOldIndustry(LoadgameState *ls, int num)
+{
+	Industry *i = new (num) Industry();
+	if (!LoadChunk(ls, i, industry_chunk)) return false;
+
+	if (i->xy != 0) {
+		i->town = GetTown(REMAP_TOWN_IDX(_old_town_index));
+		IncIndustryTypeCount(i->type);
+	} else {
+		i->xy = INVALID_TILE;
+	}
+
+	return true;
+}
+
+static CompanyID _current_company_id;
+static int32 _old_yearly;
+
+static const OldChunks _company_yearly_chunk[] = {
+	OCL_VAR(  OC_INT32,   1, &_old_yearly ),
+	OCL_END()
+};
+
+static bool OldCompanyYearly(LoadgameState *ls, int num)
+{
+	int i;
+	Company *c = GetCompany(_current_company_id);
+
+	for (i = 0; i < 13; i++) {
+		if (!LoadChunk(ls, NULL, _company_yearly_chunk)) return false;
+
+		c->yearly_expenses[num][i] = _old_yearly;
+	}
+
+	return true;
+}
+
+static const OldChunks _company_economy_chunk[] = {
+	OCL_SVAR( OC_FILE_I32 | OC_VAR_I64, CompanyEconomyEntry, income ),
+	OCL_SVAR( OC_FILE_I32 | OC_VAR_I64, CompanyEconomyEntry, expenses ),
+	OCL_SVAR( OC_INT32,                 CompanyEconomyEntry, delivered_cargo ),
+	OCL_SVAR( OC_INT32,                 CompanyEconomyEntry, performance_history ),
+	OCL_SVAR( OC_FILE_I32 | OC_VAR_I64, CompanyEconomyEntry, company_value ),
+
+	OCL_END()
+};
+
+static bool OldCompanyEconomy(LoadgameState *ls, int num)
+{
+	int i;
+	Company *c = GetCompany(_current_company_id);
+
+	if (!LoadChunk(ls, &c->cur_economy, _company_economy_chunk)) return false;
+
+	/* Don't ask, but the number in TTD(Patch) are inversed to OpenTTD */
+	c->cur_economy.income   = -c->cur_economy.income;
+	c->cur_economy.expenses = -c->cur_economy.expenses;
+
+	for (i = 0; i < 24; i++) {
+		if (!LoadChunk(ls, &c->old_economy[i], _company_economy_chunk)) return false;
+
+		c->old_economy[i].income   = -c->old_economy[i].income;
+		c->old_economy[i].expenses = -c->old_economy[i].expenses;
+	}
+
+	return true;
+}
+
+static const OldChunks _company_ai_build_rec_chunk[] = {
+	OCL_SVAR(   OC_TILE, AiBuildRec, spec_tile ),
+	OCL_SVAR(   OC_TILE, AiBuildRec, use_tile ),
+	OCL_SVAR(  OC_UINT8, AiBuildRec, rand_rng ),
+	OCL_SVAR(  OC_UINT8, AiBuildRec, cur_building_rule ),
+	OCL_SVAR(  OC_UINT8, AiBuildRec, unk6 ),
+	OCL_SVAR(  OC_UINT8, AiBuildRec, unk7 ),
+	OCL_SVAR(  OC_UINT8, AiBuildRec, buildcmd_a ),
+	OCL_SVAR(  OC_UINT8, AiBuildRec, buildcmd_b ),
+	OCL_SVAR(  OC_UINT8, AiBuildRec, direction ),
+	OCL_SVAR(  OC_UINT8, AiBuildRec, cargo ),
+
+	OCL_NULL( 8 ),  ///< Junk...
+
+	OCL_END()
+};
+
+static bool OldLoadAIBuildRec(LoadgameState *ls, int num)
+{
+	Company *c = GetCompany(_current_company_id);
+
+	switch (num) {
+		case 0: return LoadChunk(ls, &_companies_ai[c->index].src,  _company_ai_build_rec_chunk);
+		case 1: return LoadChunk(ls, &_companies_ai[c->index].dst,  _company_ai_build_rec_chunk);
+		case 2: return LoadChunk(ls, &_companies_ai[c->index].mid1, _company_ai_build_rec_chunk);
+		case 3: return LoadChunk(ls, &_companies_ai[c->index].mid2, _company_ai_build_rec_chunk);
+	}
+
+	return false;
+}
+static const OldChunks _company_ai_chunk[] = {
+	OCL_SVAR(  OC_UINT8, CompanyAI, state ),
+	OCL_NULL( 1 ),         ///< Junk
+	OCL_SVAR(  OC_UINT8, CompanyAI, state_mode ),
+	OCL_SVAR( OC_UINT16, CompanyAI, state_counter ),
+	OCL_SVAR( OC_UINT16, CompanyAI, timeout_counter ),
+
+	OCL_CHUNK( 4, OldLoadAIBuildRec ),
+
+	OCL_NULL( 20 ),        ///< More junk
+
+	OCL_SVAR(  OC_UINT8, CompanyAI, cargo_type ),
+	OCL_SVAR(  OC_UINT8, CompanyAI, num_wagons ),
+	OCL_SVAR(  OC_UINT8, CompanyAI, build_kind ),
+	OCL_SVAR(  OC_UINT8, CompanyAI, num_build_rec ),
+	OCL_SVAR(  OC_UINT8, CompanyAI, num_loco_to_build ),
+	OCL_SVAR(  OC_UINT8, CompanyAI, num_want_fullload ),
+
+	OCL_NULL( 14 ),        ///< Oh no more junk :|
+
+	OCL_NULL( 2 ),         ///< Loco-id, not used
+
+	OCL_SVAR( OC_UINT16, CompanyAI, wagon_list[0] ),
+	OCL_SVAR( OC_UINT16, CompanyAI, wagon_list[1] ),
+	OCL_SVAR( OC_UINT16, CompanyAI, wagon_list[2] ),
+	OCL_SVAR( OC_UINT16, CompanyAI, wagon_list[3] ),
+	OCL_SVAR( OC_UINT16, CompanyAI, wagon_list[4] ),
+	OCL_SVAR( OC_UINT16, CompanyAI, wagon_list[5] ),
+	OCL_SVAR( OC_UINT16, CompanyAI, wagon_list[6] ),
+	OCL_SVAR( OC_UINT16, CompanyAI, wagon_list[7] ),
+	OCL_SVAR( OC_UINT16, CompanyAI, wagon_list[8] ),
+	OCL_SVAR(  OC_UINT8, CompanyAI, order_list_blocks[0] ),
+	OCL_SVAR(  OC_UINT8, CompanyAI, order_list_blocks[1] ),
+	OCL_SVAR(  OC_UINT8, CompanyAI, order_list_blocks[2] ),
+	OCL_SVAR(  OC_UINT8, CompanyAI, order_list_blocks[3] ),
+	OCL_SVAR(  OC_UINT8, CompanyAI, order_list_blocks[4] ),
+	OCL_SVAR(  OC_UINT8, CompanyAI, order_list_blocks[5] ),
+	OCL_SVAR(  OC_UINT8, CompanyAI, order_list_blocks[6] ),
+	OCL_SVAR(  OC_UINT8, CompanyAI, order_list_blocks[7] ),
+	OCL_SVAR(  OC_UINT8, CompanyAI, order_list_blocks[8] ),
+	OCL_SVAR(  OC_UINT8, CompanyAI, order_list_blocks[9] ),
+	OCL_SVAR(  OC_UINT8, CompanyAI, order_list_blocks[10] ),
+	OCL_SVAR(  OC_UINT8, CompanyAI, order_list_blocks[11] ),
+	OCL_SVAR(  OC_UINT8, CompanyAI, order_list_blocks[12] ),
+	OCL_SVAR(  OC_UINT8, CompanyAI, order_list_blocks[13] ),
+	OCL_SVAR(  OC_UINT8, CompanyAI, order_list_blocks[14] ),
+	OCL_SVAR(  OC_UINT8, CompanyAI, order_list_blocks[15] ),
+	OCL_SVAR(  OC_UINT8, CompanyAI, order_list_blocks[16] ),
+	OCL_SVAR(  OC_UINT8, CompanyAI, order_list_blocks[17] ),
+	OCL_SVAR(  OC_UINT8, CompanyAI, order_list_blocks[18] ),
+	OCL_SVAR(  OC_UINT8, CompanyAI, order_list_blocks[19] ),
+
+	OCL_SVAR( OC_UINT16, CompanyAI, start_tile_a ),
+	OCL_SVAR( OC_UINT16, CompanyAI, start_tile_b ),
+	OCL_SVAR( OC_UINT16, CompanyAI, cur_tile_a ),
+	OCL_SVAR( OC_UINT16, CompanyAI, cur_tile_b ),
+
+	OCL_SVAR(  OC_UINT8, CompanyAI, start_dir_a ),
+	OCL_SVAR(  OC_UINT8, CompanyAI, start_dir_b ),
+	OCL_SVAR(  OC_UINT8, CompanyAI, cur_dir_a ),
+	OCL_SVAR(  OC_UINT8, CompanyAI, cur_dir_b ),
+
+	OCL_SVAR(  OC_UINT8, CompanyAI, banned_tile_count ),
+
+	OCL_SVAR(   OC_TILE, CompanyAI, banned_tiles[0] ),
+	OCL_SVAR(  OC_UINT8, CompanyAI, banned_val[0] ),
+	OCL_SVAR(   OC_TILE, CompanyAI, banned_tiles[1] ),
+	OCL_SVAR(  OC_UINT8, CompanyAI, banned_val[1] ),
+	OCL_SVAR(   OC_TILE, CompanyAI, banned_tiles[2] ),
+	OCL_SVAR(  OC_UINT8, CompanyAI, banned_val[2] ),
+	OCL_SVAR(   OC_TILE, CompanyAI, banned_tiles[3] ),
+	OCL_SVAR(  OC_UINT8, CompanyAI, banned_val[3] ),
+	OCL_SVAR(   OC_TILE, CompanyAI, banned_tiles[4] ),
+	OCL_SVAR(  OC_UINT8, CompanyAI, banned_val[4] ),
+	OCL_SVAR(   OC_TILE, CompanyAI, banned_tiles[5] ),
+	OCL_SVAR(  OC_UINT8, CompanyAI, banned_val[5] ),
+	OCL_SVAR(   OC_TILE, CompanyAI, banned_tiles[6] ),
+	OCL_SVAR(  OC_UINT8, CompanyAI, banned_val[6] ),
+	OCL_SVAR(   OC_TILE, CompanyAI, banned_tiles[7] ),
+	OCL_SVAR(  OC_UINT8, CompanyAI, banned_val[7] ),
+	OCL_SVAR(   OC_TILE, CompanyAI, banned_tiles[8] ),
+	OCL_SVAR(  OC_UINT8, CompanyAI, banned_val[8] ),
+	OCL_SVAR(   OC_TILE, CompanyAI, banned_tiles[9] ),
+	OCL_SVAR(  OC_UINT8, CompanyAI, banned_val[9] ),
+	OCL_SVAR(   OC_TILE, CompanyAI, banned_tiles[10] ),
+	OCL_SVAR(  OC_UINT8, CompanyAI, banned_val[10] ),
+	OCL_SVAR(   OC_TILE, CompanyAI, banned_tiles[11] ),
+	OCL_SVAR(  OC_UINT8, CompanyAI, banned_val[11] ),
+	OCL_SVAR(   OC_TILE, CompanyAI, banned_tiles[12] ),
+	OCL_SVAR(  OC_UINT8, CompanyAI, banned_val[12] ),
+	OCL_SVAR(   OC_TILE, CompanyAI, banned_tiles[13] ),
+	OCL_SVAR(  OC_UINT8, CompanyAI, banned_val[13] ),
+	OCL_SVAR(   OC_TILE, CompanyAI, banned_tiles[14] ),
+	OCL_SVAR(  OC_UINT8, CompanyAI, banned_val[14] ),
+	OCL_SVAR(   OC_TILE, CompanyAI, banned_tiles[15] ),
+	OCL_SVAR(  OC_UINT8, CompanyAI, banned_val[15] ),
+
+	OCL_SVAR(  OC_UINT8, CompanyAI, railtype_to_use ),
+	OCL_SVAR(  OC_UINT8, CompanyAI, route_type_mask ),
+
+	OCL_END()
+};
+
+static bool OldCompanyAI(LoadgameState *ls, int num)
+{
+	return LoadChunk(ls, &_companies_ai[_current_company_id], _company_ai_chunk);
+}
+
+uint8 ai_tick;
+static const OldChunks _company_chunk[] = {
+	OCL_VAR ( OC_UINT16,   1, &_old_string_id ),
+	OCL_SVAR( OC_UINT32, Company, name_2 ),
+	OCL_SVAR( OC_UINT32, Company, face ),
+	OCL_VAR ( OC_UINT16,   1, &_old_string_id_2 ),
+	OCL_SVAR( OC_UINT32, Company, president_name_2 ),
+
+	OCL_SVAR(  OC_INT32, Company, money ),
+	OCL_SVAR(  OC_INT32, Company, current_loan ),
+
+	OCL_SVAR(  OC_UINT8, Company, colour ),
+	OCL_SVAR(  OC_UINT8, Company, money_fraction ),
+	OCL_SVAR(  OC_UINT8, Company, quarters_of_bankrupcy ),
+	OCL_SVAR(  OC_UINT8, Company, bankrupt_asked ),
+	OCL_SVAR( OC_FILE_U32 | OC_VAR_I64, Company, bankrupt_value ),
+	OCL_SVAR( OC_UINT16, Company, bankrupt_timeout ),
+
+	OCL_SVAR( OC_UINT32, Company, cargo_types ),
+
+	OCL_CHUNK( 3, OldCompanyYearly ),
+	OCL_CHUNK( 1, OldCompanyEconomy ),
+
+	OCL_SVAR( OC_FILE_U16 | OC_VAR_I32, Company, inaugurated_year),
+	OCL_SVAR(                  OC_TILE, Company, last_build_coordinate ),
+	OCL_SVAR(                 OC_UINT8, Company, num_valid_stat_ent ),
+
+	OCL_CHUNK( 1, OldCompanyAI ),
+
+	OCL_SVAR(  OC_UINT8, Company, block_preview ),
+	 OCL_VAR(  OC_UINT8,   1, &ai_tick ),
+	OCL_SVAR(  OC_UINT8, Company, avail_railtypes ),
+	OCL_SVAR(   OC_TILE, Company, location_of_HQ ),
+	OCL_SVAR(  OC_UINT8, Company, share_owners[0] ),
+	OCL_SVAR(  OC_UINT8, Company, share_owners[1] ),
+	OCL_SVAR(  OC_UINT8, Company, share_owners[2] ),
+	OCL_SVAR(  OC_UINT8, Company, share_owners[3] ),
+
+	OCL_NULL( 8 ), ///< junk at end of chunk
+
+	OCL_END()
+};
+
+static bool LoadOldCompany(LoadgameState *ls, int num)
+{
+	Company *c = new (num) Company();
+
+	_current_company_id = (CompanyID)num;
+
+	if (!LoadChunk(ls, c, _company_chunk)) return false;
+
+	if (_old_string_id == 0) {
+		delete c;
+		return true;
+	}
+
+	c->name_1 = RemapOldStringID(_old_string_id);
+	c->president_name_1 = RemapOldStringID(_old_string_id_2);
+	_companies_ai[_current_company_id].tick = ai_tick;
+
+	if (num == 0) {
+		/* If the first company has no name, make sure we call it UNNAMED */
+		if (c->name_1 == 0)
+			c->name_1 = STR_SV_UNNAMED;
+	} else {
+		/* Beside some multiplayer maps (1 on 1), which we don't official support,
+		 * all other companys are an AI.. mark them as such */
+		c->is_ai = true;
+	}
+
+	/* Sometimes it is better to not ask.. in old scenarios, the money
+	 * was always 893288 pounds. In the newer versions this is correct,
+	 * but correct for those oldies
+	 * Ps: this also means that if you had exact 893288 pounds, you will go back
+	 * to 100000.. this is a very VERY small chance ;) */
+	if (c->money == 893288) c->money = c->current_loan = 100000;
+
+	_company_colours[num] = c->colour;
+	c->inaugurated_year -= ORIGINAL_BASE_YEAR;
+
+	/* State 20 for AI companies is sell vehicle. Since the AI struct is not
+	 * really figured out as of now, _companies_ai[c->index].cur_veh; needed for 'sell vehicle'
+	 * is NULL and the function will crash. To fix this, just change the state
+	 * to some harmless state, like 'loop vehicle'; 1 */
+	if (!IsHumanCompany((CompanyID)num) && _companies_ai[c->index].state == 20) _companies_ai[c->index].state = 1;
+
+	if (c->is_ai && (!_networking || _network_server) && _ai.enabled)
+		AI_StartNewAI(c->index);
+
+	return true;
+}
+
+static uint32 _old_order_ptr;
+static uint16 _old_next_ptr;
+static uint32 _current_vehicle_id;
+
+static const OldChunks vehicle_train_chunk[] = {
+	OCL_SVAR(  OC_UINT8, VehicleRail, track ),
+	OCL_SVAR(  OC_UINT8, VehicleRail, force_proceed ),
+	OCL_SVAR( OC_UINT16, VehicleRail, crash_anim_pos ),
+	OCL_SVAR(  OC_UINT8, VehicleRail, railtype ),
+
+	OCL_NULL( 5 ), ///< Junk
+
+	OCL_END()
+};
+
+static const OldChunks vehicle_road_chunk[] = {
+	OCL_SVAR(  OC_UINT8, VehicleRoad, state ),
+	OCL_SVAR(  OC_UINT8, VehicleRoad, frame ),
+	OCL_SVAR( OC_UINT16, VehicleRoad, blocked_ctr ),
+	OCL_SVAR(  OC_UINT8, VehicleRoad, overtaking ),
+	OCL_SVAR(  OC_UINT8, VehicleRoad, overtaking_ctr ),
+	OCL_SVAR( OC_UINT16, VehicleRoad, crashed_ctr ),
+	OCL_SVAR(  OC_UINT8, VehicleRoad, reverse_ctr ),
+
+	OCL_NULL( 1 ), ///< Junk
+
+	OCL_END()
+};
+
+static const OldChunks vehicle_ship_chunk[] = {
+	OCL_SVAR(  OC_UINT8, VehicleShip, state ),
+
+	OCL_NULL( 9 ), ///< Junk
+
+	OCL_END()
+};
+
+static const OldChunks vehicle_air_chunk[] = {
+	OCL_SVAR(  OC_UINT8, VehicleAir, pos ),
+	OCL_SVAR(  OC_FILE_U8 | OC_VAR_U16, VehicleAir, targetairport ),
+	OCL_SVAR( OC_UINT16, VehicleAir, crashed_counter ),
+	OCL_SVAR(  OC_UINT8, VehicleAir, state ),
+
+	OCL_NULL( 5 ), ///< Junk
+
+	OCL_END()
+};
+
+static const OldChunks vehicle_effect_chunk[] = {
+	OCL_SVAR( OC_UINT16, VehicleEffect, animation_state ),
+	OCL_SVAR(  OC_UINT8, VehicleEffect, animation_substate ),
+
+	OCL_NULL( 7 ), // Junk
+
+	OCL_END()
+};
+
+static const OldChunks vehicle_disaster_chunk[] = {
+	OCL_SVAR( OC_UINT16, VehicleDisaster, image_override ),
+	OCL_SVAR( OC_UINT16, VehicleDisaster, big_ufo_destroyer_target ),
+
+	OCL_NULL( 6 ), ///< Junk
+
+	OCL_END()
+};
+
+static const OldChunks vehicle_empty_chunk[] = {
+	OCL_NULL( 10 ), ///< Junk
+
+	OCL_END()
+};
+
+static bool LoadOldVehicleUnion(LoadgameState *ls, int num)
+{
+	Vehicle *v = GetVehicle(_current_vehicle_id);
+	uint temp = ls->total_read;
+	bool res;
+
+	switch (v->type) {
+		default: NOT_REACHED();
+		case VEH_INVALID : res = LoadChunk(ls, NULL,           vehicle_empty_chunk);    break;
+		case VEH_TRAIN   : res = LoadChunk(ls, &v->u.rail,     vehicle_train_chunk);    break;
+		case VEH_ROAD    : res = LoadChunk(ls, &v->u.road,     vehicle_road_chunk);     break;
+		case VEH_SHIP    : res = LoadChunk(ls, &v->u.ship,     vehicle_ship_chunk);     break;
+		case VEH_AIRCRAFT: res = LoadChunk(ls, &v->u.air,      vehicle_air_chunk);      break;
+		case VEH_EFFECT  : res = LoadChunk(ls, &v->u.effect,   vehicle_effect_chunk);   break;
+		case VEH_DISASTER: res = LoadChunk(ls, &v->u.disaster, vehicle_disaster_chunk); break;
+	}
+
+	/* This chunk size should always be 10 bytes */
+	if (ls->total_read - temp != 10) {
+		DEBUG(oldloader, 0, "Assert failed in VehicleUnion: invalid chunk size");
+		return false;
+	}
+
+	return res;
+}
+
+static uint16 _cargo_count;
+
+static const OldChunks vehicle_chunk[] = {
+	OCL_SVAR(  OC_UINT8, Vehicle, subtype ),
+
+	OCL_NULL( 2 ),         ///< Hash, calculated automatically
+	OCL_NULL( 2 ),         ///< Index, calculated automatically
+
+	OCL_VAR ( OC_UINT32,   1, &_old_order_ptr ),
+	OCL_VAR ( OC_UINT16,   1, &_old_order ),
+
+	OCL_NULL ( 1 ), ///< num_orders, now calculated
+	OCL_SVAR(  OC_UINT8, Vehicle, cur_order_index ),
+	OCL_SVAR(   OC_TILE, Vehicle, dest_tile ),
+	OCL_SVAR( OC_UINT16, Vehicle, load_unload_time_rem ),
+	OCL_SVAR( OC_FILE_U16 | OC_VAR_U32, Vehicle, date_of_last_service ),
+	OCL_SVAR( OC_UINT16, Vehicle, service_interval ),
+	OCL_SVAR( OC_FILE_U8 | OC_VAR_U16, Vehicle, last_station_visited ),
+	OCL_SVAR(  OC_UINT8, Vehicle, tick_counter ),
+	OCL_SVAR( OC_UINT16, Vehicle, max_speed ),
+
+	OCL_SVAR( OC_FILE_U16 | OC_VAR_I32, Vehicle, x_pos ),
+	OCL_SVAR( OC_FILE_U16 | OC_VAR_I32, Vehicle, y_pos ),
+	OCL_SVAR(  OC_UINT8, Vehicle, z_pos ),
+	OCL_SVAR(  OC_UINT8, Vehicle, direction ),
+	OCL_NULL( 2 ),         ///< x_offs and y_offs, calculated automatically
+	OCL_NULL( 2 ),         ///< x_extent and y_extent, calculated automatically
+	OCL_NULL( 1 ),         ///< z_extent, calculated automatically
+
+	OCL_SVAR(  OC_UINT8, Vehicle, owner ),
+	OCL_SVAR(   OC_TILE, Vehicle, tile ),
+	OCL_SVAR( OC_UINT16, Vehicle, cur_image ),
+
+	OCL_NULL( 8 ),        ///< Vehicle sprite box, calculated automatically
+
+	OCL_SVAR( OC_FILE_U16 | OC_VAR_U8, Vehicle, vehstatus ),
+	OCL_SVAR( OC_UINT16, Vehicle, cur_speed ),
+	OCL_SVAR(  OC_UINT8, Vehicle, subspeed ),
+	OCL_SVAR(  OC_UINT8, Vehicle, acceleration ),
+	OCL_SVAR(  OC_UINT8, Vehicle, progress ),
+
+	OCL_SVAR(  OC_UINT8, Vehicle, cargo_type ),
+	OCL_SVAR( OC_UINT16, Vehicle, cargo_cap ),
+	OCL_VAR ( OC_UINT16, 1,       &_cargo_count ),
+	OCL_VAR (  OC_UINT8, 1,       &_cargo_source ),
+	OCL_VAR (  OC_UINT8, 1,       &_cargo_days ),
+
+	OCL_SVAR( OC_FILE_U16 | OC_VAR_U32, Vehicle, age ),
+	OCL_SVAR( OC_FILE_U16 | OC_VAR_U32, Vehicle, max_age ),
+	OCL_SVAR( OC_FILE_U8 | OC_VAR_I32, Vehicle, build_year ),
+	OCL_SVAR( OC_FILE_U8 | OC_VAR_U16, Vehicle, unitnumber ),
+
+	OCL_SVAR( OC_UINT16, Vehicle, engine_type ),
+
+	OCL_SVAR(  OC_UINT8, Vehicle, spritenum ),
+	OCL_SVAR(  OC_UINT8, Vehicle, day_counter ),
+
+	OCL_SVAR(  OC_UINT8, Vehicle, breakdowns_since_last_service ),
+	OCL_SVAR(  OC_UINT8, Vehicle, breakdown_ctr ),
+	OCL_SVAR(  OC_UINT8, Vehicle, breakdown_delay ),
+	OCL_SVAR(  OC_UINT8, Vehicle, breakdown_chance ),
+
+	OCL_SVAR( OC_UINT16, Vehicle, reliability ),
+	OCL_SVAR( OC_UINT16, Vehicle, reliability_spd_dec ),
+
+	OCL_SVAR( OC_FILE_I32 | OC_VAR_I64, Vehicle, profit_this_year ),
+	OCL_SVAR( OC_FILE_I32 | OC_VAR_I64, Vehicle, profit_last_year ),
+
+	OCL_VAR ( OC_UINT16,   1, &_old_next_ptr ),
+
+	OCL_SVAR( OC_UINT32, Vehicle, value ),
+
+	OCL_VAR ( OC_UINT16,   1, &_old_string_id ),
+
+	OCL_CHUNK( 1, LoadOldVehicleUnion ),
+
+	OCL_NULL( 20 ), ///< Junk at end of struct (TTDPatch has some data in it)
+
+	OCL_END()
+};
+
+bool LoadOldVehicle(LoadgameState *ls, int num)
+{
+	uint i;
+
+	/* Read the TTDPatch flags, because we need some info from it */
+	ReadTTDPatchFlags();
+
+	for (i = 0; i < _old_vehicle_multiplier; i++) {
+		_current_vehicle_id = num * _old_vehicle_multiplier + i;
+
+		/* Read the vehicle type and allocate the right vehicle */
+		Vehicle *v;
+		switch (ReadByte(ls)) {
+			default: NOT_REACHED();
+			case 0x00 /*VEH_INVALID */: v = new (_current_vehicle_id) InvalidVehicle();  break;
+			case 0x10 /*VEH_TRAIN   */: v = new (_current_vehicle_id) Train();           break;
+			case 0x11 /*VEH_ROAD    */: v = new (_current_vehicle_id) RoadVehicle();     break;
+			case 0x12 /*VEH_SHIP    */: v = new (_current_vehicle_id) Ship();            break;
+			case 0x13 /*VEH_AIRCRAFT*/: v = new (_current_vehicle_id) Aircraft();        break;
+			case 0x14 /*VEH_EFFECT  */: v = new (_current_vehicle_id) EffectVehicle();   break;
+			case 0x15 /*VEH_DISASTER*/: v = new (_current_vehicle_id) DisasterVehicle(); break;
+		}
+		if (!LoadChunk(ls, v, vehicle_chunk)) return false;
+
+		/* This should be consistent, else we have a big problem... */
+		if (v->index != _current_vehicle_id) {
+			DEBUG(oldloader, 0, "Loading failed - vehicle-array is invalid");
+			return false;
+		}
+
+		if (_old_order_ptr != 0 && _old_order_ptr != 0xFFFFFFFF) {
+			uint old_id = REMAP_ORDER_IDX(_old_order_ptr);
+			/* There is a maximum of 5000 orders in old savegames, so *if*
+			 * we go over that limit something is very wrong. In that case
+			 * we just assume there are no orders for the vehicle.
+			 */
+			if (old_id < 5000) v->orders.old = GetOrder(old_id);
+		}
+		v->current_order.AssignOrder(UnpackOldOrder(_old_order));
+
+		/* For some reason we need to correct for this */
+		switch (v->spritenum) {
+			case 0xfd: break;
+			case 0xff: v->spritenum = 0xfe; break;
+			default:   v->spritenum >>= 1; break;
+		}
+
+		if (_old_next_ptr != 0xFFFF) v->next = GetVehiclePoolSize() <= _old_next_ptr ? new (_old_next_ptr) InvalidVehicle() : GetVehicle(_old_next_ptr);
+
+		_old_vehicle_names[_current_vehicle_id] = RemapOldStringID(_old_string_id);
+		v->name = NULL;
+
+		/* Vehicle-subtype is different in TTD(Patch) */
+		if (v->type == VEH_EFFECT) v->subtype = v->subtype >> 1;
+
+		if (_cargo_count != 0) {
+			CargoPacket *cp = new CargoPacket((_cargo_source == 0xFF) ? INVALID_STATION : _cargo_source, _cargo_count);
+			cp->days_in_transit = _cargo_days;
+			v->cargo.Append(cp);
+		}
+	}
+
+	return true;
+}
+
+static const OldChunks sign_chunk[] = {
+	OCL_VAR ( OC_UINT16, 1, &_old_string_id ),
+	OCL_SVAR( OC_FILE_U16 | OC_VAR_I32, Sign, x ),
+	OCL_SVAR( OC_FILE_U16 | OC_VAR_I32, Sign, y ),
+	OCL_SVAR( OC_FILE_U16 | OC_VAR_I8, Sign, z ),
+
+	OCL_NULL( 6 ),         ///< Width of sign, no longer in use
+
+	OCL_END()
+};
+
+static bool LoadOldSign(LoadgameState *ls, int num)
+{
+	Sign *si = new (num) Sign();
+	if (!LoadChunk(ls, si, sign_chunk)) return false;
+
+	_old_string_id = RemapOldStringID(_old_string_id);
+	si->name = CopyFromOldName(_old_string_id);
+
+	return true;
+}
+
+static const OldChunks engine_chunk[] = {
+	OCL_SVAR( OC_UINT16, Engine, company_avail ),
+	OCL_SVAR( OC_FILE_U16 | OC_VAR_U32, Engine, intro_date ),
+	OCL_SVAR( OC_FILE_U16 | OC_VAR_U32, Engine, age ),
+	OCL_SVAR( OC_UINT16, Engine, reliability ),
+	OCL_SVAR( OC_UINT16, Engine, reliability_spd_dec ),
+	OCL_SVAR( OC_UINT16, Engine, reliability_start ),
+	OCL_SVAR( OC_UINT16, Engine, reliability_max ),
+	OCL_SVAR( OC_UINT16, Engine, reliability_final ),
+	OCL_SVAR( OC_UINT16, Engine, duration_phase_1 ),
+	OCL_SVAR( OC_UINT16, Engine, duration_phase_2 ),
+	OCL_SVAR( OC_UINT16, Engine, duration_phase_3 ),
+
+	OCL_SVAR(  OC_UINT8, Engine, lifelength ),
+	OCL_SVAR(  OC_UINT8, Engine, flags ),
+	OCL_SVAR(  OC_UINT8, Engine, preview_company_rank ),
+	OCL_SVAR(  OC_UINT8, Engine, preview_wait ),
+
+	OCL_NULL( 2 ), ///< Junk
+
+	OCL_END()
+};
+
+static bool LoadOldEngine(LoadgameState *ls, int num)
+{
+	Engine *e = GetTempDataEngine(num);
+	return LoadChunk(ls, e, engine_chunk);
+}
+
+static bool LoadOldEngineName(LoadgameState *ls, int num)
+{
+	Engine *e = GetTempDataEngine(num);
+	e->name = CopyFromOldName(RemapOldStringID(ReadUint16(ls)));
+	return true;
+}
+
+static const OldChunks subsidy_chunk[] = {
+	OCL_SVAR(  OC_UINT8, Subsidy, cargo_type ),
+	OCL_SVAR(  OC_UINT8, Subsidy, age ),
+	OCL_SVAR(  OC_FILE_U8 | OC_VAR_U16, Subsidy, from ),
+	OCL_SVAR(  OC_FILE_U8 | OC_VAR_U16, Subsidy, to ),
+
+	OCL_END()
+};
+
+static inline bool LoadOldSubsidy(LoadgameState *ls, int num)
+{
+	return LoadChunk(ls, &_subsidies[num], subsidy_chunk);
+}
+
+static const OldChunks game_difficulty_chunk[] = {
+	OCL_SVAR( OC_FILE_U16 |  OC_VAR_U8, DifficultySettings, max_no_competitors ),
+	OCL_SVAR( OC_FILE_U16 |  OC_VAR_U8, DifficultySettings, competitor_start_time ),
+	OCL_SVAR( OC_FILE_U16 |  OC_VAR_U8, DifficultySettings, number_towns ),
+	OCL_SVAR( OC_FILE_U16 |  OC_VAR_U8, DifficultySettings, number_industries ),
+	OCL_SVAR( OC_FILE_U16 | OC_VAR_U32, DifficultySettings, max_loan ),
+	OCL_SVAR( OC_FILE_U16 |  OC_VAR_U8, DifficultySettings, initial_interest ),
+	OCL_SVAR( OC_FILE_U16 |  OC_VAR_U8, DifficultySettings, vehicle_costs ),
+	OCL_SVAR( OC_FILE_U16 |  OC_VAR_U8, DifficultySettings, competitor_speed ),
+	OCL_SVAR( OC_FILE_U16 |  OC_VAR_U8, DifficultySettings, competitor_intelligence ),
+	OCL_SVAR( OC_FILE_U16 |  OC_VAR_U8, DifficultySettings, vehicle_breakdowns ),
+	OCL_SVAR( OC_FILE_U16 |  OC_VAR_U8, DifficultySettings, subsidy_multiplier ),
+	OCL_SVAR( OC_FILE_U16 |  OC_VAR_U8, DifficultySettings, construction_cost ),
+	OCL_SVAR( OC_FILE_U16 |  OC_VAR_U8, DifficultySettings, terrain_type ),
+	OCL_SVAR( OC_FILE_U16 |  OC_VAR_U8, DifficultySettings, quantity_sea_lakes ),
+	OCL_SVAR( OC_FILE_U16 |  OC_VAR_U8, DifficultySettings, economy ),
+	OCL_SVAR( OC_FILE_U16 |  OC_VAR_U8, DifficultySettings, line_reverse_mode ),
+	OCL_SVAR( OC_FILE_U16 |  OC_VAR_U8, DifficultySettings, disasters ),
+	OCL_END()
+};
+
+static inline bool LoadOldGameDifficulty(LoadgameState *ls, int num)
+{
+	bool ret = LoadChunk(ls, &_settings_game.difficulty, game_difficulty_chunk);
+	_settings_game.difficulty.max_loan *= 1000;
+	return ret;
+}
+
+
+static bool LoadOldMapPart1(LoadgameState *ls, int num)
+{
+	uint i;
+
+	for (i = 0; i < OLD_MAP_SIZE; i++) {
+		_m[i].m1 = ReadByte(ls);
+	}
+	for (i = 0; i < OLD_MAP_SIZE; i++) {
+		_m[i].m2 = ReadByte(ls);
+	}
+	for (i = 0; i < OLD_MAP_SIZE; i++) {
+		_old_map3[i * 2] = ReadByte(ls);
+		_old_map3[i * 2 + 1] = ReadByte(ls);
+	}
+	for (i = 0; i < OLD_MAP_SIZE / 4; i++) {
+		byte b = ReadByte(ls);
+		_m[i * 4 + 0].m6 = GB(b, 0, 2);
+		_m[i * 4 + 1].m6 = GB(b, 2, 2);
+		_m[i * 4 + 2].m6 = GB(b, 4, 2);
+		_m[i * 4 + 3].m6 = GB(b, 6, 2);
+	}
+
+	return !ls->failed;
+}
+
+static bool LoadOldMapPart2(LoadgameState *ls, int num)
+{
+	uint i;
+
+	for (i = 0; i < OLD_MAP_SIZE; i++) {
+		_m[i].type_height = ReadByte(ls);
+	}
+	for (i = 0; i < OLD_MAP_SIZE; i++) {
+		_m[i].m5 = ReadByte(ls);
+	}
+
+	return !ls->failed;
+}
+
+static bool LoadTTDPatchExtraChunks(LoadgameState *ls, int num)
+{
+	ReadTTDPatchFlags();
+
+	DEBUG(oldloader, 2, "Found %d extra chunk(s)", _old_extra_chunk_nums);
+
+	for (int i = 0; i != _old_extra_chunk_nums; i++) {
+		uint16 id = ReadUint16(ls);
+		uint32 len = ReadUint32(ls);
+
+		switch (id) {
+			/* List of GRFIDs, used in the savegame. 0x8004 is the new ID
+			 * They are saved in a 'GRFID:4 active:1' format, 5 bytes for each entry */
+			case 0x2:
+			case 0x8004: {
+				/* Skip the first element: TTDP hack for the Action D special variables (FFFF0000 01) */
+				ReadUint32(ls); ReadByte(ls); len -= 5;
+
+				ClearGRFConfigList(&_grfconfig);
+				while (len != 0) {
+					uint32 grfid = ReadUint32(ls);
+
+					if (ReadByte(ls) == 1) {
+						GRFConfig *c = CallocT<GRFConfig>(1);
+						c->grfid = grfid;
+						c->filename = strdup("TTDP game, no information");
+
+						AppendToGRFConfigList(&_grfconfig, c);
+						DEBUG(oldloader, 3, "TTDPatch game using GRF file with GRFID %0X", BSWAP32(c->grfid));
+					}
+					len -= 5;
+				};
+
+				/* Append static NewGRF configuration */
+				AppendStaticGRFConfigs(&_grfconfig);
+			} break;
+
+			/* TTDPatch version and configuration */
+			case 0x3:
+				_ttdp_version = ReadUint32(ls);
+				DEBUG(oldloader, 3, "Game saved with TTDPatch version %d.%d.%d r%d",
+					GB(_ttdp_version, 24, 8), GB(_ttdp_version, 20, 4), GB(_ttdp_version, 16, 4), GB(_ttdp_version, 0, 16));
+				len -= 4;
+				while (len-- != 0) ReadByte(ls); // skip the configuration
+				break;
+
+			default:
+				DEBUG(oldloader, 4, "Skipping unknown extra chunk %X", id);
+				while (len-- != 0) ReadByte(ls);
+				break;
+		}
+	}
+
+	return !ls->failed;
+}
+
+extern TileIndex _cur_tileloop_tile;
+static uint32 _old_cur_town_ctr;
+static const OldChunks main_chunk[] = {
+	OCL_ASSERT( 0 ),
+	OCL_VAR ( OC_FILE_U16 | OC_VAR_U32, 1, &_date ),
+	OCL_VAR ( OC_UINT16,   1, &_date_fract ),
+	OCL_NULL( 600 ),            ///< TextEffects
+	OCL_VAR ( OC_UINT32,   2, &_random.state ),
+
+	OCL_ASSERT( 0x264 ),
+	OCL_CHUNK(  70, LoadOldTown ),
+	OCL_ASSERT( 0x1C18 ),
+	OCL_CHUNK(5000, LoadOldOrder ),
+	OCL_ASSERT( 0x4328 ),
+
+	OCL_CHUNK( 1, LoadOldAnimTileList ),
+	OCL_NULL( 4 ),              ///< old end-of-order-list-pointer, no longer in use
+
+	OCL_CHUNK( 255, LoadOldDepot ),
+	OCL_ASSERT( 0x4B26 ),
+
+	OCL_VAR ( OC_UINT32,   1, &_old_cur_town_ctr ),
+	OCL_NULL( 2 ),              ///< timer_counter, no longer in use
+	OCL_NULL( 2 ),              ///< land_code,     no longer in use
+
+	OCL_VAR ( OC_FILE_U16 | OC_VAR_U8, 1, &_age_cargo_skip_counter ),
+	OCL_VAR ( OC_UINT16,   1, &_tick_counter ),
+	OCL_VAR (   OC_TILE,   1, &_cur_tileloop_tile ),
+
+	OCL_CHUNK( 49, LoadOldPrice ),
+	OCL_CHUNK( 12, LoadOldCargoPaymentRate ),
+
+	OCL_ASSERT( 0x4CBA ),
+
+	OCL_CHUNK( 1, LoadOldMapPart1 ),
+
+	OCL_ASSERT( 0x48CBA ),
+
+	OCL_CHUNK(250, LoadOldStation ),
+	OCL_CHUNK( 90, LoadOldIndustry ),
+	OCL_CHUNK(  8, LoadOldCompany ),
+
+	OCL_ASSERT( 0x547F2 ),
+
+	OCL_CHUNK( 850, LoadOldVehicle ),
+
+	OCL_ASSERT( 0x6F0F2 ),
+
+	OCL_VAR (  OC_UINT8 | OC_DEREFERENCE_POINTER, 32 * 500, &_old_name_array ),
+
+	OCL_NULL( 0x2000 ),            ///< Old hash-table, no longer in use
+
+	OCL_CHUNK( 40, LoadOldSign ),
+	OCL_CHUNK(256, LoadOldEngine ),
+
+	OCL_VAR ( OC_UINT16,    1, &_vehicle_id_ctr_day ),
+
+	OCL_CHUNK(  8, LoadOldSubsidy ),
+
+	OCL_VAR ( OC_FILE_U16 | OC_VAR_U32,   1, &_next_competitor_start ),
+	OCL_VAR ( OC_FILE_I16 | OC_VAR_I32,   1, &_saved_scrollpos_x ),
+	OCL_VAR ( OC_FILE_I16 | OC_VAR_I32,   1, &_saved_scrollpos_y ),
+	OCL_VAR ( OC_FILE_U16 | OC_VAR_U8,    1, &_saved_scrollpos_zoom ),
+
+	OCL_VAR ( OC_FILE_U32 | OC_VAR_I64,   1, &_economy.max_loan ),
+	OCL_VAR ( OC_FILE_U32 | OC_VAR_I64,   1, &_economy.max_loan_unround ),
+	OCL_VAR (  OC_INT16,    1, &_economy.fluct ),
+
+	OCL_VAR ( OC_UINT16,    1, &_disaster_delay ),
+
+	OCL_NULL( 144 ),             ///< cargo-stuff, calculated in InitializeLandscapeVariables
+
+	OCL_CHUNK(256, LoadOldEngineName ),
+
+	OCL_NULL( 144 ),             ///< AI cargo-stuff, calculated in InitializeLandscapeVariables
+	OCL_NULL( 2 ),               ///< Company indexes of companies, no longer in use
+
+	OCL_VAR ( OC_FILE_U8 | OC_VAR_U16,    1, &_station_tick_ctr ),
+
+	OCL_VAR (  OC_UINT8,    1, &_settings_game.locale.currency ),
+	OCL_VAR (  OC_UINT8,    1, &_settings_game.locale.units ),
+	OCL_VAR ( OC_FILE_U8 | OC_VAR_U32,    1, &_cur_company_tick_index ),
+
+	OCL_NULL( 2 ),               ///< Date stuff, calculated automatically
+	OCL_NULL( 8 ),               ///< Company colors, calculated automatically
+
+	OCL_VAR (  OC_UINT8,    1, &_economy.infl_amount ),
+	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_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_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.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
+
+	OCL_ASSERT( 0x77179 ),
+
+	OCL_CHUNK( 1, LoadOldMapPart2 ),
+
+	OCL_ASSERT( 0x97179 ),
+
+	/* Below any (if available) extra chunks from TTDPatch can follow */
+	OCL_CHUNK(1, LoadTTDPatchExtraChunks),
+
+	OCL_END()
+};
+
+static bool LoadOldMain(LoadgameState *ls)
+{
+	int i;
+
+	/* The first 49 is the name of the game + checksum, skip it */
+	fseek(ls->file, HEADER_SIZE, SEEK_SET);
+
+	DEBUG(oldloader, 3, "Reading main chunk...");
+	/* Load the biggest chunk */
+	_old_map3 = MallocT<byte>(OLD_MAP_SIZE * 2);
+	_old_vehicle_names = NULL;
+	if (!LoadChunk(ls, NULL, main_chunk)) {
+		DEBUG(oldloader, 0, "Loading failed");
+		free(_old_map3);
+		free(_old_vehicle_names);
+		return false;
+	}
+	DEBUG(oldloader, 3, "Done, converting game data...");
+
+	/* Fix some general stuff */
+	_settings_game.game_creation.landscape = _settings_game.game_creation.landscape & 0xF;
+
+	/* Remap some pointers */
+	_cur_town_ctr      = REMAP_TOWN_IDX(_old_cur_town_ctr);
+
+	/* _old_map3 is changed in _map3_lo and _map3_hi */
+	for (i = 0; i < OLD_MAP_SIZE; i++) {
+		_m[i].m3 = _old_map3[i * 2];
+		_m[i].m4 = _old_map3[i * 2 + 1];
+	}
+
+	for (i = 0; i < OLD_MAP_SIZE; i ++) {
+		switch (GetTileType(i)) {
+			case MP_STATION:
+				_m[i].m4 = 0; // We do not understand this TTDP station mapping (yet)
+				switch (_m[i].m5) {
+					/* We have drive through stops at a totally different place */
+					case 0x53: case 0x54: _m[i].m5 += 170 - 0x53; break; // Bus drive through
+					case 0x57: case 0x58: _m[i].m5 += 168 - 0x57; break; // Truck drive through
+					case 0x55: case 0x56: _m[i].m5 += 170 - 0x55; break; // Bus tram stop
+					case 0x59: case 0x5A: _m[i].m5 += 168 - 0x59; break; // Truck tram stop
+					default: break;
+				}
+				break;
+
+			case MP_RAILWAY:
+				/* We save presignals different from TTDPatch, convert them */
+				if (GetRailTileType(i) == RAIL_TILE_SIGNALS) {
+					/* This byte is always zero in TTD for this type of tile */
+					if (_m[i].m4) /* Convert the presignals to our own format */
+						_m[i].m4 = (_m[i].m4 >> 1) & 7;
+				}
+				/* TTDPatch stores PBS things in L6 and all elsewhere; so we'll just
+				 * clear it for ourselves and let OTTD's rebuild PBS itself */
+				_m[i].m4 &= 0xF; /* Only keep the lower four bits; upper four is PBS */
+				break;
+
+			case MP_WATER:
+				if (GetWaterClass(i) == 3) MakeRiver(i, Random());
+				break;
+
+			default:
+				break;
+		}
+	}
+
+	/* Make sure the available engines are really available, otherwise
+	 * we will get a "new vehicle"-spree. */
+	Engine *e;
+	FOR_ALL_ENGINES(e) {
+		if (_date >= (e->intro_date + 365)) {
+			e->flags = (e->flags & ~ENGINE_EXCLUSIVE_PREVIEW) | ENGINE_AVAILABLE;
+			e->company_avail = (CompanyMask)-1;
+		}
+	}
+
+	/* Fix the game to be compatible with OpenTTD */
+	FixOldTowns();
+	FixOldVehicles();
+
+	/* We have a new difficulty setting */
+	_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");
+
+	free(_old_map3);
+	free(_old_vehicle_names);
+
+	return true;
+}
+
+bool LoadOldSaveGame(const char *file)
+{
+	LoadgameState ls;
+
+	DEBUG(oldloader, 3, "Trying to load a TTD(Patch) savegame");
+
+	InitLoading(&ls);
+
+	/* Open file */
+	ls.file = fopen(file, "rb");
+
+	if (ls.file == NULL) {
+		DEBUG(oldloader, 0, "Cannot open file '%s'", file);
+		return false;
+	}
+
+	/* Load the main chunk */
+	if (!LoadOldMain(&ls)) return false;
+
+	fclose(ls.file);
+
+	/* Some old TTD(Patch) savegames could have buoys at tile 0
+	 * (without assigned station struct)
+	 * MakeWater() can be used as long as sea has the same
+	 * format as old savegames (eg. everything is zeroed) */
+	MakeWater(0);
+
+	_pause_game = 2;
+
+	return true;
+}
+
+void GetOldSaveGameName(char *title, const char *path, const char *file)
+{
+	char filename[MAX_PATH];
+	FILE *f;
+
+	snprintf(filename, lengthof(filename), "%s" PATHSEP "%s", path, file);
+	f = fopen(filename, "rb");
+	title[0] = '\0';
+	title[48] = '\0';
+
+	if (f == NULL) return;
+
+	if (fread(title, 1, 48, f) != 48) snprintf(title, 48, "Corrupt file");
+
+	fclose(f);
+}
new file mode 100644
--- /dev/null
+++ b/src/saveload/order_sl.cpp
@@ -0,0 +1,203 @@
+/* $Id$ */
+
+/** @file order_sl.cpp Code handling saving and loading of orders */
+
+#include "../stdafx.h"
+#include "../order_base.h"
+#include "../core/alloc_func.hpp"
+#include "../settings_type.h"
+
+#include "saveload.h"
+
+void Order::ConvertFromOldSavegame()
+{
+	uint8 old_flags = this->flags;
+	this->flags = 0;
+
+	/* First handle non-stop */
+	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 {
+		this->SetNonStopType((old_flags & 8) ? ONSF_NO_STOP_AT_INTERMEDIATE_STATIONS : ONSF_STOP_EVERYWHERE);
+	}
+
+	switch (this->GetType()) {
+		/* Only a few types need the other savegame conversions. */
+		case OT_GOTO_DEPOT: case OT_GOTO_STATION: case OT_LOADING: break;
+		default: return;
+	}
+
+	if (this->GetType() != OT_GOTO_DEPOT) {
+		/* Then the load flags */
+		if ((old_flags & 2) != 0) { // OFB_UNLOAD
+			this->SetLoadType(OLFB_NO_LOAD);
+		} else if ((old_flags & 4) == 0) { // !OFB_FULL_LOAD
+			this->SetLoadType(OLF_LOAD_IF_POSSIBLE);
+		} else {
+			this->SetLoadType(_settings_client.gui.sg_full_load_any ? OLF_FULL_LOAD_ANY : OLFB_FULL_LOAD);
+		}
+
+		/* Finally fix the unload flags */
+		if ((old_flags & 1) != 0) { // OFB_TRANSFER
+			this->SetUnloadType(OUFB_TRANSFER);
+		} else if ((old_flags & 2) != 0) { // OFB_UNLOAD
+			this->SetUnloadType(OUFB_UNLOAD);
+		} else {
+			this->SetUnloadType(OUF_UNLOAD_IF_POSSIBLE);
+		}
+	} else {
+		/* Then the depot action flags */
+		this->SetDepotActionType(((old_flags & 6) == 4) ? ODATFB_HALT : ODATF_SERVICE_ONLY);
+
+		/* Finally fix the depot type flags */
+		uint t = ((old_flags & 6) == 6) ? ODTFB_SERVICE : ODTF_MANUAL;
+		if ((old_flags & 2) != 0) t |= ODTFB_PART_OF_ORDERS;
+		this->SetDepotOrderType((OrderDepotTypeFlags)t);
+	}
+}
+
+/** Unpacks a order from savegames with version 4 and lower
+ * @param packed packed order
+ * @return unpacked order
+ */
+static Order UnpackVersion4Order(uint16 packed)
+{
+	return Order(GB(packed, 8, 8) << 16 | GB(packed, 4, 4) << 8 | GB(packed, 0, 4));
+}
+
+/** Unpacks a order from savegames made with TTD(Patch)
+ * @param packed packed order
+ * @return unpacked order
+ */
+Order UnpackOldOrder(uint16 packed)
+{
+	Order order = UnpackVersion4Order(packed);
+
+	/*
+	 * Sanity check
+	 * TTD stores invalid orders as OT_NOTHING with non-zero flags/station
+	 */
+	if (!order.IsValid() && packed != 0) order.MakeDummy();
+
+	return order;
+}
+
+const SaveLoad *GetOrderDescription()
+{
+	static const SaveLoad _order_desc[] = {
+		     SLE_VAR(Order, type,           SLE_UINT8),
+		     SLE_VAR(Order, flags,          SLE_UINT8),
+		     SLE_VAR(Order, dest,           SLE_UINT16),
+		     SLE_REF(Order, next,           REF_ORDER),
+		 SLE_CONDVAR(Order, refit_cargo,    SLE_UINT8,   36, SL_MAX_VERSION),
+		 SLE_CONDVAR(Order, refit_subtype,  SLE_UINT8,   36, SL_MAX_VERSION),
+		 SLE_CONDVAR(Order, wait_time,      SLE_UINT16,  67, SL_MAX_VERSION),
+		 SLE_CONDVAR(Order, travel_time,    SLE_UINT16,  67, SL_MAX_VERSION),
+
+		/* Leftover from the minor savegame version stuff
+		 * We will never use those free bytes, but we have to keep this line to allow loading of old savegames */
+		SLE_CONDNULL(10,                                  5,  35),
+		     SLE_END()
+	};
+
+	return _order_desc;
+}
+
+static void Save_ORDR()
+{
+	Order *order;
+
+	FOR_ALL_ORDERS(order) {
+		SlSetArrayIndex(order->index);
+		SlObject(order, GetOrderDescription());
+	}
+}
+
+static void Load_ORDR()
+{
+	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) */
+		size_t len = SlGetFieldLength();
+		uint i;
+
+		if (CheckSavegameVersion(5)) {
+			/* Pre-version 5 had an other layout for orders
+			    (uint16 instead of uint32) */
+			len /= sizeof(uint16);
+			uint16 *orders = MallocT<uint16>(len + 1);
+
+			SlArray(orders, len, SLE_UINT16);
+
+			for (i = 0; i < len; ++i) {
+				Order *order = new (i) Order();
+				order->AssignOrder(UnpackVersion4Order(orders[i]));
+			}
+
+			free(orders);
+		} else if (CheckSavegameVersionOldStyle(5, 2)) {
+			len /= sizeof(uint16);
+			uint16 *orders = MallocT<uint16>(len + 1);
+
+			SlArray(orders, len, SLE_UINT32);
+
+			for (i = 0; i < len; ++i) {
+				new (i) Order(orders[i]);
+			}
+
+			free(orders);
+		}
+
+		/* Update all the next pointer */
+		for (i = 1; i < len; ++i) {
+			/* The orders were built like this:
+			 *   While the order is valid, set the previous will get it's next pointer set
+			 *   We start with index 1 because no order will have the first in it's next pointer */
+			if (GetOrder(i)->IsValid())
+				GetOrder(i - 1)->next = GetOrder(i);
+		}
+	} else {
+		int index;
+
+		while ((index = SlIterateArray()) != -1) {
+			Order *order = new (index) Order();
+			SlObject(order, GetOrderDescription());
+		}
+	}
+}
+
+const SaveLoad *GetOrderListDescription()
+{
+	static const SaveLoad _orderlist_desc[] = {
+		SLE_REF(OrderList, first,              REF_ORDER),
+		SLE_END()
+	};
+
+	return _orderlist_desc;
+}
+
+static void Save_ORDL()
+{
+	OrderList *list;
+
+	FOR_ALL_ORDER_LISTS(list) {
+		SlSetArrayIndex(list->index);
+		SlObject(list, GetOrderListDescription());
+	}
+}
+
+static void Load_ORDL()
+{
+	int index;
+
+	while ((index = SlIterateArray()) != -1) {
+		OrderList *list = new (index) OrderList();
+		SlObject(list, GetOrderListDescription());
+	}
+}
+
+extern const ChunkHandler _order_chunk_handlers[] = {
+	{ 'ORDR', Save_ORDR, Load_ORDR, CH_ARRAY},
+	{ 'ORDL', Save_ORDL, Load_ORDL, CH_ARRAY | CH_LAST},
+};
new file mode 100644
--- /dev/null
+++ b/src/saveload/saveload.cpp
@@ -0,0 +1,1899 @@
+/* $Id$ */
+
+/** @file saveload.cpp
+ * All actions handling saving and loading goes on in this file. The general actions
+ * are as follows for saving a game (loading is analogous):
+ * <ol>
+ * <li>initialize the writer by creating a temporary memory-buffer for it
+ * <li>go through all to-be saved elements, each 'chunk' (ChunkHandler) prefixed by a label
+ * <li>use their description array (SaveLoad) to know what elements to save and in what version
+ *    of the game it was active (used when loading)
+ * <li>write all data byte-by-byte to the temporary buffer so it is endian-safe
+ * <li>when the buffer is full; flush it to the output (eg save to file) (_sl.buf, _sl.bufp, _sl.bufe)
+ * <li>repeat this until everything is done, and flush any remaining output to file
+ * </ol>
+ */
+#include "../stdafx.h"
+#include "../openttd.h"
+#include "../debug.h"
+#include "../station_base.h"
+#include "../thread.h"
+#include "../town.h"
+#include "../network/network.h"
+#include "../variables.h"
+#include "../window_func.h"
+#include "../strings_func.h"
+#include "../gfx_func.h"
+#include "../core/alloc_func.hpp"
+#include "../functions.h"
+#include "../core/endian_func.hpp"
+#include "../vehicle_base.h"
+#include "../company_func.h"
+#include "../date_func.h"
+#include "../autoreplace_base.h"
+#include "../statusbar_gui.h"
+#include "../fileio_func.h"
+#include "../gamelog.h"
+
+#include "table/strings.h"
+
+#include "saveload.h"
+#include "saveload_internal.h"
+
+#include <list>
+
+extern const uint16 SAVEGAME_VERSION = 105;
+
+SavegameType _savegame_type; ///< type of savegame we are loading
+
+uint32 _ttdp_version;     ///< version of TTDP savegame (if applicable)
+uint16 _sl_version;       ///< the major savegame version identifier
+byte   _sl_minor_version; ///< the minor savegame version, DO NOT USE!
+
+typedef void WriterProc(size_t len);
+typedef size_t ReaderProc();
+
+/** The saveload struct, containing reader-writer functions, bufffer, version, etc. */
+static struct {
+	bool save;                           ///< are we doing a save or a load atm. True when saving
+	byte need_length;                    ///< ???
+	byte block_mode;                     ///< ???
+	bool error;                          ///< did an error occur or not
+
+	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
+
+	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
+
+	const ChunkHandler* const *chs;      ///< the chunk of data that is being processed atm (vehicles, signs, etc.)
+
+	/* When saving/loading savegames, they are always saved to a temporary memory-place
+	 * to be flushed to file (save) or to final place (load) when full. */
+	byte *bufp, *bufe;                   ///< bufp(ointer) gives the current position in the buffer bufe(nd) gives the end of the buffer
+
+	/* these 3 may be used by compressor/decompressors. */
+	byte *buf;                           ///< pointer to temporary memory to read/write, initialized by SaveLoadFormat->initread/write
+	byte *buf_ori;                       ///< pointer to the original memory location of buf, used to free it afterwards
+	uint bufsize;                        ///< the size of the temporary memory *buf
+	FILE *fh;                            ///< the file from which is read or written to
+
+	void (*excpt_uninit)();              ///< the function to execute on any encountered error
+	StringID error_str;                  ///< the translateable error message to show
+	char *extra_msg;                     ///< the error message
+} _sl;
+
+
+enum NeedLengthValues {NL_NONE = 0, NL_WANTLENGTH = 1, NL_CALCLENGTH = 2};
+
+/** Error handler, calls longjmp to simulate an exception.
+ * @todo this was used to have a central place to handle errors, but it is
+ * pretty ugly, and seriously interferes with any multithreaded approaches */
+static void NORETURN SlError(StringID string, const char *extra_msg = NULL)
+{
+	_sl.error_str = string;
+	free(_sl.extra_msg);
+	_sl.extra_msg = (extra_msg == NULL) ? NULL : strdup(extra_msg);
+	throw std::exception();
+}
+
+typedef void (*AsyncSaveFinishProc)();
+static AsyncSaveFinishProc _async_save_finish = NULL;
+static ThreadObject *_save_thread;
+
+/**
+ * Called by save thread to tell we finished saving.
+ */
+static void SetAsyncSaveFinish(AsyncSaveFinishProc proc)
+{
+	if (_exit_game) return;
+	while (_async_save_finish != NULL) CSleep(10);
+
+	_async_save_finish = proc;
+}
+
+/**
+ * Handle async save finishes.
+ */
+void ProcessAsyncSaveFinish()
+{
+	if (_async_save_finish == NULL) return;
+
+	_async_save_finish();
+
+	_async_save_finish = NULL;
+
+	if (_save_thread != NULL) {
+		_save_thread->Join();
+		delete _save_thread;
+		_save_thread = NULL;
+	}
+}
+
+/**
+ * Fill the input buffer by reading from the file with the given reader
+ */
+static void SlReadFill()
+{
+	size_t len = _sl.read_bytes();
+	if (len == 0) SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME, "Unexpected end of chunk");
+
+	_sl.bufp = _sl.buf;
+	_sl.bufe = _sl.buf + len;
+	_sl.offs_base += len;
+}
+
+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
+ * @param conv VarType type of variable that is used for calculating the size
+ * @return Return the size of this type in bytes */
+static inline byte SlCalcConvMemLen(VarType conv)
+{
+	static const byte conv_mem_size[] = {1, 1, 1, 2, 2, 4, 4, 8, 8, 0};
+	byte length = GB(conv, 4, 4);
+	assert(length < lengthof(conv_mem_size));
+	return conv_mem_size[length];
+}
+
+/** Return the size in bytes of a certain type of normal/atomic variable
+ * as it appears in a saved game. See VarTypes
+ * @param conv VarType type of variable that is used for calculating the size
+ * @return Return the size of this type in bytes */
+static inline byte SlCalcConvFileLen(VarType conv)
+{
+	static const byte conv_file_size[] = {1, 1, 2, 2, 4, 4, 8, 8, 2};
+	byte length = GB(conv, 0, 4);
+	assert(length < lengthof(conv_file_size));
+	return conv_file_size[length];
+}
+
+/** Return the size in bytes of a reference (pointer) */
+static inline size_t SlCalcRefLen() {return CheckSavegameVersion(69) ? 2 : 4;}
+
+/** Flush the output buffer by writing to disk with the given reader.
+ * If the buffer pointer has not yet been set up, set it up now. Usually
+ * only called when the buffer is full, or there is no more data to be processed
+ */
+static void SlWriteFill()
+{
+	/* flush the buffer to disk (the writer) */
+	if (_sl.bufp != NULL) {
+		uint len = _sl.bufp - _sl.buf;
+		_sl.offs_base += len;
+		if (len) _sl.write_bytes(len);
+	}
+
+	/* All the data from the buffer has been written away, rewind to the beginning
+	 * to start reading in more data */
+	_sl.bufp = _sl.buf;
+	_sl.bufe = _sl.buf + _sl.bufsize;
+}
+
+/** Read in a single byte from file. If the temporary buffer is full,
+ * flush it to its final destination
+ * @return return the read byte from file
+ */
+static inline byte SlReadByteInternal()
+{
+	if (_sl.bufp == _sl.bufe) SlReadFill();
+	return *_sl.bufp++;
+}
+
+/** Wrapper for SlReadByteInternal */
+byte SlReadByte() {return SlReadByteInternal();}
+
+/** Write away a single byte from memory. If the temporary buffer is full,
+ * flush it to its destination (file)
+ * @param b the byte that is currently written
+ */
+static inline void SlWriteByteInternal(byte b)
+{
+	if (_sl.bufp == _sl.bufe) SlWriteFill();
+	*_sl.bufp++ = b;
+}
+
+/** Wrapper for SlWriteByteInternal */
+void SlWriteByte(byte b) {SlWriteByteInternal(b);}
+
+static inline int SlReadUint16()
+{
+	int x = SlReadByte() << 8;
+	return x | SlReadByte();
+}
+
+static inline uint32 SlReadUint32()
+{
+	uint32 x = SlReadUint16() << 16;
+	return x | SlReadUint16();
+}
+
+static inline uint64 SlReadUint64()
+{
+	uint32 x = SlReadUint32();
+	uint32 y = SlReadUint32();
+	return (uint64)x << 32 | y;
+}
+
+static inline void SlWriteUint16(uint16 v)
+{
+	SlWriteByte(GB(v, 8, 8));
+	SlWriteByte(GB(v, 0, 8));
+}
+
+static inline void SlWriteUint32(uint32 v)
+{
+	SlWriteUint16(GB(v, 16, 16));
+	SlWriteUint16(GB(v,  0, 16));
+}
+
+static inline void SlWriteUint64(uint64 x)
+{
+	SlWriteUint32((uint32)(x >> 32));
+	SlWriteUint32((uint32)x);
+}
+
+/**
+ * Read in the header descriptor of an object or an array.
+ * If the highest bit is set (7), then the index is bigger than 127
+ * elements, so use the next byte to read in the real value.
+ * The actual value is then both bytes added with the first shifted
+ * 8 bits to the left, and dropping the highest bit (which only indicated a big index).
+ * x = ((x & 0x7F) << 8) + SlReadByte();
+ * @return Return the value of the index
+ */
+static uint SlReadSimpleGamma()
+{
+	uint i = SlReadByte();
+	if (HasBit(i, 7)) {
+		i &= ~0x80;
+		if (HasBit(i, 6)) {
+			i &= ~0x40;
+			if (HasBit(i, 5)) {
+				i &= ~0x20;
+				if (HasBit(i, 4))
+					SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME, "Unsupported gamma");
+				i = (i << 8) | SlReadByte();
+			}
+			i = (i << 8) | SlReadByte();
+		}
+		i = (i << 8) | SlReadByte();
+	}
+	return i;
+}
+
+/**
+ * Write the header descriptor of an object or an array.
+ * If the element is bigger than 127, use 2 bytes for saving
+ * and use the highest byte of the first written one as a notice
+ * that the length consists of 2 bytes, etc.. like this:
+ * 0xxxxxxx
+ * 10xxxxxx xxxxxxxx
+ * 110xxxxx xxxxxxxx xxxxxxxx
+ * 1110xxxx xxxxxxxx xxxxxxxx xxxxxxxx
+ * @param i Index being written
+ */
+
+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)(i >> 16));
+			} else {
+				SlWriteByte((byte)(0xC0 | (i >> 16)));
+			}
+			SlWriteByte((byte)(i >> 8));
+		} else {
+			SlWriteByte((byte)(0x80 | (i >> 8)));
+		}
+	}
+	SlWriteByte((byte)i);
+}
+
+/** Return how many bytes used to encode a gamma value */
+static inline uint SlGetGammaLength(size_t i)
+{
+	return 1 + (i >= (1 << 7)) + (i >= (1 << 14)) + (i >= (1 << 21));
+}
+
+static inline uint SlReadSparseIndex() {return SlReadSimpleGamma();}
+static inline void SlWriteSparseIndex(uint index) {SlWriteSimpleGamma(index);}
+
+static inline uint SlReadArrayLength() {return SlReadSimpleGamma();}
+static inline void SlWriteArrayLength(size_t length) {SlWriteSimpleGamma(length);}
+static inline uint SlGetArrayLength(size_t length) {return SlGetGammaLength(length);}
+
+void SlSetArrayIndex(uint index)
+{
+	_sl.need_length = NL_WANTLENGTH;
+	_sl.array_index = index;
+}
+
+static size_t _next_offs;
+
+/**
+ * Iterate through the elements of an array and read the whole thing
+ * @return The index of the object, or -1 if we have reached the end of current block
+ */
+int SlIterateArray()
+{
+	int index;
+
+	/* After reading in the whole array inside the loop
+	 * we must have read in all the data, so we must be at end of current block. */
+	if (_next_offs != 0 && SlGetOffs() != _next_offs) SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME, "Invalid chunk size");
+
+	while (true) {
+		uint length = SlReadArrayLength();
+		if (length == 0) {
+			_next_offs = 0;
+			return -1;
+		}
+
+		_sl.obj_len = --length;
+		_next_offs = SlGetOffs() + length;
+
+		switch (_sl.block_mode) {
+		case CH_SPARSE_ARRAY: index = (int)SlReadSparseIndex(); break;
+		case CH_ARRAY:        index = _sl.array_index++; break;
+		default:
+			DEBUG(sl, 0, "SlIterateArray error");
+			return -1; // error
+		}
+
+		if (length != 0) return index;
+	}
+}
+
+/**
+ * Sets the length of either a RIFF object or the number of items in an array.
+ * This lets us load an object or an array of arbitrary size
+ * @param length The length of the sought object/array
+ */
+void SlSetLength(size_t length)
+{
+	assert(_sl.save);
+
+	switch (_sl.need_length) {
+	case NL_WANTLENGTH:
+		_sl.need_length = NL_NONE;
+		switch (_sl.block_mode) {
+		case CH_RIFF:
+			/* Ugly encoding of >16M RIFF chunks
+			 * The lower 24 bits are normal
+			 * The uppermost 4 bits are bits 24:27 */
+			assert(length < (1 << 28));
+			SlWriteUint32((uint32)((length & 0xFFFFFF) | ((length >> 24) << 28)));
+			break;
+		case CH_ARRAY:
+			assert(_sl.last_array_index <= _sl.array_index);
+			while (++_sl.last_array_index <= _sl.array_index)
+				SlWriteArrayLength(1);
+			SlWriteArrayLength(length + 1);
+			break;
+		case CH_SPARSE_ARRAY:
+			SlWriteArrayLength(length + 1 + SlGetArrayLength(_sl.array_index)); // Also include length of sparse index.
+			SlWriteSparseIndex(_sl.array_index);
+			break;
+		default: NOT_REACHED();
+		} break;
+	case NL_CALCLENGTH:
+		_sl.obj_len += (int)length;
+		break;
+	}
+}
+
+/**
+ * Save/Load bytes. These do not need to be converted to Little/Big Endian
+ * so directly write them or read them to/from file
+ * @param ptr The source or destination of the object being manipulated
+ * @param length number of bytes this fast CopyBytes lasts
+ */
+static void SlCopyBytes(void *ptr, size_t length)
+{
+	byte *p = (byte*)ptr;
+
+	if (_sl.save) {
+		for (; length != 0; length--) {SlWriteByteInternal(*p++);}
+	} else {
+		for (; length != 0; length--) {*p++ = SlReadByteInternal();}
+	}
+}
+
+/** Read in bytes from the file/data structure but don't do
+ * anything with them, discarding them in effect
+ * @param length The amount of bytes that is being treated this way
+ */
+static inline void SlSkipBytes(size_t length)
+{
+	for (; length != 0; length--) SlReadByte();
+}
+
+/* Get the length of the current object */
+size_t SlGetFieldLength() {return _sl.obj_len;}
+
+/** Return a signed-long version of the value of a setting
+ * @param ptr pointer to the variable
+ * @param conv type of variable, can be a non-clean
+ * type, eg one with other flags because it is parsed
+ * @return returns the value of the pointer-setting */
+int64 ReadValue(const void *ptr, VarType conv)
+{
+	switch (GetVarMemType(conv)) {
+	case SLE_VAR_BL:  return (*(bool*)ptr != 0);
+	case SLE_VAR_I8:  return *(int8*  )ptr;
+	case SLE_VAR_U8:  return *(byte*  )ptr;
+	case SLE_VAR_I16: return *(int16* )ptr;
+	case SLE_VAR_U16: return *(uint16*)ptr;
+	case SLE_VAR_I32: return *(int32* )ptr;
+	case SLE_VAR_U32: return *(uint32*)ptr;
+	case SLE_VAR_I64: return *(int64* )ptr;
+	case SLE_VAR_U64: return *(uint64*)ptr;
+	case SLE_VAR_NULL:return 0;
+	default: NOT_REACHED();
+	}
+
+	/* useless, but avoids compiler warning this way */
+	return 0;
+}
+
+/** Write the value of a setting
+ * @param ptr pointer to the variable
+ * @param conv type of variable, can be a non-clean type, eg
+ *             with other flags. It is parsed upon read
+ * @param val the new value being given to the variable */
+void WriteValue(void *ptr, VarType conv, int64 val)
+{
+	switch (GetVarMemType(conv)) {
+	case SLE_VAR_BL:  *(bool  *)ptr = (val != 0);  break;
+	case SLE_VAR_I8:  *(int8  *)ptr = val; break;
+	case SLE_VAR_U8:  *(byte  *)ptr = val; break;
+	case SLE_VAR_I16: *(int16 *)ptr = val; break;
+	case SLE_VAR_U16: *(uint16*)ptr = val; break;
+	case SLE_VAR_I32: *(int32 *)ptr = val; break;
+	case SLE_VAR_U32: *(uint32*)ptr = val; break;
+	case SLE_VAR_I64: *(int64 *)ptr = val; break;
+	case SLE_VAR_U64: *(uint64*)ptr = val; break;
+	case SLE_VAR_NAME: *(char**)ptr = CopyFromOldName(val); break;
+	case SLE_VAR_NULL: break;
+	default: NOT_REACHED();
+	}
+}
+
+/**
+ * Handle all conversion and typechecking of variables here.
+ * In the case of saving, read in the actual value from the struct
+ * and then write them to file, endian safely. Loading a value
+ * goes exactly the opposite way
+ * @param ptr The object being filled/read
+ * @param conv VarType type of the current element of the struct
+ */
+static void SlSaveLoadConv(void *ptr, VarType conv)
+{
+	int64 x = 0;
+
+	if (_sl.save) { // SAVE values
+		/* Read a value from the struct. These ARE endian safe. */
+		x = ReadValue(ptr, conv);
+
+		/* Write the value to the file and check if its value is in the desired range */
+		switch (GetVarFileType(conv)) {
+		case SLE_FILE_I8: assert(x >= -128 && x <= 127);     SlWriteByte(x);break;
+		case SLE_FILE_U8: assert(x >= 0 && x <= 255);        SlWriteByte(x);break;
+		case SLE_FILE_I16:assert(x >= -32768 && x <= 32767); SlWriteUint16(x);break;
+		case SLE_FILE_STRINGID:
+		case SLE_FILE_U16:assert(x >= 0 && x <= 65535);      SlWriteUint16(x);break;
+		case SLE_FILE_I32:
+		case SLE_FILE_U32:                                   SlWriteUint32((uint32)x);break;
+		case SLE_FILE_I64:
+		case SLE_FILE_U64:                                   SlWriteUint64(x);break;
+		default: NOT_REACHED();
+		}
+	} else { // LOAD values
+
+		/* Read a value from the file */
+		switch (GetVarFileType(conv)) {
+		case SLE_FILE_I8:  x = (int8  )SlReadByte();   break;
+		case SLE_FILE_U8:  x = (byte  )SlReadByte();   break;
+		case SLE_FILE_I16: x = (int16 )SlReadUint16(); break;
+		case SLE_FILE_U16: x = (uint16)SlReadUint16(); break;
+		case SLE_FILE_I32: x = (int32 )SlReadUint32(); break;
+		case SLE_FILE_U32: x = (uint32)SlReadUint32(); break;
+		case SLE_FILE_I64: x = (int64 )SlReadUint64(); break;
+		case SLE_FILE_U64: x = (uint64)SlReadUint64(); break;
+		case SLE_FILE_STRINGID: x = RemapOldStringID((uint16)SlReadUint16()); break;
+		default: NOT_REACHED();
+		}
+
+		/* Write The value to the struct. These ARE endian safe. */
+		WriteValue(ptr, conv, x);
+	}
+}
+
+/** Calculate the net length of a string. This is in almost all cases
+ * just strlen(), but if the string is not properly terminated, we'll
+ * resort to the maximum length of the buffer.
+ * @param ptr pointer to the stringbuffer
+ * @param length maximum length of the string (buffer). If -1 we don't care
+ * about a maximum length, but take string length as it is.
+ * @return return the net length of the string */
+static inline size_t SlCalcNetStringLen(const char *ptr, size_t length)
+{
+	if (ptr == NULL) return 0;
+	return min(strlen(ptr), length - 1);
+}
+
+/** Calculate the gross length of the string that it
+ * will occupy in the savegame. This includes the real length, returned
+ * by SlCalcNetStringLen and the length that the index will occupy.
+ * @param ptr pointer to the stringbuffer
+ * @param length maximum length of the string (buffer size, etc.)
+ * @param conv type of data been used
+ * @return return the gross length of the string */
+static inline size_t SlCalcStringLen(const void *ptr, size_t length, VarType conv)
+{
+	size_t len;
+	const char *str;
+
+	switch (GetVarMemType(conv)) {
+		default: NOT_REACHED();
+		case SLE_VAR_STR:
+		case SLE_VAR_STRQ:
+			str = *(const char**)ptr;
+			len = SIZE_MAX;
+			break;
+		case SLE_VAR_STRB:
+		case SLE_VAR_STRBQ:
+			str = (const char*)ptr;
+			len = length;
+			break;
+	}
+
+	len = SlCalcNetStringLen(str, len);
+	return len + SlGetArrayLength(len); // also include the length of the index
+}
+
+/**
+ * Save/Load a string.
+ * @param ptr the string being manipulated
+ * @param length of the string (full length)
+ * @param conv must be SLE_FILE_STRING */
+static void SlString(void *ptr, size_t length, VarType conv)
+{
+	size_t len;
+
+	if (_sl.save) { // SAVE string
+		switch (GetVarMemType(conv)) {
+			default: NOT_REACHED();
+			case SLE_VAR_STRB:
+			case SLE_VAR_STRBQ:
+				len = SlCalcNetStringLen((char*)ptr, length);
+				break;
+			case SLE_VAR_STR:
+			case SLE_VAR_STRQ:
+				ptr = *(char**)ptr;
+				len = SlCalcNetStringLen((char*)ptr, SIZE_MAX);
+				break;
+		}
+
+		SlWriteArrayLength(len);
+		SlCopyBytes(ptr, len);
+	} else { // LOAD string
+		len = SlReadArrayLength();
+
+		switch (GetVarMemType(conv)) {
+			default: NOT_REACHED();
+			case SLE_VAR_STRB:
+			case SLE_VAR_STRBQ:
+				if (len >= length) {
+					DEBUG(sl, 1, "String length in savegame is bigger than buffer, truncating");
+					SlCopyBytes(ptr, length);
+					SlSkipBytes(len - length);
+					len = length - 1;
+				} else {
+					SlCopyBytes(ptr, len);
+				}
+				break;
+			case SLE_VAR_STR:
+			case SLE_VAR_STRQ: // Malloc'd string, free previous incarnation, and allocate
+				free(*(char**)ptr);
+				if (len == 0) {
+					*(char**)ptr = NULL;
+				} else {
+					*(char**)ptr = MallocT<char>(len + 1); // terminating '\0'
+					ptr = *(char**)ptr;
+					SlCopyBytes(ptr, len);
+				}
+				break;
+		}
+
+		((char*)ptr)[len] = '\0'; // properly terminate the string
+	}
+}
+
+/**
+ * Return the size in bytes of a certain type of atomic array
+ * @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(size_t length, VarType conv)
+{
+	return SlCalcConvFileLen(conv) * length;
+}
+
+/**
+ * Save/Load an array.
+ * @param array The array being manipulated
+ * @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, size_t length, VarType conv)
+{
+	/* Automatically calculate the length? */
+	if (_sl.need_length != NL_NONE) {
+		SlSetLength(SlCalcArrayLen(length, conv));
+		/* Determine length only? */
+		if (_sl.need_length == NL_CALCLENGTH) return;
+	}
+
+	/* NOTICE - handle some buggy stuff, in really old versions everything was saved
+	 * as a byte-type. So detect this, and adjust array size accordingly */
+	if (!_sl.save && _sl_version == 0) {
+		/* all arrays except difficulty settings */
+		if (conv == SLE_INT16 || conv == SLE_UINT16 || conv == SLE_STRINGID ||
+				conv == SLE_INT32 || conv == SLE_UINT32) {
+			SlCopyBytes(array, length * SlCalcConvFileLen(conv));
+			return;
+		}
+		/* used for conversion of Money 32bit->64bit */
+		if (conv == (SLE_FILE_I32 | SLE_VAR_I64)) {
+			for (uint i = 0; i < length; i++) {
+				((int64*)array)[i] = (int32)BSWAP32(SlReadUint32());
+			}
+			return;
+		}
+	}
+
+	/* If the size of elements is 1 byte both in file and memory, no special
+	 * conversion is needed, use specialized copy-copy function to speed up things */
+	if (conv == SLE_INT8 || conv == SLE_UINT8) {
+		SlCopyBytes(array, length);
+	} else {
+		byte *a = (byte*)array;
+		byte mem_size = SlCalcConvMemLen(conv);
+
+		for (; length != 0; length --) {
+			SlSaveLoadConv(a, conv);
+			a += mem_size; // get size
+		}
+	}
+}
+
+
+static uint ReferenceToInt(const void* obj, SLRefType rt);
+static void* IntToReference(uint index, SLRefType rt);
+
+
+/**
+ * Return the size in bytes of a list
+ * @param list The std::list to find the size of
+ */
+static inline size_t SlCalcListLen(const void *list)
+{
+	std::list<void *> *l = (std::list<void *> *) list;
+
+	int type_size = CheckSavegameVersion(69) ? 2 : 4;
+	/* Each entry is saved as type_size bytes, plus type_size bytes are used for the length
+	 * of the list */
+	return l->size() * type_size + type_size;
+}
+
+
+/**
+ * Save/Load a list.
+ * @param list The list being manipulated
+ * @param conv SLRefType type of the list (Vehicle *, Station *, etc)
+ */
+void SlList(void *list, SLRefType conv)
+{
+	/* Automatically calculate the length? */
+	if (_sl.need_length != NL_NONE) {
+		SlSetLength(SlCalcListLen(list));
+		/* Determine length only? */
+		if (_sl.need_length == NL_CALCLENGTH) return;
+	}
+
+	std::list<void *> *l = (std::list<void *> *) list;
+
+	if (_sl.save) {
+		SlWriteUint32((uint32)l->size());
+
+		std::list<void *>::iterator iter;
+		for (iter = l->begin(); iter != l->end(); ++iter) {
+			void *ptr = *iter;
+			SlWriteUint32(ReferenceToInt(ptr, conv));
+		}
+	} else {
+		uint length = CheckSavegameVersion(69) ? SlReadUint16() : SlReadUint32();
+
+		/* Load each reference and push to the end of the list */
+		for (uint i = 0; i < length; i++) {
+			void *ptr = IntToReference(CheckSavegameVersion(69) ? SlReadUint16() : SlReadUint32(), conv);
+			l->push_back(ptr);
+		}
+	}
+}
+
+
+/** Are we going to save this object or not? */
+static inline bool SlIsObjectValidInSavegame(const SaveLoad *sld)
+{
+	if (_sl_version < sld->version_from || _sl_version > sld->version_to) return false;
+	if (sld->conv & SLF_SAVE_NO) return false;
+
+	return true;
+}
+
+/** Are we going to load this variable when loading a savegame or not?
+ * @note If the variable is skipped it is skipped in the savegame
+ * bytestream itself as well, so there is no need to skip it somewhere else */
+static inline bool SlSkipVariableOnLoad(const SaveLoad *sld)
+{
+	if ((sld->conv & SLF_NETWORK_NO) && !_sl.save && _networking && !_network_server) {
+		SlSkipBytes(SlCalcConvMemLen(sld->conv) * sld->length);
+		return true;
+	}
+
+	return false;
+}
+
+/**
+ * Calculate the size of an object.
+ * @param object to be measured
+ * @param sld The SaveLoad description of the object so we know how to manipulate it
+ * @return size of given objetc
+ */
+size_t SlCalcObjLength(const void *object, const SaveLoad *sld)
+{
+	size_t length = 0;
+
+	/* Need to determine the length and write a length tag. */
+	for (; sld->cmd != SL_END; sld++) {
+		length += SlCalcObjMemberLength(object, sld);
+	}
+	return length;
+}
+
+size_t SlCalcObjMemberLength(const void *object, const SaveLoad *sld)
+{
+	assert(_sl.save);
+
+	switch (sld->cmd) {
+		case SL_VAR:
+		case SL_REF:
+		case SL_ARR:
+		case SL_STR:
+		case SL_LST:
+			/* CONDITIONAL saveload types depend on the savegame version */
+			if (!SlIsObjectValidInSavegame(sld)) break;
+
+			switch (sld->cmd) {
+			case SL_VAR: return SlCalcConvFileLen(sld->conv);
+			case SL_REF: return SlCalcRefLen();
+			case SL_ARR: return SlCalcArrayLen(sld->length, sld->conv);
+			case SL_STR: return SlCalcStringLen(GetVariableAddress(object, sld), sld->length, sld->conv);
+			case SL_LST: return SlCalcListLen(GetVariableAddress(object, sld));
+			default: NOT_REACHED();
+			}
+			break;
+		case SL_WRITEBYTE: return 1; // a byte is logically of size 1
+		case SL_VEH_INCLUDE: return SlCalcObjLength(object, GetVehicleDescription(VEH_END));
+		default: NOT_REACHED();
+	}
+	return 0;
+}
+
+
+bool SlObjectMember(void *ptr, const SaveLoad *sld)
+{
+	VarType conv = GB(sld->conv, 0, 8);
+	switch (sld->cmd) {
+	case SL_VAR:
+	case SL_REF:
+	case SL_ARR:
+	case SL_STR:
+	case SL_LST:
+		/* CONDITIONAL saveload types depend on the savegame version */
+		if (!SlIsObjectValidInSavegame(sld)) return false;
+		if (SlSkipVariableOnLoad(sld)) return false;
+
+		switch (sld->cmd) {
+		case SL_VAR: SlSaveLoadConv(ptr, conv); break;
+		case SL_REF: // Reference variable, translate
+			if (_sl.save) {
+				SlWriteUint32(ReferenceToInt(*(void**)ptr, (SLRefType)conv));
+			} else {
+				*(void**)ptr = IntToReference(CheckSavegameVersion(69) ? SlReadUint16() : SlReadUint32(), (SLRefType)conv);
+			}
+			break;
+		case SL_ARR: SlArray(ptr, sld->length, conv); break;
+		case SL_STR: SlString(ptr, sld->length, conv); break;
+		case SL_LST: SlList(ptr, (SLRefType)conv); break;
+		default: NOT_REACHED();
+		}
+		break;
+
+	/* SL_WRITEBYTE translates a value of a variable to another one upon
+	 * saving or loading.
+	 * XXX - variable renaming abuse
+	 * game_value: the value of the variable ingame is abused by sld->version_from
+	 * file_value: the value of the variable in the savegame is abused by sld->version_to */
+	case SL_WRITEBYTE:
+		if (_sl.save) {
+			SlWriteByte(sld->version_to);
+		} else {
+			*(byte*)ptr = sld->version_from;
+		}
+		break;
+
+	/* SL_VEH_INCLUDE loads common code for vehicles */
+	case SL_VEH_INCLUDE:
+		SlObject(ptr, GetVehicleDescription(VEH_END));
+		break;
+	default: NOT_REACHED();
+	}
+	return true;
+}
+
+/**
+ * Main SaveLoad function.
+ * @param object The object that is being saved or loaded
+ * @param sld The SaveLoad description of the object so we know how to manipulate it
+ */
+void SlObject(void *object, const SaveLoad *sld)
+{
+	/* Automatically calculate the length? */
+	if (_sl.need_length != NL_NONE) {
+		SlSetLength(SlCalcObjLength(object, sld));
+		if (_sl.need_length == NL_CALCLENGTH) return;
+	}
+
+	for (; sld->cmd != SL_END; sld++) {
+		void *ptr = sld->global ? sld->address : GetVariableAddress(object, sld);
+		SlObjectMember(ptr, sld);
+	}
+}
+
+/**
+ * Save or Load (a list of) global variables
+ * @param sldg The global variable that is being loaded or saved
+ */
+void SlGlobList(const SaveLoadGlobVarList *sldg)
+{
+	SlObject(NULL, (const SaveLoad*)sldg);
+}
+
+/**
+ * Do something of which I have no idea what it is :P
+ * @param proc The callback procedure that is called
+ * @param arg The variable that will be used for the callback procedure
+ */
+void SlAutolength(AutolengthProc *proc, void *arg)
+{
+	size_t offs;
+
+	assert(_sl.save);
+
+	/* Tell it to calculate the length */
+	_sl.need_length = NL_CALCLENGTH;
+	_sl.obj_len = 0;
+	proc(arg);
+
+	/* Setup length */
+	_sl.need_length = NL_WANTLENGTH;
+	SlSetLength(_sl.obj_len);
+
+	offs = SlGetOffs() + _sl.obj_len;
+
+	/* And write the stuff */
+	proc(arg);
+
+	if (offs != SlGetOffs()) SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME, "Invalid chunk size");
+}
+
+/**
+ * Load a chunk of data (eg vehicles, stations, etc.)
+ * @param ch The chunkhandler that will be used for the operation
+ */
+static void SlLoadChunk(const ChunkHandler *ch)
+{
+	byte m = SlReadByte();
+	size_t len;
+	size_t endoffs;
+
+	_sl.block_mode = m;
+	_sl.obj_len = 0;
+
+	switch (m) {
+	case CH_ARRAY:
+		_sl.array_index = 0;
+		ch->load_proc();
+		break;
+	case CH_SPARSE_ARRAY:
+		ch->load_proc();
+		break;
+	default:
+		if ((m & 0xF) == CH_RIFF) {
+			/* Read length */
+			len = (SlReadByte() << 16) | ((m >> 4) << 24);
+			len += SlReadUint16();
+			_sl.obj_len = len;
+			endoffs = SlGetOffs() + len;
+			ch->load_proc();
+			if (SlGetOffs() != endoffs) SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME, "Invalid chunk size");
+		} else {
+			SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME, "Invalid chunk type");
+		}
+		break;
+	}
+}
+
+/* Stub Chunk handlers to only calculate length and do nothing else */
+static ChunkSaveLoadProc *_tmp_proc_1;
+static inline void SlStubSaveProc2(void *arg) {_tmp_proc_1();}
+static void SlStubSaveProc() {SlAutolength(SlStubSaveProc2, NULL);}
+
+/** Save a chunk of data (eg. vehicles, stations, etc.). Each chunk is
+ * prefixed by an ID identifying it, followed by data, and terminator where appropiate
+ * @param ch The chunkhandler that will be used for the operation
+ */
+static void SlSaveChunk(const ChunkHandler *ch)
+{
+	ChunkSaveLoadProc *proc = ch->save_proc;
+
+	/* Don't save any chunk information if there is no save handler. */
+	if (proc == NULL) return;
+
+	SlWriteUint32(ch->id);
+	DEBUG(sl, 2, "Saving chunk %c%c%c%c", ch->id >> 24, ch->id >> 16, ch->id >> 8, ch->id);
+
+	if (ch->flags & CH_AUTO_LENGTH) {
+		/* Need to calculate the length. Solve that by calling SlAutoLength in the save_proc. */
+		_tmp_proc_1 = proc;
+		proc = SlStubSaveProc;
+	}
+
+	_sl.block_mode = ch->flags & CH_TYPE_MASK;
+	switch (ch->flags & CH_TYPE_MASK) {
+	case CH_RIFF:
+		_sl.need_length = NL_WANTLENGTH;
+		proc();
+		break;
+	case CH_ARRAY:
+		_sl.last_array_index = 0;
+		SlWriteByte(CH_ARRAY);
+		proc();
+		SlWriteArrayLength(0); // Terminate arrays
+		break;
+	case CH_SPARSE_ARRAY:
+		SlWriteByte(CH_SPARSE_ARRAY);
+		proc();
+		SlWriteArrayLength(0); // Terminate arrays
+		break;
+	default: NOT_REACHED();
+	}
+}
+
+/** Save all chunks */
+static void SlSaveChunks()
+{
+	const ChunkHandler *ch;
+	const ChunkHandler* const *chsc;
+	uint p;
+
+	for (p = 0; p != CH_NUM_PRI_LEVELS; p++) {
+		for (chsc = _sl.chs; (ch = *chsc++) != NULL;) {
+			while (true) {
+				if (((ch->flags >> CH_PRI_SHL) & (CH_NUM_PRI_LEVELS - 1)) == p)
+					SlSaveChunk(ch);
+				if (ch->flags & CH_LAST)
+					break;
+				ch++;
+			}
+		}
+	}
+
+	/* Terminator */
+	SlWriteUint32(0);
+}
+
+/** Find the ChunkHandler that will be used for processing the found
+ * chunk in the savegame or in memory
+ * @param id the chunk in question
+ * @return returns the appropiate chunkhandler
+ */
+static const ChunkHandler *SlFindChunkHandler(uint32 id)
+{
+	const ChunkHandler *ch;
+	const ChunkHandler *const *chsc;
+	for (chsc = _sl.chs; (ch = *chsc++) != NULL;) {
+		for (;;) {
+			if (ch->id == id) return ch;
+			if (ch->flags & CH_LAST) break;
+			ch++;
+		}
+	}
+	return NULL;
+}
+
+/** Load all chunks */
+static void SlLoadChunks()
+{
+	uint32 id;
+	const ChunkHandler *ch;
+
+	for (id = SlReadUint32(); id != 0; id = SlReadUint32()) {
+		DEBUG(sl, 2, "Loading chunk %c%c%c%c", id >> 24, id >> 16, id >> 8, id);
+
+		ch = SlFindChunkHandler(id);
+		if (ch == NULL) SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME, "Unknown chunk type");
+		SlLoadChunk(ch);
+	}
+}
+
+/*******************************************
+ ********** START OF LZO CODE **************
+ *******************************************/
+#define LZO_SIZE 8192
+
+#include "../minilzo.h"
+
+static size_t ReadLZO()
+{
+	byte out[LZO_SIZE + LZO_SIZE / 64 + 16 + 3 + 8];
+	uint32 tmp[2];
+	uint32 size;
+	uint len;
+
+	/* Read header*/
+	if (fread(tmp, sizeof(tmp), 1, _sl.fh) != 1) SlError(STR_GAME_SAVELOAD_ERROR_FILE_NOT_READABLE, "File read failed");
+
+	/* Check if size is bad */
+	((uint32*)out)[0] = size = tmp[1];
+
+	if (_sl_version != 0) {
+		tmp[0] = TO_BE32(tmp[0]);
+		size = TO_BE32(size);
+	}
+
+	if (size >= sizeof(out)) SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME, "Inconsistent size");
+
+	/* Read block */
+	if (fread(out + sizeof(uint32), size, 1, _sl.fh) != 1) SlError(STR_GAME_SAVELOAD_ERROR_FILE_NOT_READABLE);
+
+	/* Verify checksum */
+	if (tmp[0] != lzo_adler32(0, out, size + sizeof(uint32))) SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME, "Bad checksum");
+
+	/* Decompress */
+	lzo1x_decompress(out + sizeof(uint32)*1, size, _sl.buf, &len, NULL);
+	return len;
+}
+
+/* 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(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, (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);
+}
+
+static bool InitLZO()
+{
+	_sl.bufsize = LZO_SIZE;
+	_sl.buf = _sl.buf_ori = MallocT<byte>(LZO_SIZE);
+	return true;
+}
+
+static void UninitLZO()
+{
+	free(_sl.buf_ori);
+}
+
+/*********************************************
+ ******** START OF NOCOMP CODE (uncompressed)*
+ *********************************************/
+static size_t ReadNoComp()
+{
+	return fread(_sl.buf, 1, LZO_SIZE, _sl.fh);
+}
+
+static void WriteNoComp(size_t size)
+{
+	if (fwrite(_sl.buf, 1, size, _sl.fh) != size) SlError(STR_GAME_SAVELOAD_ERROR_FILE_NOT_WRITEABLE);
+}
+
+static bool InitNoComp()
+{
+	_sl.bufsize = LZO_SIZE;
+	_sl.buf = _sl.buf_ori = MallocT<byte>(LZO_SIZE);
+	return true;
+}
+
+static void UninitNoComp()
+{
+	free(_sl.buf_ori);
+}
+
+/********************************************
+ ********** START OF MEMORY CODE (in ram)****
+ ********************************************/
+
+#include "../table/sprites.h"
+#include "../gui.h"
+
+struct ThreadedSave {
+	uint count;
+	byte ff_state;
+	bool saveinprogress;
+	CursorID cursor;
+};
+
+/* A maximum size of of 128K * 500 = 64.000KB savegames */
+STATIC_OLD_POOL(Savegame, byte, 17, 500, NULL, NULL)
+static ThreadedSave _ts;
+
+static bool InitMem()
+{
+	_ts.count = 0;
+
+	_Savegame_pool.CleanPool();
+	_Savegame_pool.AddBlockToPool();
+
+	/* A block from the pool is a contigious area of memory, so it is safe to write to it sequentially */
+	_sl.bufsize = GetSavegamePoolSize();
+	_sl.buf = GetSavegame(_ts.count);
+	return true;
+}
+
+static void UnInitMem()
+{
+	_Savegame_pool.CleanPool();
+}
+
+static void WriteMem(size_t size)
+{
+	_ts.count += (uint)size;
+	/* Allocate new block and new buffer-pointer */
+	_Savegame_pool.AddBlockIfNeeded(_ts.count);
+	_sl.buf = GetSavegame(_ts.count);
+}
+
+/********************************************
+ ********** START OF ZLIB CODE **************
+ ********************************************/
+
+#if defined(WITH_ZLIB)
+#include <zlib.h>
+
+static z_stream _z;
+
+static bool InitReadZlib()
+{
+	memset(&_z, 0, sizeof(_z));
+	if (inflateInit(&_z) != Z_OK) return false;
+
+	_sl.bufsize = 4096;
+	_sl.buf = _sl.buf_ori = MallocT<byte>(4096 + 4096); // also contains fread buffer
+	return true;
+}
+
+static size_t ReadZlib()
+{
+	int r;
+
+	_z.next_out = _sl.buf;
+	_z.avail_out = 4096;
+
+	do {
+		/* read more bytes from the file? */
+		if (_z.avail_in == 0) {
+			_z.avail_in = (uint)fread(_z.next_in = _sl.buf + 4096, 1, 4096, _sl.fh);
+		}
+
+		/* inflate the data */
+		r = inflate(&_z, 0);
+		if (r == Z_STREAM_END)
+			break;
+
+		if (r != Z_OK) SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR, "inflate() failed");
+	} while (_z.avail_out);
+
+	return 4096 - _z.avail_out;
+}
+
+static void UninitReadZlib()
+{
+	inflateEnd(&_z);
+	free(_sl.buf_ori);
+}
+
+static bool InitWriteZlib()
+{
+	memset(&_z, 0, sizeof(_z));
+	if (deflateInit(&_z, 6) != Z_OK) return false;
+
+	_sl.bufsize = 4096;
+	_sl.buf = _sl.buf_ori = MallocT<byte>(4096); // also contains fread buffer
+	return true;
+}
+
+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 = (uInt)len;
+	do {
+		z->next_out = buf;
+		z->avail_out = sizeof(buf);
+		r = deflate(z, mode);
+			/* bytes were emitted? */
+		if ((n = sizeof(buf) - z->avail_out) != 0) {
+			if (fwrite(buf, n, 1, _sl.fh) != 1) SlError(STR_GAME_SAVELOAD_ERROR_FILE_NOT_WRITEABLE);
+		}
+		if (r == Z_STREAM_END)
+			break;
+		if (r != Z_OK) SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR, "zlib returned error code");
+	} while (z->avail_in || !z->avail_out);
+}
+
+static void WriteZlib(size_t len)
+{
+	WriteZlibLoop(&_z, _sl.buf, len, 0);
+}
+
+static void UninitWriteZlib()
+{
+	/* flush any pending output. */
+	if (_sl.fh) WriteZlibLoop(&_z, NULL, 0, Z_FINISH);
+	deflateEnd(&_z);
+	free(_sl.buf_ori);
+}
+
+#endif /* WITH_ZLIB */
+
+/*******************************************
+ ************* END OF CODE *****************
+ *******************************************/
+
+/* these define the chunks */
+extern const ChunkHandler _gamelog_chunk_handlers[];
+extern const ChunkHandler _map_chunk_handlers[];
+extern const ChunkHandler _misc_chunk_handlers[];
+extern const ChunkHandler _name_chunk_handlers[];
+extern const ChunkHandler _cheat_chunk_handlers[] ;
+extern const ChunkHandler _setting_chunk_handlers[];
+extern const ChunkHandler _company_chunk_handlers[];
+extern const ChunkHandler _engine_chunk_handlers[];
+extern const ChunkHandler _veh_chunk_handlers[];
+extern const ChunkHandler _waypoint_chunk_handlers[];
+extern const ChunkHandler _depot_chunk_handlers[];
+extern const ChunkHandler _order_chunk_handlers[];
+extern const ChunkHandler _town_chunk_handlers[];
+extern const ChunkHandler _sign_chunk_handlers[];
+extern const ChunkHandler _station_chunk_handlers[];
+extern const ChunkHandler _industry_chunk_handlers[];
+extern const ChunkHandler _economy_chunk_handlers[];
+extern const ChunkHandler _subsidy_chunk_handlers[];
+extern const ChunkHandler _animated_tile_chunk_handlers[];
+extern const ChunkHandler _newgrf_chunk_handlers[];
+extern const ChunkHandler _group_chunk_handlers[];
+extern const ChunkHandler _cargopacket_chunk_handlers[];
+extern const ChunkHandler _autoreplace_chunk_handlers[];
+
+static const ChunkHandler * const _chunk_handlers[] = {
+	_gamelog_chunk_handlers,
+	_map_chunk_handlers,
+	_misc_chunk_handlers,
+	_name_chunk_handlers,
+	_cheat_chunk_handlers,
+	_setting_chunk_handlers,
+	_veh_chunk_handlers,
+	_waypoint_chunk_handlers,
+	_depot_chunk_handlers,
+	_order_chunk_handlers,
+	_industry_chunk_handlers,
+	_economy_chunk_handlers,
+	_subsidy_chunk_handlers,
+	_engine_chunk_handlers,
+	_town_chunk_handlers,
+	_sign_chunk_handlers,
+	_station_chunk_handlers,
+	_company_chunk_handlers,
+	_animated_tile_chunk_handlers,
+	_newgrf_chunk_handlers,
+	_group_chunk_handlers,
+	_cargopacket_chunk_handlers,
+	_autoreplace_chunk_handlers,
+	NULL,
+};
+
+/**
+ * Pointers cannot be saved to a savegame, so this functions gets
+ * the index of the item, and if not available, it hussles with
+ * pointers (looks really bad :()
+ * Remember that a NULL item has value 0, and all
+ * indeces have +1, so vehicle 0 is saved as index 1.
+ * @param obj The object that we want to get the index of
+ * @param rt SLRefType type of the object the index is being sought of
+ * @return Return the pointer converted to an index of the type pointed to
+ */
+static uint ReferenceToInt(const void *obj, SLRefType rt)
+{
+	if (obj == NULL) return 0;
+
+	switch (rt) {
+		case REF_VEHICLE_OLD: // Old vehicles we save as new onces
+		case REF_VEHICLE:   return ((const  Vehicle*)obj)->index + 1;
+		case REF_STATION:   return ((const  Station*)obj)->index + 1;
+		case REF_TOWN:      return ((const     Town*)obj)->index + 1;
+		case REF_ORDER:     return ((const    Order*)obj)->index + 1;
+		case REF_ROADSTOPS: return ((const RoadStop*)obj)->index + 1;
+		case REF_ENGINE_RENEWS: return ((const EngineRenew*)obj)->index + 1;
+		case REF_CARGO_PACKET:  return ((const CargoPacket*)obj)->index + 1;
+		case REF_ORDERLIST:     return ((const   OrderList*)obj)->index + 1;
+		default: NOT_REACHED();
+	}
+
+	return 0; // avoid compiler warning
+}
+
+/**
+ * Pointers cannot be loaded from a savegame, so this function
+ * gets the index from the savegame and returns the appropiate
+ * pointer from the already loaded base.
+ * Remember that an index of 0 is a NULL pointer so all indeces
+ * are +1 so vehicle 0 is saved as 1.
+ * @param index The index that is being converted to a pointer
+ * @param rt SLRefType type of the object the pointer is sought of
+ * @return Return the index converted to a pointer of any type
+ */
+static void *IntToReference(uint index, SLRefType rt)
+{
+	/* After version 4.3 REF_VEHICLE_OLD is saved as REF_VEHICLE,
+	 * and should be loaded like that */
+	if (rt == REF_VEHICLE_OLD && !CheckSavegameVersionOldStyle(4, 4)) {
+		rt = REF_VEHICLE;
+	}
+
+	/* No need to look up NULL pointers, just return immediately */
+	if (rt != REF_VEHICLE_OLD && index == 0) {
+		return NULL;
+	}
+
+	index--; // correct for the NULL index
+
+	switch (rt) {
+		case REF_ORDERLIST:
+			if (_OrderList_pool.AddBlockIfNeeded(index)) return GetOrderList(index);
+			error("Orders: failed loading savegame: too many order lists");
+
+		case REF_ORDER:
+			if (_Order_pool.AddBlockIfNeeded(index)) return GetOrder(index);
+			error("Orders: failed loading savegame: too many orders");
+
+		case REF_VEHICLE:
+			if (_Vehicle_pool.AddBlockIfNeeded(index)) return GetVehicle(index);
+			error("Vehicles: failed loading savegame: too many vehicles");
+
+		case REF_STATION:
+			if (_Station_pool.AddBlockIfNeeded(index)) return GetStation(index);
+			error("Stations: failed loading savegame: too many stations");
+
+		case REF_TOWN:
+			if (_Town_pool.AddBlockIfNeeded(index)) return GetTown(index);
+			error("Towns: failed loading savegame: too many towns");
+
+		case REF_ROADSTOPS:
+			if (_RoadStop_pool.AddBlockIfNeeded(index)) return GetRoadStop(index);
+			error("RoadStops: failed loading savegame: too many RoadStops");
+
+		case REF_ENGINE_RENEWS:
+			if (_EngineRenew_pool.AddBlockIfNeeded(index)) return GetEngineRenew(index);
+			error("EngineRenews: failed loading savegame: too many EngineRenews");
+
+		case REF_CARGO_PACKET:
+			if (_CargoPacket_pool.AddBlockIfNeeded(index)) return GetCargoPacket(index);
+			error("CargoPackets: failed loading savegame: too many Cargo packets");
+
+		case REF_VEHICLE_OLD:
+			/* Old vehicles were saved differently:
+			 * invalid vehicle was 0xFFFF,
+			 * and the index was not - 1.. correct for this */
+			index++;
+			if (index == INVALID_VEHICLE) return NULL;
+
+			if (_Vehicle_pool.AddBlockIfNeeded(index)) return GetVehicle(index);
+			error("Vehicles: failed loading savegame: too many vehicles");
+
+		default: NOT_REACHED();
+	}
+
+	return NULL;
+}
+
+/** The format for a reader/writer type of a savegame */
+struct SaveLoadFormat {
+	const char *name;           ///< name of the compressor/decompressor (debug-only)
+	uint32 tag;                 ///< the 4-letter tag by which it is identified in the savegame
+
+	bool (*init_read)();        ///< function executed upon initalization of the loader
+	ReaderProc *reader;         ///< function that loads the data from the file
+	void (*uninit_read)();      ///< function executed when reading is finished
+
+	bool (*init_write)();       ///< function executed upon intialization of the saver
+	WriterProc *writer;         ///< function that saves the data to the file
+	void (*uninit_write)();     ///< function executed when writing is done
+};
+
+static const SaveLoadFormat _saveload_formats[] = {
+	{"memory", 0,                NULL,         NULL,       NULL,           InitMem,       WriteMem,    UnInitMem},
+	{"lzo",    TO_BE32X('OTTD'), InitLZO,      ReadLZO,    UninitLZO,      InitLZO,       WriteLZO,    UninitLZO},
+	{"none",   TO_BE32X('OTTN'), InitNoComp,   ReadNoComp, UninitNoComp,   InitNoComp,    WriteNoComp, UninitNoComp},
+#if defined(WITH_ZLIB)
+	{"zlib",   TO_BE32X('OTTZ'), InitReadZlib, ReadZlib,   UninitReadZlib, InitWriteZlib, WriteZlib,   UninitWriteZlib},
+#else
+	{"zlib",   TO_BE32X('OTTZ'), NULL,         NULL,       NULL,           NULL,          NULL,        NULL},
+#endif
+};
+
+/**
+ * Return the savegameformat of the game. Whether it was create with ZLIB compression
+ * uncompressed, or another type
+ * @param s Name of the savegame format. If NULL it picks the first available one
+ * @return Pointer to SaveLoadFormat struct giving all characteristics of this type of savegame
+ */
+static const SaveLoadFormat *GetSavegameFormat(const char *s)
+{
+	const SaveLoadFormat *def = endof(_saveload_formats) - 1;
+
+	/* find default savegame format, the highest one with which files can be written */
+	while (!def->init_write) def--;
+
+	if (s != NULL && s[0] != '\0') {
+		const SaveLoadFormat *slf;
+		for (slf = &_saveload_formats[0]; slf != endof(_saveload_formats); slf++) {
+			if (slf->init_write != NULL && strcmp(s, slf->name) == 0)
+				return slf;
+		}
+
+		ShowInfoF("Savegame format '%s' is not available. Reverting to '%s'.", s, def->name);
+	}
+	return def;
+}
+
+/* actual loader/saver function */
+void InitializeGame(uint size_x, uint size_y, bool reset_date);
+extern bool AfterLoadGame();
+extern bool LoadOldSaveGame(const char *file);
+
+/** Small helper function to close the to be loaded savegame an signal error */
+static inline SaveOrLoadResult AbortSaveLoad()
+{
+	if (_sl.fh != NULL) fclose(_sl.fh);
+
+	_sl.fh = NULL;
+	return SL_ERROR;
+}
+
+/** Update the gui accordingly when starting saving
+ * and set locks on saveload. Also turn off fast-forward cause with that
+ * saving takes Aaaaages */
+static void SaveFileStart()
+{
+	_ts.ff_state = _fast_forward;
+	_fast_forward = 0;
+	if (_cursor.sprite == SPR_CURSOR_MOUSE) SetMouseCursor(SPR_CURSOR_ZZZ, PAL_NONE);
+
+	InvalidateWindowData(WC_STATUS_BAR, 0, SBI_SAVELOAD_START);
+	_ts.saveinprogress = true;
+}
+
+/** Update the gui accordingly when saving is done and release locks
+ * on saveload */
+static void SaveFileDone()
+{
+	if (_game_mode != GM_MENU) _fast_forward = _ts.ff_state;
+	if (_cursor.sprite == SPR_CURSOR_ZZZ) SetMouseCursor(SPR_CURSOR_MOUSE, PAL_NONE);
+
+	InvalidateWindowData(WC_STATUS_BAR, 0, SBI_SAVELOAD_FINISH);
+	_ts.saveinprogress = false;
+}
+
+/** Set the error message from outside of the actual loading/saving of the game (AfterLoadGame and friends) */
+void SetSaveLoadError(StringID str)
+{
+	_sl.error_str = str;
+}
+
+/** Get the string representation of the error message */
+const char *GetSaveLoadErrorString()
+{
+	SetDParam(0, _sl.error_str);
+	SetDParamStr(1, _sl.extra_msg);
+
+	static char err_str[512];
+	GetString(err_str, _sl.save ? STR_4007_GAME_SAVE_FAILED : STR_4009_GAME_LOAD_FAILED, lastof(err_str));
+	return err_str;
+}
+
+/** Show a gui message when saving has failed */
+static void SaveFileError()
+{
+	SetDParamStr(0, GetSaveLoadErrorString());
+	ShowErrorMessage(STR_JUST_RAW_STRING, STR_NULL, 0, 0);
+	SaveFileDone();
+}
+
+/** We have written the whole game into memory, _Savegame_pool, now find
+ * and appropiate compressor and start writing to file.
+ */
+static SaveOrLoadResult SaveFileToDisk(bool threaded)
+{
+	const SaveLoadFormat *fmt;
+	uint32 hdr[2];
+
+	_sl.excpt_uninit = NULL;
+	try {
+		fmt = GetSavegameFormat(_savegame_format);
+
+		/* We have written our stuff to memory, now write it to file! */
+		hdr[0] = fmt->tag;
+		hdr[1] = TO_BE32(SAVEGAME_VERSION << 16);
+		if (fwrite(hdr, sizeof(hdr), 1, _sl.fh) != 1) SlError(STR_GAME_SAVELOAD_ERROR_FILE_NOT_WRITEABLE);
+
+		if (!fmt->init_write()) SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR, "cannot initialize compressor");
+
+		{
+			uint i;
+			uint count = 1 << Savegame_POOL_BLOCK_SIZE_BITS;
+
+			if (_ts.count != _sl.offs_base) SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME, "Unexpected size of chunk");
+			for (i = 0; i != _Savegame_pool.GetBlockCount() - 1; i++) {
+				_sl.buf = _Savegame_pool.blocks[i];
+				fmt->writer(count);
+			}
+
+			/* The last block is (almost) always not fully filled, so only write away
+			 * as much data as it is in there */
+			_sl.buf = _Savegame_pool.blocks[i];
+			fmt->writer(_ts.count - (i * count));
+		}
+
+		fmt->uninit_write();
+		if (_ts.count != _sl.offs_base) SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME, "Unexpected size of chunk");
+		GetSavegameFormat("memory")->uninit_write(); // clean the memorypool
+		fclose(_sl.fh);
+
+		if (threaded) SetAsyncSaveFinish(SaveFileDone);
+
+		return SL_OK;
+	}
+	catch (...) {
+		AbortSaveLoad();
+		if (_sl.excpt_uninit != NULL) _sl.excpt_uninit();
+
+		/* Skip the "color" character */
+		DEBUG(sl, 0, GetSaveLoadErrorString() + 3);
+
+		if (threaded) {
+			SetAsyncSaveFinish(SaveFileError);
+		} else {
+			SaveFileError();
+		}
+		return SL_ERROR;
+	}
+}
+
+static void SaveFileToDiskThread(void *arg)
+{
+	SaveFileToDisk(true);
+}
+
+void WaitTillSaved()
+{
+	if (_save_thread == NULL) return;
+
+	_save_thread->Join();
+	delete _save_thread;
+	_save_thread = NULL;
+}
+
+/**
+ * Main Save or Load function where the high-level saveload functions are
+ * handled. It opens the savegame, selects format and checks versions
+ * @param filename The name of the savegame being created/loaded
+ * @param mode Save or load. Load can also be a TTD(Patch) game. Use SL_LOAD, SL_OLD_LOAD or SL_SAVE
+ * @return Return the results of the action. SL_OK, SL_ERROR or SL_REINIT ("unload" the game)
+ */
+SaveOrLoadResult SaveOrLoad(const char *filename, int mode, Subdirectory sb)
+{
+	uint32 hdr[2];
+	const SaveLoadFormat *fmt;
+
+	/* An instance of saving is already active, so don't go saving again */
+	if (_ts.saveinprogress && mode == SL_SAVE) {
+		/* if not an autosave, but a user action, show error message */
+		if (!_do_autosave) ShowErrorMessage(INVALID_STRING_ID, STR_SAVE_STILL_IN_PROGRESS, 0, 0);
+		return SL_OK;
+	}
+	WaitTillSaved();
+
+	_next_offs = 0;
+
+	/* Load a TTDLX or TTDPatch game */
+	if (mode == SL_OLD_LOAD) {
+		InitializeGame(256, 256, true); // set a mapsize of 256x256 for TTDPatch games or it might get confused
+		GamelogReset();
+		if (!LoadOldSaveGame(filename)) return SL_REINIT;
+		_sl_version = 0;
+		_sl_minor_version = 0;
+		GamelogStartAction(GLAT_LOAD);
+		if (!AfterLoadGame()) {
+			GamelogStopAction();
+			return SL_REINIT;
+		}
+		GamelogStopAction();
+		return SL_OK;
+	}
+
+	_sl.excpt_uninit = NULL;
+	try {
+		_sl.fh = (mode == SL_SAVE) ? FioFOpenFile(filename, "wb", sb) : FioFOpenFile(filename, "rb", sb);
+
+		/* Make it a little easier to load savegames from the console */
+		if (_sl.fh == NULL && mode == SL_LOAD) _sl.fh = FioFOpenFile(filename, "rb", SAVE_DIR);
+		if (_sl.fh == NULL && mode == SL_LOAD) _sl.fh = FioFOpenFile(filename, "rb", BASE_DIR);
+
+		if (_sl.fh == NULL) {
+			SlError(mode == SL_SAVE ? STR_GAME_SAVELOAD_ERROR_FILE_NOT_WRITEABLE : STR_GAME_SAVELOAD_ERROR_FILE_NOT_READABLE);
+		}
+
+		_sl.bufe = _sl.bufp = NULL;
+		_sl.offs_base = 0;
+		_sl.save = (mode != 0);
+		_sl.chs = _chunk_handlers;
+
+		/* General tactic is to first save the game to memory, then use an available writer
+		 * to write it to file, either in threaded mode if possible, or single-threaded */
+		if (mode == SL_SAVE) { /* SAVE game */
+			DEBUG(desync, 1, "save: %s\n", filename);
+			fmt = GetSavegameFormat("memory"); // write to memory
+
+			_sl.write_bytes = fmt->writer;
+			_sl.excpt_uninit = fmt->uninit_write;
+			if (!fmt->init_write()) {
+				DEBUG(sl, 0, "Initializing writer '%s' failed.", fmt->name);
+				return AbortSaveLoad();
+			}
+
+			_sl_version = SAVEGAME_VERSION;
+
+			SaveViewportBeforeSaveGame();
+			SlSaveChunks();
+			SlWriteFill(); // flush the save buffer
+
+			SaveFileStart();
+			if (_network_server ||
+						(_save_thread = ThreadObject::New(&SaveFileToDiskThread, NULL)) == NULL) {
+				if (!_network_server) DEBUG(sl, 1, "Cannot create savegame thread, reverting to single-threaded mode...");
+
+				SaveOrLoadResult result = SaveFileToDisk(false);
+				SaveFileDone();
+
+				return result;
+			}
+		} else { /* LOAD game */
+			assert(mode == SL_LOAD);
+			DEBUG(desync, 1, "load: %s\n", filename);
+
+			if (fread(hdr, sizeof(hdr), 1, _sl.fh) != 1) SlError(STR_GAME_SAVELOAD_ERROR_FILE_NOT_READABLE);
+
+			/* see if we have any loader for this type. */
+			for (fmt = _saveload_formats; ; fmt++) {
+				/* No loader found, treat as version 0 and use LZO format */
+				if (fmt == endof(_saveload_formats)) {
+					DEBUG(sl, 0, "Unknown savegame type, trying to load it as the buggy format");
+	#if defined(WINCE)
+					/* Of course some system had not to support rewind ;) */
+					fseek(_sl.fh, 0L, SEEK_SET);
+					clearerr(_sl.fh);
+	#else
+					rewind(_sl.fh);
+	#endif
+					_sl_version = 0;
+					_sl_minor_version = 0;
+					fmt = _saveload_formats + 1; // LZO
+					break;
+				}
+
+				if (fmt->tag == hdr[0]) {
+					/* check version number */
+					_sl_version = TO_BE32(hdr[1]) >> 16;
+					/* Minor is not used anymore from version 18.0, but it is still needed
+					 * in versions before that (4 cases) which can't be removed easy.
+					 * Therefor it is loaded, but never saved (or, it saves a 0 in any scenario).
+					 * So never EVER use this minor version again. -- TrueLight -- 22-11-2005 */
+					_sl_minor_version = (TO_BE32(hdr[1]) >> 8) & 0xFF;
+
+					DEBUG(sl, 1, "Loading savegame version %d", _sl_version);
+
+					/* Is the version higher than the current? */
+					if (_sl_version > SAVEGAME_VERSION) SlError(STR_GAME_SAVELOAD_ERROR_TOO_NEW_SAVEGAME);
+					break;
+				}
+			}
+
+			_sl.read_bytes = fmt->reader;
+			_sl.excpt_uninit = fmt->uninit_read;
+
+			/* loader for this savegame type is not implemented? */
+			if (fmt->init_read == NULL) {
+				char err_str[64];
+				snprintf(err_str, lengthof(err_str), "Loader for '%s' is not available.", fmt->name);
+				SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR, err_str);
+			}
+
+			if (!fmt->init_read()) {
+				char err_str[64];
+				snprintf(err_str, lengthof(err_str), "Initializing loader '%s' failed", fmt->name);
+				SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR, err_str);
+			}
+
+			/* 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(256, 256, true);
+
+			GamelogReset();
+
+			SlLoadChunks();
+			fmt->uninit_read();
+			fclose(_sl.fh);
+
+			GamelogStartAction(GLAT_LOAD);
+
+			_savegame_type = SGT_OTTD;
+
+			/* After loading fix up savegame for any internal changes that
+			 * might've occured since then. If it fails, load back the old game */
+			if (!AfterLoadGame()) {
+				GamelogStopAction();
+				return SL_REINIT;
+			}
+
+			GamelogStopAction();
+		}
+
+		return SL_OK;
+	}
+	catch (...) {
+		AbortSaveLoad();
+
+		/* deinitialize compressor. */
+		if (_sl.excpt_uninit != NULL) _sl.excpt_uninit();
+
+		/* Skip the "color" character */
+		DEBUG(sl, 0, GetSaveLoadErrorString() + 3);
+
+		/* A saver/loader exception!! reinitialize all variables to prevent crash! */
+		return (mode == SL_LOAD) ? SL_REINIT : SL_ERROR;
+	}
+}
+
+/** Do a save when exiting the game (patch option) _settings_client.gui.autosave_on_exit */
+void DoExitSave()
+{
+	SaveOrLoad("exit.sav", SL_SAVE, AUTOSAVE_DIR);
+}
+
+/**
+ * Fill the buffer with the default name for a savegame *or* screenshot.
+ * @param buf the buffer to write to.
+ * @param last the last element in the buffer.
+ */
+void GenerateDefaultSaveName(char *buf, const char *last)
+{
+	/* Check if we have a name for this map, which is the name of the first
+	 * available company. When there's no company available we'll use
+	 * 'Spectator' as "company" name. */
+	CompanyID cid = _local_company;
+	if (!IsValidCompanyID(cid)) {
+		const Company *c;
+		FOR_ALL_COMPANIES(c) {
+			cid = c->index;
+			break;
+		}
+	}
+
+	SetDParam(0, cid);
+
+	/* Insert current date */
+	switch (_settings_client.gui.date_format_in_default_names) {
+		case 0: SetDParam(1, STR_JUST_DATE_LONG); break;
+		case 1: SetDParam(1, STR_JUST_DATE_TINY); break;
+		case 2: SetDParam(1, STR_JUST_DATE_ISO); break;
+		default: NOT_REACHED();
+	}
+	SetDParam(2, _date);
+
+	/* Get the correct string (special string for when there's not company) */
+	GetString(buf, !IsValidCompanyID(cid) ? STR_GAME_SAVELOAD_SPECTATOR_SAVEGAME : STR_4004, last);
+	SanitizeFilename(buf);
+}
+
+#if 0
+/**
+ * Function to get the type of the savegame by looking at the file header.
+ * NOTICE: Not used right now, but could be used if extensions of savegames are garbled
+ * @param file Savegame to be checked
+ * @return SL_OLD_LOAD or SL_LOAD of the file
+ */
+int GetSavegameType(char *file)
+{
+	const SaveLoadFormat *fmt;
+	uint32 hdr;
+	FILE *f;
+	int mode = SL_OLD_LOAD;
+
+	f = fopen(file, "rb");
+	if (fread(&hdr, sizeof(hdr), 1, f) != 1) {
+		DEBUG(sl, 0, "Savegame is obsolete or invalid format");
+		mode = SL_LOAD; // don't try to get filename, just show name as it is written
+	} else {
+		/* see if we have any loader for this type. */
+		for (fmt = _saveload_formats; fmt != endof(_saveload_formats); fmt++) {
+			if (fmt->tag == hdr) {
+				mode = SL_LOAD; // new type of savegame
+				break;
+			}
+		}
+	}
+
+	fclose(f);
+	return mode;
+}
+#endif
new file mode 100644
--- /dev/null
+++ b/src/saveload/saveload.h
@@ -0,0 +1,332 @@
+/* $Id$ */
+
+/** @file saveload.h Functions/types related to saving and loading games. */
+
+#ifndef SAVELOAD_H
+#define SAVELOAD_H
+
+#include "../fileio_type.h"
+
+#ifdef SIZE_MAX
+#undef SIZE_MAX
+#endif
+
+#define SIZE_MAX ((size_t)-1)
+
+enum SaveOrLoadResult {
+	SL_OK     = 0, ///< completed successfully
+	SL_ERROR  = 1, ///< error that was caught before internal structures were modified
+	SL_REINIT = 2, ///< error that was caught in the middle of updating game state, need to clear it. (can only happen during load)
+};
+
+enum SaveOrLoadMode {
+	SL_INVALID  = -1,
+	SL_LOAD     =  0,
+	SL_SAVE     =  1,
+	SL_OLD_LOAD =  2,
+	SL_PNG      =  3,
+	SL_BMP      =  4,
+};
+
+enum SavegameType {
+	SGT_TTD,    ///< TTD  savegame (can be detected incorrectly)
+	SGT_TTDP1,  ///< TTDP savegame ( -//- ) (data at NW border)
+	SGT_TTDP2,  ///< TTDP savegame in new format (data at SE border)
+	SGT_OTTD    ///< OTTD savegame
+};
+
+void GenerateDefaultSaveName(char *buf, const char *last);
+void SetSaveLoadError(uint16 str);
+const char *GetSaveLoadErrorString();
+SaveOrLoadResult SaveOrLoad(const char *filename, int mode, Subdirectory sb);
+void WaitTillSaved();
+void DoExitSave();
+
+
+typedef void ChunkSaveLoadProc();
+typedef void AutolengthProc(void *arg);
+
+struct ChunkHandler {
+	uint32 id;
+	ChunkSaveLoadProc *save_proc;
+	ChunkSaveLoadProc *load_proc;
+	uint32 flags;
+};
+
+struct NullStruct {
+	byte null;
+};
+
+enum SLRefType {
+	REF_ORDER         = 0,
+	REF_VEHICLE       = 1,
+	REF_STATION       = 2,
+	REF_TOWN          = 3,
+	REF_VEHICLE_OLD   = 4,
+	REF_ROADSTOPS     = 5,
+	REF_ENGINE_RENEWS = 6,
+	REF_CARGO_PACKET  = 7,
+	REF_ORDERLIST     = 8,
+};
+
+#define SL_MAX_VERSION 255
+
+enum {
+	INC_VEHICLE_COMMON = 0,
+};
+
+enum {
+	CH_RIFF         =  0,
+	CH_ARRAY        =  1,
+	CH_SPARSE_ARRAY =  2,
+	CH_TYPE_MASK    =  3,
+	CH_LAST         =  8,
+	CH_AUTO_LENGTH  = 16,
+
+	CH_PRI_0          = 0 << 4,
+	CH_PRI_1          = 1 << 4,
+	CH_PRI_2          = 2 << 4,
+	CH_PRI_3          = 3 << 4,
+	CH_PRI_SHL        = 4,
+	CH_NUM_PRI_LEVELS = 4,
+};
+
+/** VarTypes is the general bitmasked magic type that tells us
+ * certain characteristics about the variable it refers to. For example
+ * SLE_FILE_* gives the size(type) as it would be in the savegame and
+ * SLE_VAR_* the size(type) as it is in memory during runtime. These are
+ * the first 8 bits (0-3 SLE_FILE, 4-7 SLE_VAR).
+ * Bits 8-15 are reserved for various flags as explained below */
+enum VarTypes {
+	/* 4 bits allocated a maximum of 16 types for NumberType */
+	SLE_FILE_I8       = 0,
+	SLE_FILE_U8       = 1,
+	SLE_FILE_I16      = 2,
+	SLE_FILE_U16      = 3,
+	SLE_FILE_I32      = 4,
+	SLE_FILE_U32      = 5,
+	SLE_FILE_I64      = 6,
+	SLE_FILE_U64      = 7,
+	SLE_FILE_STRINGID = 8, ///< StringID offset into strings-array
+	SLE_FILE_STRING   = 9,
+	/* 6 more possible file-primitives */
+
+	/* 4 bits allocated a maximum of 16 types for NumberType */
+	SLE_VAR_BL    =  0 << 4,
+	SLE_VAR_I8    =  1 << 4,
+	SLE_VAR_U8    =  2 << 4,
+	SLE_VAR_I16   =  3 << 4,
+	SLE_VAR_U16   =  4 << 4,
+	SLE_VAR_I32   =  5 << 4,
+	SLE_VAR_U32   =  6 << 4,
+	SLE_VAR_I64   =  7 << 4,
+	SLE_VAR_U64   =  8 << 4,
+	SLE_VAR_NULL  =  9 << 4, ///< useful to write zeros in savegame.
+	SLE_VAR_STRB  = 10 << 4, ///< string (with pre-allocated buffer)
+	SLE_VAR_STRBQ = 11 << 4, ///< string enclosed in quotes (with pre-allocated buffer)
+	SLE_VAR_STR   = 12 << 4, ///< string pointer
+	SLE_VAR_STRQ  = 13 << 4, ///< string pointer enclosed in quotes
+	SLE_VAR_NAME  = 14 << 4, ///< old custom name to be converted to a char pointer
+	/* 1 more possible memory-primitives */
+
+	/* Shortcut values */
+	SLE_VAR_CHAR = SLE_VAR_I8,
+
+	/* Default combinations of variables. As savegames change, so can variables
+	 * and thus it is possible that the saved value and internal size do not
+	 * match and you need to specify custom combo. The defaults are listed here */
+	SLE_BOOL         = SLE_FILE_I8  | SLE_VAR_BL,
+	SLE_INT8         = SLE_FILE_I8  | SLE_VAR_I8,
+	SLE_UINT8        = SLE_FILE_U8  | SLE_VAR_U8,
+	SLE_INT16        = SLE_FILE_I16 | SLE_VAR_I16,
+	SLE_UINT16       = SLE_FILE_U16 | SLE_VAR_U16,
+	SLE_INT32        = SLE_FILE_I32 | SLE_VAR_I32,
+	SLE_UINT32       = SLE_FILE_U32 | SLE_VAR_U32,
+	SLE_INT64        = SLE_FILE_I64 | SLE_VAR_I64,
+	SLE_UINT64       = SLE_FILE_U64 | SLE_VAR_U64,
+	SLE_CHAR         = SLE_FILE_I8  | SLE_VAR_CHAR,
+	SLE_STRINGID     = SLE_FILE_STRINGID | SLE_VAR_U16,
+	SLE_STRINGBUF    = SLE_FILE_STRING   | SLE_VAR_STRB,
+	SLE_STRINGBQUOTE = SLE_FILE_STRING   | SLE_VAR_STRBQ,
+	SLE_STRING       = SLE_FILE_STRING   | SLE_VAR_STR,
+	SLE_STRINGQUOTE  = SLE_FILE_STRING   | SLE_VAR_STRQ,
+	SLE_NAME         = SLE_FILE_STRINGID | SLE_VAR_NAME,
+
+	/* Shortcut values */
+	SLE_UINT  = SLE_UINT32,
+	SLE_INT   = SLE_INT32,
+	SLE_STRB  = SLE_STRINGBUF,
+	SLE_STRBQ = SLE_STRINGBQUOTE,
+	SLE_STR   = SLE_STRING,
+	SLE_STRQ  = SLE_STRINGQUOTE,
+
+	/* 8 bits allocated for a maximum of 8 flags
+	 * Flags directing saving/loading of a variable */
+	SLF_SAVE_NO      = 1 <<  8, ///< do not save with savegame, basically client-based
+	SLF_CONFIG_NO    = 1 <<  9, ///< do not save to config file
+	SLF_NETWORK_NO   = 1 << 10, ///< do not synchronize over network (but it is saved if SSF_SAVE_NO is not set)
+	/* 5 more possible flags */
+};
+
+typedef uint32 VarType;
+
+enum SaveLoadTypes {
+	SL_VAR         =  0,
+	SL_REF         =  1,
+	SL_ARR         =  2,
+	SL_STR         =  3,
+	SL_LST         =  4,
+	// non-normal save-load types
+	SL_WRITEBYTE   =  8,
+	SL_VEH_INCLUDE =  9,
+	SL_END         = 15
+};
+
+typedef byte SaveLoadType;
+
+/** SaveLoad type struct. Do NOT use this directly but use the SLE_ macros defined just below! */
+struct SaveLoad {
+	bool global;         ///< should we load a global variable or a non-global one
+	SaveLoadType cmd;    ///< the action to take with the saved/loaded type, All types need different action
+	VarType conv;        ///< type of the variable to be saved, int
+	uint16 length;       ///< (conditional) length of the variable (eg. arrays) (max array size is 65536 elements)
+	uint16 version_from; ///< save/load the variable starting from this savegame version
+	uint16 version_to;   ///< save/load the variable until this savegame version
+	/* NOTE: This element either denotes the address of the variable for a global
+	 * variable, or the offset within a struct which is then bound to a variable
+	 * during runtime. Decision on which one to use is controlled by the function
+	 * that is called to save it. address: global=true, offset: global=false */
+	void *address;       ///< address of variable OR offset of variable in the struct (max offset is 65536)
+};
+
+/* Same as SaveLoad but global variables are used (for better readability); */
+typedef SaveLoad SaveLoadGlobVarList;
+
+/* Simple variables, references (pointers) and arrays */
+#define SLE_GENERAL(cmd, base, variable, type, length, from, to) {false, cmd, type, length, from, to, (void*)cpp_offsetof(base, variable)}
+#define SLE_CONDVAR(base, variable, type, from, to) SLE_GENERAL(SL_VAR, base, variable, type, 0, from, to)
+#define SLE_CONDREF(base, variable, type, from, to) SLE_GENERAL(SL_REF, base, variable, type, 0, from, to)
+#define SLE_CONDARR(base, variable, type, length, from, to) SLE_GENERAL(SL_ARR, base, variable, type, length, from, to)
+#define SLE_CONDSTR(base, variable, type, length, from, to) SLE_GENERAL(SL_STR, base, variable, type, length, from, to)
+#define SLE_CONDLST(base, variable, type, from, to) SLE_GENERAL(SL_LST, base, variable, type, 0, from, to)
+
+#define SLE_VAR(base, variable, type) SLE_CONDVAR(base, variable, type, 0, SL_MAX_VERSION)
+#define SLE_REF(base, variable, type) SLE_CONDREF(base, variable, type, 0, SL_MAX_VERSION)
+#define SLE_ARR(base, variable, type, length) SLE_CONDARR(base, variable, type, length, 0, SL_MAX_VERSION)
+#define SLE_STR(base, variable, type, length) SLE_CONDSTR(base, variable, type, length, 0, SL_MAX_VERSION)
+#define SLE_LST(base, variable, type) SLE_CONDLST(base, variable, type, 0, SL_MAX_VERSION)
+
+#define SLE_CONDNULL(length, from, to) SLE_CONDARR(NullStruct, null, SLE_FILE_U8 | SLE_VAR_NULL | SLF_CONFIG_NO, length, from, to)
+
+/* Translate values ingame to different values in the savegame and vv */
+#define SLE_WRITEBYTE(base, variable, value) SLE_GENERAL(SL_WRITEBYTE, base, variable, 0, 0, value, value)
+
+/* The same as the ones at the top, only the offset is given directly; used for unions */
+#define SLE_GENERALX(cmd, offset, type, length, param1, param2) {false, cmd, type, length, param1, param2, (void*)(offset)}
+#define SLE_CONDVARX(offset, type, from, to) SLE_GENERALX(SL_VAR, offset, type, 0, from, to)
+#define SLE_CONDARRX(offset, type, length, from, to) SLE_GENERALX(SL_ARR, offset, type, length, from, to)
+#define SLE_CONDREFX(offset, type, from, to) SLE_GENERALX(SL_REF, offset, type, 0, from, to)
+
+#define SLE_VARX(offset, type) SLE_CONDVARX(offset, type, 0, SL_MAX_VERSION)
+#define SLE_REFX(offset, type) SLE_CONDREFX(offset, type, 0, SL_MAX_VERSION)
+
+#define SLE_WRITEBYTEX(offset, something) SLE_GENERALX(SL_WRITEBYTE, offset, 0, 0, something, 0)
+#define SLE_VEH_INCLUDEX() SLE_GENERALX(SL_VEH_INCLUDE, 0, 0, 0, 0, SL_MAX_VERSION)
+
+/* End marker */
+#define SLE_END() {false, SL_END, 0, 0, 0, 0, NULL}
+
+/* Simple variables, references (pointers) and arrays, but for global variables */
+#define SLEG_GENERAL(cmd, variable, type, length, from, to) {true, cmd, type, length, from, to, (void*)&variable}
+
+#define SLEG_CONDVAR(variable, type, from, to) SLEG_GENERAL(SL_VAR, variable, type, 0, from, to)
+#define SLEG_CONDREF(variable, type, from, to) SLEG_GENERAL(SL_REF, variable, type, 0, from, to)
+#define SLEG_CONDARR(variable, type, length, from, to) SLEG_GENERAL(SL_ARR, variable, type, length, from, to)
+#define SLEG_CONDSTR(variable, type, length, from, to) SLEG_GENERAL(SL_STR, variable, type, length, from, to)
+#define SLEG_CONDLST(variable, type, from, to) SLEG_GENERAL(SL_LST, variable, type, 0, from, to)
+
+#define SLEG_VAR(variable, type) SLEG_CONDVAR(variable, type, 0, SL_MAX_VERSION)
+#define SLEG_REF(variable, type) SLEG_CONDREF(variable, type, 0, SL_MAX_VERSION)
+#define SLEG_ARR(variable, type) SLEG_CONDARR(variable, type, lengthof(variable), 0, SL_MAX_VERSION)
+#define SLEG_STR(variable, type) SLEG_CONDSTR(variable, type, lengthof(variable), 0, SL_MAX_VERSION)
+#define SLEG_LST(variable, type) SLEG_CONDLST(variable, type, 0, SL_MAX_VERSION)
+
+#define SLEG_CONDNULL(length, from, to) {true, SL_ARR, SLE_FILE_U8 | SLE_VAR_NULL | SLF_CONFIG_NO, length, from, to, (void*)NULL}
+
+#define SLEG_END() {true, SL_END, 0, 0, 0, 0, NULL}
+
+/** Checks if the savegame is below major.minor.
+ */
+static inline bool CheckSavegameVersionOldStyle(uint16 major, byte minor)
+{
+	extern uint16 _sl_version;
+	extern byte   _sl_minor_version;
+	return (_sl_version < major) || (_sl_version == major && _sl_minor_version < minor);
+}
+
+/** Checks if the savegame is below version.
+ */
+static inline bool CheckSavegameVersion(uint16 version)
+{
+	extern uint16 _sl_version;
+	return _sl_version < version;
+}
+
+/** Checks if some version from/to combination falls within the range of the
+ * active savegame version */
+static inline bool SlIsObjectCurrentlyValid(uint16 version_from, uint16 version_to)
+{
+	extern const uint16 SAVEGAME_VERSION;
+	if (SAVEGAME_VERSION < version_from || SAVEGAME_VERSION > version_to) return false;
+
+	return true;
+}
+
+/* Get the NumberType of a setting. This describes the integer type
+ * as it is represented in memory
+ * @param type VarType holding information about the variable-type
+ * @return return the SLE_VAR_* part of a variable-type description */
+static inline VarType GetVarMemType(VarType type)
+{
+	return type & 0xF0; // GB(type, 4, 4) << 4;
+}
+
+/* Get the FileType of a setting. This describes the integer type
+ * as it is represented in a savegame/file
+ * @param type VarType holding information about the variable-type
+ * @param return the SLE_FILE_* part of a variable-type description */
+static inline VarType GetVarFileType(VarType type)
+{
+	return type & 0xF; // GB(type, 0, 4);
+}
+
+/** Get the address of the variable. Which one to pick depends on the object
+ * pointer. If it is NULL we are dealing with global variables so the address
+ * is taken. If non-null only the offset is stored in the union and we need
+ * to add this to the address of the object */
+static inline void *GetVariableAddress(const void *object, const SaveLoad *sld)
+{
+	return (byte*)(sld->global ? NULL : object) + (ptrdiff_t)sld->address;
+}
+
+int64 ReadValue(const void *ptr, VarType conv);
+void WriteValue(void *ptr, VarType conv, int64 val);
+
+void SlSetArrayIndex(uint index);
+int SlIterateArray();
+
+void SlAutolength(AutolengthProc *proc, void *arg);
+size_t SlGetFieldLength();
+void SlSetLength(size_t length);
+size_t SlCalcObjMemberLength(const void *object, const SaveLoad *sld);
+size_t SlCalcObjLength(const void *object, const SaveLoad *sld);
+
+byte SlReadByte();
+void SlWriteByte(byte b);
+
+void SlGlobList(const SaveLoadGlobVarList *sldg);
+void SlArray(void *array, size_t length, VarType conv);
+void SlObject(void *object, const SaveLoad *sld);
+bool SlObjectMember(void *object, const SaveLoad *sld);
+
+#endif /* SAVELOAD_H */
new file mode 100644
--- /dev/null
+++ b/src/saveload/saveload_internal.h
@@ -0,0 +1,40 @@
+/* $Id$ */
+
+/** @file saveload_internal.h Declaration of functions used in more save/load files */
+
+#ifndef SAVELOAD_INTERNAL_H
+#define SAVELOAD_INTERNAL_H
+
+#include "../strings_type.h"
+#include "../company_manager_face.h"
+#include "../order_base.h"
+
+void InitializeOldNames();
+StringID RemapOldStringID(StringID s);
+char *CopyFromOldName(StringID id);
+void ResetOldNames();
+
+void FixOldWaypoints();
+
+void AfterLoadWaypoints();
+void AfterLoadVehicles(bool part_of_load);
+void AfterLoadStations();
+void AfterLoadTown();
+void UpdateHousesAndTowns();
+
+void UpdateOldAircraft();
+
+void SaveViewportBeforeSaveGame();
+void ResetViewportAfterLoadGame();
+
+void ConvertOldMultiheadToNew();
+void ConnectMultiheadedTrains();
+
+extern int32 _saved_scrollpos_x;
+extern int32 _saved_scrollpos_y;
+
+CompanyManagerFace ConvertFromOldCompanyManagerFace(uint32 face);
+
+Order UnpackOldOrder(uint16 packed);
+
+#endif /* SAVELOAD_INTERNAL_H */
new file mode 100644
--- /dev/null
+++ b/src/saveload/signs_sl.cpp
@@ -0,0 +1,49 @@
+/* $Id$ */
+
+/** @file signs_sl.cpp Code handling saving and loading of economy data */
+
+#include "../stdafx.h"
+#include "../strings_func.h"
+#include "../company_func.h"
+#include "../signs_base.h"
+#include "../signs_func.h"
+
+#include "saveload_internal.h"
+#include "saveload.h"
+
+static const SaveLoad _sign_desc[] = {
+  SLE_CONDVAR(Sign, name,  SLE_NAME,                   0, 83),
+  SLE_CONDSTR(Sign, name,  SLE_STR, 0,                84, SL_MAX_VERSION),
+  SLE_CONDVAR(Sign, x,     SLE_FILE_I16 | SLE_VAR_I32, 0, 4),
+  SLE_CONDVAR(Sign, y,     SLE_FILE_I16 | SLE_VAR_I32, 0, 4),
+  SLE_CONDVAR(Sign, x,     SLE_INT32,                  5, SL_MAX_VERSION),
+  SLE_CONDVAR(Sign, y,     SLE_INT32,                  5, SL_MAX_VERSION),
+  SLE_CONDVAR(Sign, owner, SLE_UINT8,                  6, SL_MAX_VERSION),
+      SLE_VAR(Sign, z,     SLE_UINT8),
+	SLE_END()
+};
+
+/** Save all signs */
+static void Save_SIGN()
+{
+	Sign *si;
+
+	FOR_ALL_SIGNS(si) {
+		SlSetArrayIndex(si->index);
+		SlObject(si, _sign_desc);
+	}
+}
+
+/** Load all signs */
+static void Load_SIGN()
+{
+	int index;
+	while ((index = SlIterateArray()) != -1) {
+		Sign *si = new (index) Sign();
+		SlObject(si, _sign_desc);
+	}
+}
+
+extern const ChunkHandler _sign_chunk_handlers[] = {
+	{ 'SIGN', Save_SIGN, Load_SIGN, CH_ARRAY | CH_LAST},
+};
new file mode 100644
--- /dev/null
+++ b/src/saveload/station_sl.cpp
@@ -0,0 +1,227 @@
+/* $Id$ */
+
+/** @file station_sl.cpp Code handling saving and loading of economy data */
+
+#include "../stdafx.h"
+#include "../station_base.h"
+#include "../core/bitmath_func.hpp"
+#include "../core/alloc_func.hpp"
+#include "../variables.h"
+#include "../newgrf_station.h"
+
+#include "saveload.h"
+
+
+void AfterLoadStations()
+{
+	/* Update the speclists of all stations to point to the currently loaded custom stations. */
+	Station *st;
+	FOR_ALL_STATIONS(st) {
+		for (uint i = 0; i < st->num_specs; i++) {
+			if (st->speclist[i].grfid == 0) continue;
+
+			st->speclist[i].spec = GetCustomStationSpecByGrf(st->speclist[i].grfid, st->speclist[i].localidx);
+		}
+
+		for (CargoID c = 0; c < NUM_CARGO; c++) st->goods[c].cargo.InvalidateCache();
+
+		StationUpdateAnimTriggers(st);
+	}
+}
+
+static const SaveLoad _roadstop_desc[] = {
+	SLE_VAR(RoadStop, xy,           SLE_UINT32),
+	SLE_CONDNULL(1, 0, 44),
+	SLE_VAR(RoadStop, status,       SLE_UINT8),
+	/* Index was saved in some versions, but this is not needed */
+	SLE_CONDNULL(4, 0, 8),
+	SLE_CONDNULL(2, 0, 44),
+	SLE_CONDNULL(1, 0, 25),
+
+	SLE_REF(RoadStop, next,         REF_ROADSTOPS),
+	SLE_CONDNULL(2, 0, 44),
+
+	SLE_CONDNULL(4, 0, 24),
+	SLE_CONDNULL(1, 25, 25),
+
+	SLE_END()
+};
+
+static const SaveLoad _station_desc[] = {
+	SLE_CONDVAR(Station, xy,                         SLE_FILE_U16 | SLE_VAR_U32,  0, 5),
+	SLE_CONDVAR(Station, xy,                         SLE_UINT32,                  6, SL_MAX_VERSION),
+	SLE_CONDNULL(4, 0, 5),  ///< bus/lorry tile
+	SLE_CONDVAR(Station, train_tile,                 SLE_FILE_U16 | SLE_VAR_U32,  0, 5),
+	SLE_CONDVAR(Station, train_tile,                 SLE_UINT32,                  6, SL_MAX_VERSION),
+	SLE_CONDVAR(Station, airport_tile,               SLE_FILE_U16 | SLE_VAR_U32,  0, 5),
+	SLE_CONDVAR(Station, airport_tile,               SLE_UINT32,                  6, SL_MAX_VERSION),
+	SLE_CONDVAR(Station, dock_tile,                  SLE_FILE_U16 | SLE_VAR_U32,  0, 5),
+	SLE_CONDVAR(Station, dock_tile,                  SLE_UINT32,                  6, SL_MAX_VERSION),
+	    SLE_REF(Station, town,                       REF_TOWN),
+	    SLE_VAR(Station, trainst_w,                  SLE_UINT8),
+	SLE_CONDVAR(Station, trainst_h,                  SLE_UINT8,                   2, SL_MAX_VERSION),
+
+	SLE_CONDNULL(1, 0, 3),  ///< alpha_order
+
+	    SLE_VAR(Station, string_id,                  SLE_STRINGID),
+	SLE_CONDSTR(Station, name,                       SLE_STR, 0,                 84, SL_MAX_VERSION),
+	SLE_CONDVAR(Station, indtype,                    SLE_UINT8,                 103, SL_MAX_VERSION),
+	    SLE_VAR(Station, had_vehicle_of_type,        SLE_UINT16),
+
+	    SLE_VAR(Station, time_since_load,            SLE_UINT8),
+	    SLE_VAR(Station, time_since_unload,          SLE_UINT8),
+	    SLE_VAR(Station, delete_ctr,                 SLE_UINT8),
+	    SLE_VAR(Station, owner,                      SLE_UINT8),
+	    SLE_VAR(Station, facilities,                 SLE_UINT8),
+	    SLE_VAR(Station, airport_type,               SLE_UINT8),
+
+	SLE_CONDNULL(2, 0, 5),  ///< Truck/bus stop status
+	SLE_CONDNULL(1, 0, 4),  ///< Blocked months
+
+	SLE_CONDVAR(Station, airport_flags,              SLE_VAR_U64 | SLE_FILE_U16,  0,  2),
+	SLE_CONDVAR(Station, airport_flags,              SLE_VAR_U64 | SLE_FILE_U32,  3, 45),
+	SLE_CONDVAR(Station, airport_flags,              SLE_UINT64,                 46, SL_MAX_VERSION),
+
+	SLE_CONDNULL(2, 0, 25), ///< last-vehicle
+	SLE_CONDVAR(Station, last_vehicle_type,          SLE_UINT8,                  26, SL_MAX_VERSION),
+
+	SLE_CONDNULL(2, 3, 25), ///< custom station class and id
+	SLE_CONDVAR(Station, build_date,                 SLE_FILE_U16 | SLE_VAR_I32,  3, 30),
+	SLE_CONDVAR(Station, build_date,                 SLE_INT32,                  31, SL_MAX_VERSION),
+
+	SLE_CONDREF(Station, bus_stops,                  REF_ROADSTOPS,               6, SL_MAX_VERSION),
+	SLE_CONDREF(Station, truck_stops,                REF_ROADSTOPS,               6, SL_MAX_VERSION),
+
+	/* Used by newstations for graphic variations */
+	SLE_CONDVAR(Station, random_bits,                SLE_UINT16,                 27, SL_MAX_VERSION),
+	SLE_CONDVAR(Station, waiting_triggers,           SLE_UINT8,                  27, SL_MAX_VERSION),
+	SLE_CONDVAR(Station, num_specs,                  SLE_UINT8,                  27, SL_MAX_VERSION),
+
+	SLE_CONDLST(Station, loading_vehicles,           REF_VEHICLE,                57, SL_MAX_VERSION),
+
+	/* reserve extra space in savegame here. (currently 32 bytes) */
+	SLE_CONDNULL(32, 2, SL_MAX_VERSION),
+
+	SLE_END()
+};
+
+static uint16 _waiting_acceptance;
+static uint16 _cargo_source;
+static uint32 _cargo_source_xy;
+static uint16 _cargo_days;
+static Money  _cargo_feeder_share;
+
+static const SaveLoad _station_speclist_desc[] = {
+	SLE_CONDVAR(StationSpecList, grfid,    SLE_UINT32, 27, SL_MAX_VERSION),
+	SLE_CONDVAR(StationSpecList, localidx, SLE_UINT8,  27, SL_MAX_VERSION),
+
+	SLE_END()
+};
+
+
+void SaveLoad_STNS(Station *st)
+{
+	static const SaveLoad _goods_desc[] = {
+		SLEG_CONDVAR(            _waiting_acceptance, SLE_UINT16,                  0, 67),
+		 SLE_CONDVAR(GoodsEntry, acceptance_pickup,   SLE_UINT8,                  68, SL_MAX_VERSION),
+		SLE_CONDNULL(2,                                                           51, 67),
+		     SLE_VAR(GoodsEntry, days_since_pickup,   SLE_UINT8),
+		     SLE_VAR(GoodsEntry, rating,              SLE_UINT8),
+		SLEG_CONDVAR(            _cargo_source,       SLE_FILE_U8 | SLE_VAR_U16,   0, 6),
+		SLEG_CONDVAR(            _cargo_source,       SLE_UINT16,                  7, 67),
+		SLEG_CONDVAR(            _cargo_source_xy,    SLE_UINT32,                 44, 67),
+		SLEG_CONDVAR(            _cargo_days,         SLE_UINT8,                   0, 67),
+		     SLE_VAR(GoodsEntry, last_speed,          SLE_UINT8),
+		     SLE_VAR(GoodsEntry, last_age,            SLE_UINT8),
+		SLEG_CONDVAR(            _cargo_feeder_share, SLE_FILE_U32 | SLE_VAR_I64, 14, 64),
+		SLEG_CONDVAR(            _cargo_feeder_share, SLE_INT64,                  65, 67),
+		 SLE_CONDLST(GoodsEntry, cargo.packets,       REF_CARGO_PACKET,           68, SL_MAX_VERSION),
+
+		SLE_END()
+	};
+
+
+	SlObject(st, _station_desc);
+
+	_waiting_acceptance = 0;
+
+	uint num_cargo = CheckSavegameVersion(55) ? 12 : NUM_CARGO;
+	for (CargoID i = 0; i < num_cargo; i++) {
+		GoodsEntry *ge = &st->goods[i];
+		SlObject(ge, _goods_desc);
+		if (CheckSavegameVersion(68)) {
+			SB(ge->acceptance_pickup, GoodsEntry::ACCEPTANCE, 1, HasBit(_waiting_acceptance, 15));
+			if (GB(_waiting_acceptance, 0, 12) != 0) {
+				/* Don't construct the packet with station here, because that'll fail with old savegames */
+				CargoPacket *cp = new CargoPacket();
+				/* In old versions, enroute_from used 0xFF as INVALID_STATION */
+				cp->source          = (CheckSavegameVersion(7) && _cargo_source == 0xFF) ? INVALID_STATION : _cargo_source;
+				cp->count           = GB(_waiting_acceptance, 0, 12);
+				cp->days_in_transit = _cargo_days;
+				cp->feeder_share    = _cargo_feeder_share;
+				cp->source_xy       = _cargo_source_xy;
+				cp->days_in_transit = _cargo_days;
+				cp->feeder_share    = _cargo_feeder_share;
+				SB(ge->acceptance_pickup, GoodsEntry::PICKUP, 1, 1);
+				ge->cargo.Append(cp);
+			}
+		}
+	}
+
+	if (st->num_specs != 0) {
+		/* Allocate speclist memory when loading a game */
+		if (st->speclist == NULL) st->speclist = CallocT<StationSpecList>(st->num_specs);
+		for (uint i = 0; i < st->num_specs; i++) {
+			SlObject(&st->speclist[i], _station_speclist_desc);
+		}
+	}
+}
+
+static void Save_STNS()
+{
+	Station *st;
+	/* Write the stations */
+	FOR_ALL_STATIONS(st) {
+		SlSetArrayIndex(st->index);
+		SlAutolength((AutolengthProc*)SaveLoad_STNS, st);
+	}
+}
+
+static void Load_STNS()
+{
+	int index;
+	while ((index = SlIterateArray()) != -1) {
+		Station *st = new (index) Station();
+
+		SaveLoad_STNS(st);
+	}
+
+	/* This is to ensure all pointers are within the limits of _stations_size */
+	if (_station_tick_ctr > GetMaxStationIndex()) _station_tick_ctr = 0;
+}
+
+static void Save_ROADSTOP()
+{
+	RoadStop *rs;
+
+	FOR_ALL_ROADSTOPS(rs) {
+		SlSetArrayIndex(rs->index);
+		SlObject(rs, _roadstop_desc);
+	}
+}
+
+static void Load_ROADSTOP()
+{
+	int index;
+
+	while ((index = SlIterateArray()) != -1) {
+		RoadStop *rs = new (index) RoadStop(INVALID_TILE);
+
+		SlObject(rs, _roadstop_desc);
+	}
+}
+
+extern const ChunkHandler _station_chunk_handlers[] = {
+	{ 'STNS', Save_STNS,      Load_STNS,      CH_ARRAY },
+	{ 'ROAD', Save_ROADSTOP,  Load_ROADSTOP,  CH_ARRAY | CH_LAST},
+};
new file mode 100644
--- /dev/null
+++ b/src/saveload/strings_sl.cpp
@@ -0,0 +1,126 @@
+/* $Id$ */
+
+/** @file strings_sl.cpp Code handling saving and loading of strings */
+
+#include "../stdafx.h"
+#include "../strings_type.h"
+#include "../core/math_func.hpp"
+#include "../core/bitmath_func.hpp"
+#include "../core/alloc_func.hpp"
+#include "../string_func.h"
+
+#include "table/strings.h"
+
+#include "saveload.h"
+
+/**
+ * Remap a string ID from the old format to the new format
+ * @param s StringID that requires remapping
+ * @return translated ID
+ */
+StringID RemapOldStringID(StringID s)
+{
+	switch (s) {
+		case 0x0006: return STR_SV_EMPTY;
+		case 0x7000: return STR_SV_UNNAMED;
+		case 0x70E4: return SPECSTR_PLAYERNAME_ENGLISH;
+		case 0x70E9: return SPECSTR_PLAYERNAME_ENGLISH;
+		case 0x8864: return STR_SV_TRAIN_NAME;
+		case 0x902B: return STR_SV_ROADVEH_NAME;
+		case 0x9830: return STR_SV_SHIP_NAME;
+		case 0xA02F: return STR_SV_AIRCRAFT_NAME;
+
+		default:
+			if (IsInsideMM(s, 0x300F, 0x3030)) {
+				return s - 0x300F + STR_SV_STNAME;
+			} else {
+				return s;
+			}
+	}
+}
+
+/** Location to load the old names to. */
+char *_old_name_array = NULL;
+
+/**
+ * Copy and convert old custom names to UTF-8.
+ * They were all stored in a 512 by 32 long string array and are
+ * now stored with stations, waypoints and other places with names.
+ * @param id the StringID of the custom name to clone.
+ * @return the clones custom name.
+ */
+char *CopyFromOldName(StringID id)
+{
+	/* Is this name an (old) custom name? */
+	if (GB(id, 11, 5) != 15) return NULL;
+
+	if (CheckSavegameVersion(37)) {
+		/* Old names were 32 characters long, so 128 characters should be
+		 * plenty to allow for expansion when converted to UTF-8. */
+		char tmp[128];
+		const char *strfrom = &_old_name_array[32 * GB(id, 0, 9)];
+		char *strto = tmp;
+
+		for (; *strfrom != '\0'; strfrom++) {
+			WChar c = (byte)*strfrom;
+
+			/* Map from non-ISO8859-15 characters to UTF-8. */
+			switch (c) {
+				case 0xA4: c = 0x20AC; break; // Euro
+				case 0xA6: c = 0x0160; break; // S with caron
+				case 0xA8: c = 0x0161; break; // s with caron
+				case 0xB4: c = 0x017D; break; // Z with caron
+				case 0xB8: c = 0x017E; break; // z with caron
+				case 0xBC: c = 0x0152; break; // OE ligature
+				case 0xBD: c = 0x0153; break; // oe ligature
+				case 0xBE: c = 0x0178; break; // Y with diaresis
+				default: break;
+			}
+
+			/* Check character will fit into our buffer. */
+			if (strto + Utf8CharLen(c) > lastof(tmp)) break;
+
+			strto += Utf8Encode(strto, c);
+		}
+
+		/* Terminate the new string and copy it back to the name array */
+		*strto = '\0';
+
+		return strdup(tmp);
+	} else {
+		/* Name will already be in UTF-8. */
+		return strdup(&_old_name_array[32 * GB(id, 0, 9)]);
+	}
+}
+
+/**
+ * Free the memory of the old names array.
+ * Should be called once the old names have all been converted.
+ */
+void ResetOldNames()
+{
+	free(_old_name_array);
+	_old_name_array = NULL;
+}
+
+/**
+ * Initialize the old names table memory.
+ */
+void InitializeOldNames()
+{
+	free(_old_name_array);
+	_old_name_array = CallocT<char>(512 * 32);
+}
+
+static void Load_NAME()
+{
+	int index;
+
+	while ((index = SlIterateArray()) != -1) {
+		SlArray(&_old_name_array[32 * index], SlGetFieldLength(), SLE_UINT8);
+	}
+}
+
+extern const ChunkHandler _name_chunk_handlers[] = {
+	{ 'NAME', NULL, Load_NAME, CH_ARRAY | CH_LAST},
+};
new file mode 100644
--- /dev/null
+++ b/src/saveload/subsidy_sl.cpp
@@ -0,0 +1,43 @@
+/* $Id$ */
+
+/** @file subsidy_sl.cpp Code handling saving and loading of subsidies */
+
+#include "../stdafx.h"
+#include "../economy_func.h"
+
+#include "saveload.h"
+
+static const SaveLoad _subsidies_desc[] = {
+	    SLE_VAR(Subsidy, cargo_type, SLE_UINT8),
+	    SLE_VAR(Subsidy, age,        SLE_UINT8),
+	SLE_CONDVAR(Subsidy, from,       SLE_FILE_U8 | SLE_VAR_U16, 0, 4),
+	SLE_CONDVAR(Subsidy, from,       SLE_UINT16,                5, SL_MAX_VERSION),
+	SLE_CONDVAR(Subsidy, to,         SLE_FILE_U8 | SLE_VAR_U16, 0, 4),
+	SLE_CONDVAR(Subsidy, to,         SLE_UINT16,                5, SL_MAX_VERSION),
+	SLE_END()
+};
+
+void Save_SUBS()
+{
+	int i;
+	Subsidy *s;
+
+	for (i = 0; i != lengthof(_subsidies); i++) {
+		s = &_subsidies[i];
+		if (s->cargo_type != CT_INVALID) {
+			SlSetArrayIndex(i);
+			SlObject(s, _subsidies_desc);
+		}
+	}
+}
+
+void Load_SUBS()
+{
+	int index;
+	while ((index = SlIterateArray()) != -1)
+		SlObject(&_subsidies[index], _subsidies_desc);
+}
+
+extern const ChunkHandler _subsidy_chunk_handlers[] = {
+	{ 'SUBS', Save_SUBS,     Load_SUBS,     CH_ARRAY},
+};
new file mode 100644
--- /dev/null
+++ b/src/saveload/town_sl.cpp
@@ -0,0 +1,210 @@
+/* $Id$ */
+
+/** @file town_sl.cpp Code handling saving and loading of towns and houses */
+
+#include "../stdafx.h"
+#include "../town.h"
+#include "../newgrf_house.h"
+#include "../newgrf_commons.h"
+#include "../variables.h"
+#include "../tile_map.h"
+#include "../town_map.h"
+
+#include "saveload.h"
+
+extern uint _total_towns;
+
+/**
+ * Check and update town and house values.
+ *
+ * Checked are the HouseIDs. Updated are the
+ * town population the number of houses per
+ * town, the town radius and the max passengers
+ * of the town.
+ */
+void UpdateHousesAndTowns()
+{
+	Town *town;
+	InitializeBuildingCounts();
+
+	/* Reset town population and num_houses */
+	FOR_ALL_TOWNS(town) {
+		town->population = 0;
+		town->num_houses = 0;
+	}
+
+	for (TileIndex t = 0; t < MapSize(); t++) {
+		HouseID house_id;
+
+		if (!IsTileType(t, MP_HOUSE)) continue;
+
+		house_id = GetHouseType(t);
+		if (!GetHouseSpecs(house_id)->enabled && house_id >= NEW_HOUSE_OFFSET) {
+			/* The specs for this type of house are not available any more, so
+			 * replace it with the substitute original house type. */
+			house_id = _house_mngr.GetSubstituteID(house_id);
+			SetHouseType(t, house_id);
+		}
+
+		town = GetTownByTile(t);
+		IncreaseBuildingCount(town, house_id);
+		if (IsHouseCompleted(t)) town->population += GetHouseSpecs(house_id)->population;
+
+		/* Increase the number of houses for every house, but only once. */
+		if (GetHouseNorthPart(house_id) == 0) town->num_houses++;
+	}
+
+	/* Update the population and num_house dependant values */
+	FOR_ALL_TOWNS(town) {
+		UpdateTownRadius(town);
+		UpdateTownMaxPass(town);
+	}
+}
+
+/** Save and load of towns. */
+static const SaveLoad _town_desc[] = {
+	SLE_CONDVAR(Town, xy,                    SLE_FILE_U16 | SLE_VAR_U32, 0, 5),
+	SLE_CONDVAR(Town, xy,                    SLE_UINT32,                 6, SL_MAX_VERSION),
+
+	SLE_CONDNULL(2, 0, 2),                   ///< population, no longer in use
+	SLE_CONDNULL(4, 3, 84),                  ///< population, no longer in use
+	SLE_CONDNULL(2, 0, 91),                  ///< num_houses, no longer in use
+
+	SLE_CONDVAR(Town, townnamegrfid,         SLE_UINT32, 66, SL_MAX_VERSION),
+	    SLE_VAR(Town, townnametype,          SLE_UINT16),
+	    SLE_VAR(Town, townnameparts,         SLE_UINT32),
+	SLE_CONDSTR(Town, name,                  SLE_STR, 0, 84, SL_MAX_VERSION),
+
+	    SLE_VAR(Town, flags12,               SLE_UINT8),
+	SLE_CONDVAR(Town, statues,               SLE_FILE_U8  | SLE_VAR_U16, 0, 103),
+	SLE_CONDVAR(Town, statues,               SLE_UINT16,               104, SL_MAX_VERSION),
+
+	SLE_CONDNULL(1, 0, 1),                   ///< sort_index, no longer in use
+
+	SLE_CONDVAR(Town, have_ratings,          SLE_FILE_U8  | SLE_VAR_U16, 0, 103),
+	SLE_CONDVAR(Town, have_ratings,          SLE_UINT16,               104, SL_MAX_VERSION),
+	SLE_CONDARR(Town, ratings,               SLE_INT16, 8,               0, 103),
+	SLE_CONDARR(Town, ratings,               SLE_INT16, MAX_COMPANIES, 104, SL_MAX_VERSION),
+	/* failed bribe attempts are stored since savegame format 4 */
+	SLE_CONDARR(Town, unwanted,              SLE_INT8,  8,               4, 103),
+	SLE_CONDARR(Town, unwanted,              SLE_INT8,  MAX_COMPANIES, 104, SL_MAX_VERSION),
+
+	SLE_CONDVAR(Town, max_pass,              SLE_FILE_U16 | SLE_VAR_U32, 0, 8),
+	SLE_CONDVAR(Town, max_mail,              SLE_FILE_U16 | SLE_VAR_U32, 0, 8),
+	SLE_CONDVAR(Town, new_max_pass,          SLE_FILE_U16 | SLE_VAR_U32, 0, 8),
+	SLE_CONDVAR(Town, new_max_mail,          SLE_FILE_U16 | SLE_VAR_U32, 0, 8),
+	SLE_CONDVAR(Town, act_pass,              SLE_FILE_U16 | SLE_VAR_U32, 0, 8),
+	SLE_CONDVAR(Town, act_mail,              SLE_FILE_U16 | SLE_VAR_U32, 0, 8),
+	SLE_CONDVAR(Town, new_act_pass,          SLE_FILE_U16 | SLE_VAR_U32, 0, 8),
+	SLE_CONDVAR(Town, new_act_mail,          SLE_FILE_U16 | SLE_VAR_U32, 0, 8),
+
+	SLE_CONDVAR(Town, max_pass,              SLE_UINT32,                 9, SL_MAX_VERSION),
+	SLE_CONDVAR(Town, max_mail,              SLE_UINT32,                 9, SL_MAX_VERSION),
+	SLE_CONDVAR(Town, new_max_pass,          SLE_UINT32,                 9, SL_MAX_VERSION),
+	SLE_CONDVAR(Town, new_max_mail,          SLE_UINT32,                 9, SL_MAX_VERSION),
+	SLE_CONDVAR(Town, act_pass,              SLE_UINT32,                 9, SL_MAX_VERSION),
+	SLE_CONDVAR(Town, act_mail,              SLE_UINT32,                 9, SL_MAX_VERSION),
+	SLE_CONDVAR(Town, new_act_pass,          SLE_UINT32,                 9, SL_MAX_VERSION),
+	SLE_CONDVAR(Town, new_act_mail,          SLE_UINT32,                 9, SL_MAX_VERSION),
+
+	    SLE_VAR(Town, pct_pass_transported,  SLE_UINT8),
+	    SLE_VAR(Town, pct_mail_transported,  SLE_UINT8),
+
+	    SLE_VAR(Town, act_food,              SLE_UINT16),
+	    SLE_VAR(Town, act_water,             SLE_UINT16),
+	    SLE_VAR(Town, new_act_food,          SLE_UINT16),
+	    SLE_VAR(Town, new_act_water,         SLE_UINT16),
+
+	SLE_CONDVAR(Town, time_until_rebuild,    SLE_UINT8,                  0, 53),
+	SLE_CONDVAR(Town, grow_counter,          SLE_UINT8,                  0, 53),
+	SLE_CONDVAR(Town, growth_rate,           SLE_UINT8,                  0, 53),
+
+	SLE_CONDVAR(Town, time_until_rebuild,    SLE_UINT16,                54, SL_MAX_VERSION),
+	SLE_CONDVAR(Town, grow_counter,          SLE_UINT16,                54, SL_MAX_VERSION),
+	SLE_CONDVAR(Town, growth_rate,           SLE_INT16,                 54, SL_MAX_VERSION),
+
+	    SLE_VAR(Town, fund_buildings_months, SLE_UINT8),
+	    SLE_VAR(Town, road_build_months,     SLE_UINT8),
+
+	SLE_CONDVAR(Town, exclusivity,           SLE_UINT8,                  2, SL_MAX_VERSION),
+	SLE_CONDVAR(Town, exclusive_counter,     SLE_UINT8,                  2, SL_MAX_VERSION),
+
+	SLE_CONDVAR(Town, larger_town,           SLE_BOOL,                  56, SL_MAX_VERSION),
+
+	/* reserve extra space in savegame here. (currently 30 bytes) */
+	SLE_CONDNULL(30, 2, SL_MAX_VERSION),
+
+	SLE_END()
+};
+
+/* Save and load the mapping between the house id on the map, and the grf file
+ * it came from. */
+static const SaveLoad _house_id_mapping_desc[] = {
+	SLE_VAR(EntityIDMapping, grfid,         SLE_UINT32),
+	SLE_VAR(EntityIDMapping, entity_id,     SLE_UINT8),
+	SLE_VAR(EntityIDMapping, substitute_id, SLE_UINT8),
+	SLE_END()
+};
+
+static void Save_HOUSEIDS()
+{
+	uint j = _house_mngr.GetMaxMapping();
+
+	for (uint i = 0; i < j; i++) {
+		SlSetArrayIndex(i);
+		SlObject(&_house_mngr.mapping_ID[i], _house_id_mapping_desc);
+	}
+}
+
+static void Load_HOUSEIDS()
+{
+	int index;
+
+	_house_mngr.ResetMapping();
+	uint max_id = _house_mngr.GetMaxMapping();
+
+	while ((index = SlIterateArray()) != -1) {
+		if ((uint)index >= max_id) break;
+		SlObject(&_house_mngr.mapping_ID[index], _house_id_mapping_desc);
+	}
+}
+
+static void Save_TOWN()
+{
+	Town *t;
+
+	FOR_ALL_TOWNS(t) {
+		SlSetArrayIndex(t->index);
+		SlObject(t, _town_desc);
+	}
+}
+
+static void Load_TOWN()
+{
+	int index;
+
+	_total_towns = 0;
+
+	while ((index = SlIterateArray()) != -1) {
+		Town *t = new (index) Town();
+		SlObject(t, _town_desc);
+
+		_total_towns++;
+	}
+
+	/* This is to ensure all pointers are within the limits of
+	 *  the size of the TownPool */
+	if (_cur_town_ctr > GetMaxTownIndex())
+		_cur_town_ctr = 0;
+}
+
+void AfterLoadTown()
+{
+	Town *t;
+	FOR_ALL_TOWNS(t) t->InitializeLayout();
+}
+
+extern const ChunkHandler _town_chunk_handlers[] = {
+	{ 'HIDS', Save_HOUSEIDS, Load_HOUSEIDS, CH_ARRAY },
+	{ 'CITY', Save_TOWN,     Load_TOWN,     CH_ARRAY | CH_LAST},
+};
new file mode 100644
--- /dev/null
+++ b/src/saveload/vehicle_sl.cpp
@@ -0,0 +1,670 @@
+/* $Id$ */
+
+/** @file vehicle_sl.cpp Code handling saving and loading of vehicles */
+
+#include "../stdafx.h"
+#include "../vehicle_base.h"
+#include "../vehicle_func.h"
+#include "../train.h"
+#include "../roadveh.h"
+#include "../ship.h"
+#include "../aircraft.h"
+#include "../effectvehicle_base.h"
+
+#include "saveload.h"
+
+#include <map>
+
+/*
+ * Link front and rear multiheaded engines to each other
+ * This is done when loading a savegame
+ */
+void ConnectMultiheadedTrains()
+{
+	Vehicle *v;
+
+	FOR_ALL_VEHICLES(v) {
+		if (v->type == VEH_TRAIN) {
+			v->u.rail.other_multiheaded_part = NULL;
+		}
+	}
+
+	FOR_ALL_VEHICLES(v) {
+		if (v->type == VEH_TRAIN && (IsFrontEngine(v) || IsFreeWagon(v))) {
+			/* Two ways to associate multiheaded parts to each other:
+			 * sequential-matching: Trains shall be arranged to look like <..>..<..>..<..>..
+			 * bracket-matching:    Free vehicle chains shall be arranged to look like ..<..<..>..<..>..>..
+			 *
+			 * Note: Old savegames might contain chains which do not comply with these rules, e.g.
+			 *   - the front and read parts have invalid orders
+			 *   - different engine types might be combined
+			 *   - there might be different amounts of front and rear parts.
+			 *
+			 * Note: The multiheaded parts need to be matched exactly like they are matched on the server, else desyncs will occur.
+			 *   This is why two matching strategies are needed.
+			 */
+
+			bool sequential_matching = IsFrontEngine(v);
+
+			for (Vehicle *u = v; u != NULL; u = GetNextVehicle(u)) {
+				if (u->u.rail.other_multiheaded_part != NULL) continue; // we already linked this one
+
+				if (IsMultiheaded(u)) {
+					if (!IsTrainEngine(u)) {
+						/* we got a rear car without a front car. We will convert it to a front one */
+						SetTrainEngine(u);
+						u->spritenum--;
+					}
+
+					/* Find a matching back part */
+					EngineID eid = u->engine_type;
+					Vehicle *w;
+					if (sequential_matching) {
+						for (w = GetNextVehicle(u); w != NULL; w = GetNextVehicle(w)) {
+							if (w->engine_type != eid || w->u.rail.other_multiheaded_part != NULL || !IsMultiheaded(w)) continue;
+
+							/* we found a car to partner with this engine. Now we will make sure it face the right way */
+							if (IsTrainEngine(w)) {
+								ClearTrainEngine(w);
+								w->spritenum++;
+							}
+							break;
+						}
+					} else {
+						uint stack_pos = 0;
+						for (w = GetNextVehicle(u); w != NULL; w = GetNextVehicle(w)) {
+							if (w->engine_type != eid || w->u.rail.other_multiheaded_part != NULL || !IsMultiheaded(w)) continue;
+
+							if (IsTrainEngine(w)) {
+								stack_pos++;
+							} else {
+								if (stack_pos == 0) break;
+								stack_pos--;
+							}
+						}
+					}
+
+					if (w != NULL) {
+						w->u.rail.other_multiheaded_part = u;
+						u->u.rail.other_multiheaded_part = w;
+					} else {
+						/* we got a front car and no rear cars. We will fake this one for forget that it should have been multiheaded */
+						ClearMultiheaded(u);
+					}
+				}
+			}
+		}
+	}
+}
+
+/**
+ *  Converts all trains to the new subtype format introduced in savegame 16.2
+ *  It also links multiheaded engines or make them forget they are multiheaded if no suitable partner is found
+ */
+void ConvertOldMultiheadToNew()
+{
+	Vehicle *v;
+	FOR_ALL_VEHICLES(v) {
+		if (v->type == VEH_TRAIN) {
+			SetBit(v->subtype, 7); // indicates that it's the old format and needs to be converted in the next loop
+		}
+	}
+
+	FOR_ALL_VEHICLES(v) {
+		if (v->type == VEH_TRAIN) {
+			if (HasBit(v->subtype, 7) && ((v->subtype & ~0x80) == 0 || (v->subtype & ~0x80) == 4)) {
+				for (Vehicle *u = v; u != NULL; u = u->Next()) {
+					const RailVehicleInfo *rvi = RailVehInfo(u->engine_type);
+
+					ClrBit(u->subtype, 7);
+					switch (u->subtype) {
+						case 0: /* TS_Front_Engine */
+							if (rvi->railveh_type == RAILVEH_MULTIHEAD) SetMultiheaded(u);
+							SetFrontEngine(u);
+							SetTrainEngine(u);
+							break;
+
+						case 1: /* TS_Artic_Part */
+							u->subtype = 0;
+							SetArticulatedPart(u);
+							break;
+
+						case 2: /* TS_Not_First */
+							u->subtype = 0;
+							if (rvi->railveh_type == RAILVEH_WAGON) {
+								// normal wagon
+								SetTrainWagon(u);
+								break;
+							}
+							if (rvi->railveh_type == RAILVEH_MULTIHEAD && rvi->image_index == u->spritenum - 1) {
+								// rear end of a multiheaded engine
+								SetMultiheaded(u);
+								break;
+							}
+							if (rvi->railveh_type == RAILVEH_MULTIHEAD) SetMultiheaded(u);
+							SetTrainEngine(u);
+							break;
+
+						case 4: /* TS_Free_Car */
+							u->subtype = 0;
+							SetTrainWagon(u);
+							SetFreeWagon(u);
+							break;
+						default: NOT_REACHED(); break;
+					}
+				}
+			}
+		}
+	}
+}
+
+
+/** need to be called to load aircraft from old version */
+void UpdateOldAircraft()
+{
+	/* set airport_flags to 0 for all airports just to be sure */
+	Station *st;
+	FOR_ALL_STATIONS(st) {
+		st->airport_flags = 0; // reset airport
+	}
+
+	Vehicle *v_oldstyle;
+	FOR_ALL_VEHICLES(v_oldstyle) {
+	/* airplane has another vehicle with subtype 4 (shadow), helicopter also has 3 (rotor)
+	 * skip those */
+		if (v_oldstyle->type == VEH_AIRCRAFT && IsNormalAircraft(v_oldstyle)) {
+			/* airplane in terminal stopped doesn't hurt anyone, so goto next */
+			if (v_oldstyle->vehstatus & VS_STOPPED && v_oldstyle->u.air.state == 0) {
+				v_oldstyle->u.air.state = HANGAR;
+				continue;
+			}
+
+			AircraftLeaveHangar(v_oldstyle); // make airplane visible if it was in a depot for example
+			v_oldstyle->vehstatus &= ~VS_STOPPED; // make airplane moving
+			v_oldstyle->u.air.state = FLYING;
+			AircraftNextAirportPos_and_Order(v_oldstyle); // move it to the entry point of the airport
+			GetNewVehiclePosResult gp = GetNewVehiclePos(v_oldstyle);
+			v_oldstyle->tile = 0; // aircraft in air is tile=0
+
+			/* correct speed of helicopter-rotors */
+			if (v_oldstyle->subtype == AIR_HELICOPTER) v_oldstyle->Next()->Next()->cur_speed = 32;
+
+			/* set new position x,y,z */
+			SetAircraftPosition(v_oldstyle, gp.x, gp.y, GetAircraftFlyingAltitude(v_oldstyle));
+		}
+	}
+}
+
+/** Called after load to update coordinates */
+void AfterLoadVehicles(bool part_of_load)
+{
+	Vehicle *v;
+
+	FOR_ALL_VEHICLES(v) {
+		/* Reinstate the previous pointer */
+		if (v->Next() != NULL) v->Next()->previous = v;
+		if (v->NextShared() != NULL) v->NextShared()->previous_shared = v;
+
+		v->UpdateDeltaXY(v->direction);
+
+		if (part_of_load) v->fill_percent_te_id = INVALID_TE_ID;
+		v->first = NULL;
+		if (v->type == VEH_TRAIN) v->u.rail.first_engine = INVALID_ENGINE;
+		if (v->type == VEH_ROAD)  v->u.road.first_engine = INVALID_ENGINE;
+
+		v->cargo.InvalidateCache();
+	}
+
+	/* AfterLoadVehicles may also be called in case of NewGRF reload, in this
+	 * case we may not convert orders again. */
+	if (part_of_load) {
+		/* Create shared vehicle chain for very old games (pre 5,2) and create
+		 * OrderList from shared vehicle chains. For this to work correctly, the
+		 * following conditions must be fulfilled:
+		 * a) both next_shared and previous_shared are not set for pre 5,2 games
+		 * b) both next_shared and previous_shared are set for later games
+		 */
+		std::map<Order*, OrderList*> mapping;
+
+		FOR_ALL_VEHICLES(v) {
+			if (v->orders.old != NULL) {
+				if (CheckSavegameVersion(105)) { // Pre-105 didn't save an OrderList
+					if (mapping[v->orders.old] == NULL) {
+						/* This adds the whole shared vehicle chain for case b */
+						v->orders.list = mapping[v->orders.old] = new OrderList(v->orders.old, v);
+					} else {
+						v->orders.list = mapping[v->orders.old];
+						/* For old games (case a) we must create the shared vehicle chain */
+						if (CheckSavegameVersionOldStyle(5, 2)) {
+							v->AddToShared(v->orders.list->GetFirstSharedVehicle());
+						}
+					}
+				} else { // OrderList was saved as such, only recalculate not saved values
+					if (v->PreviousShared() == NULL) {
+						new (v->orders.list) OrderList(v->orders.list->GetFirstOrder(), v);
+					}
+				}
+			}
+		}
+	}
+
+	FOR_ALL_VEHICLES(v) {
+		/* Fill the first pointers */
+		if (v->Previous() == NULL) {
+			for (Vehicle *u = v; u != NULL; u = u->Next()) {
+				u->first = v;
+			}
+		}
+	}
+
+	FOR_ALL_VEHICLES(v) {
+		assert(v->first != NULL);
+
+		if (v->type == VEH_TRAIN && (IsFrontEngine(v) || IsFreeWagon(v))) {
+			if (IsFrontEngine(v)) v->u.rail.last_speed = v->cur_speed; // update displayed train speed
+			TrainConsistChanged(v, false);
+		} else if (v->type == VEH_ROAD && IsRoadVehFront(v)) {
+			RoadVehUpdateCache(v);
+		}
+	}
+
+	/* Stop non-front engines */
+	FOR_ALL_VEHICLES(v) {
+		if (v->type == VEH_TRAIN && IsTrainEngine(v) && !IsFrontEngine(v)) v->vehstatus |= VS_STOPPED;
+	}
+
+	FOR_ALL_VEHICLES(v) {
+		switch (v->type) {
+			case VEH_ROAD:
+				v->u.road.roadtype = HasBit(EngInfo(v->engine_type)->misc_flags, EF_ROAD_TRAM) ? ROADTYPE_TRAM : ROADTYPE_ROAD;
+				v->u.road.compatible_roadtypes = RoadTypeToRoadTypes(v->u.road.roadtype);
+				/* FALL THROUGH */
+			case VEH_TRAIN:
+			case VEH_SHIP:
+				v->cur_image = v->GetImage(v->direction);
+				break;
+
+			case VEH_AIRCRAFT:
+				if (IsNormalAircraft(v)) {
+					v->cur_image = v->GetImage(v->direction);
+
+					/* The plane's shadow will have the same image as the plane */
+					Vehicle *shadow = v->Next();
+					shadow->cur_image = v->cur_image;
+
+					/* In the case of a helicopter we will update the rotor sprites */
+					if (v->subtype == AIR_HELICOPTER) {
+						Vehicle *rotor = shadow->Next();
+						rotor->cur_image = GetRotorImage(v);
+					}
+
+					UpdateAircraftCache(v);
+				}
+				break;
+			default: break;
+		}
+
+		v->left_coord = INVALID_COORD;
+		VehiclePositionChanged(v);
+	}
+}
+
+static uint8  _cargo_days;
+static uint16 _cargo_source;
+static uint32 _cargo_source_xy;
+static uint16 _cargo_count;
+static uint16 _cargo_paid_for;
+static Money  _cargo_feeder_share;
+static uint32 _cargo_loaded_at_xy;
+
+/**
+ * Make it possible to make the saveload tables "friends" of other classes.
+ * @param vt the vehicle type. Can be VEH_END for the common vehicle description data
+ * @return the saveload description
+ */
+const SaveLoad *GetVehicleDescription(VehicleType vt)
+{
+	/** Save and load of vehicles */
+	static const SaveLoad _common_veh_desc[] = {
+		     SLE_VAR(Vehicle, subtype,               SLE_UINT8),
+
+		     SLE_REF(Vehicle, next,                  REF_VEHICLE_OLD),
+		 SLE_CONDVAR(Vehicle, name,                  SLE_NAME,                     0,  83),
+		 SLE_CONDSTR(Vehicle, name,                  SLE_STR, 0,                  84, SL_MAX_VERSION),
+		 SLE_CONDVAR(Vehicle, unitnumber,            SLE_FILE_U8  | SLE_VAR_U16,   0,   7),
+		 SLE_CONDVAR(Vehicle, unitnumber,            SLE_UINT16,                   8, SL_MAX_VERSION),
+		     SLE_VAR(Vehicle, owner,                 SLE_UINT8),
+		 SLE_CONDVAR(Vehicle, tile,                  SLE_FILE_U16 | SLE_VAR_U32,   0,   5),
+		 SLE_CONDVAR(Vehicle, tile,                  SLE_UINT32,                   6, SL_MAX_VERSION),
+		 SLE_CONDVAR(Vehicle, dest_tile,             SLE_FILE_U16 | SLE_VAR_U32,   0,   5),
+		 SLE_CONDVAR(Vehicle, dest_tile,             SLE_UINT32,                   6, SL_MAX_VERSION),
+
+		 SLE_CONDVAR(Vehicle, x_pos,                 SLE_FILE_U16 | SLE_VAR_U32,   0,   5),
+		 SLE_CONDVAR(Vehicle, x_pos,                 SLE_UINT32,                   6, SL_MAX_VERSION),
+		 SLE_CONDVAR(Vehicle, y_pos,                 SLE_FILE_U16 | SLE_VAR_U32,   0,   5),
+		 SLE_CONDVAR(Vehicle, y_pos,                 SLE_UINT32,                   6, SL_MAX_VERSION),
+		     SLE_VAR(Vehicle, z_pos,                 SLE_UINT8),
+		     SLE_VAR(Vehicle, direction,             SLE_UINT8),
+
+		SLE_CONDNULL(2,                                                            0,  57),
+		     SLE_VAR(Vehicle, spritenum,             SLE_UINT8),
+		SLE_CONDNULL(5,                                                            0,  57),
+		     SLE_VAR(Vehicle, engine_type,           SLE_UINT16),
+
+		     SLE_VAR(Vehicle, max_speed,             SLE_UINT16),
+		     SLE_VAR(Vehicle, cur_speed,             SLE_UINT16),
+		     SLE_VAR(Vehicle, subspeed,              SLE_UINT8),
+		     SLE_VAR(Vehicle, acceleration,          SLE_UINT8),
+		     SLE_VAR(Vehicle, progress,              SLE_UINT8),
+
+		     SLE_VAR(Vehicle, vehstatus,             SLE_UINT8),
+		 SLE_CONDVAR(Vehicle, last_station_visited,  SLE_FILE_U8  | SLE_VAR_U16,   0,   4),
+		 SLE_CONDVAR(Vehicle, last_station_visited,  SLE_UINT16,                   5, SL_MAX_VERSION),
+
+		     SLE_VAR(Vehicle, cargo_type,            SLE_UINT8),
+		 SLE_CONDVAR(Vehicle, cargo_subtype,         SLE_UINT8,                   35, SL_MAX_VERSION),
+		SLEG_CONDVAR(         _cargo_days,           SLE_UINT8,                    0,  67),
+		SLEG_CONDVAR(         _cargo_source,         SLE_FILE_U8  | SLE_VAR_U16,   0,   6),
+		SLEG_CONDVAR(         _cargo_source,         SLE_UINT16,                   7,  67),
+		SLEG_CONDVAR(         _cargo_source_xy,      SLE_UINT32,                  44,  67),
+		     SLE_VAR(Vehicle, cargo_cap,             SLE_UINT16),
+		SLEG_CONDVAR(         _cargo_count,          SLE_UINT16,                   0,  67),
+		 SLE_CONDLST(Vehicle, cargo,                 REF_CARGO_PACKET,            68, SL_MAX_VERSION),
+
+		     SLE_VAR(Vehicle, day_counter,           SLE_UINT8),
+		     SLE_VAR(Vehicle, tick_counter,          SLE_UINT8),
+		 SLE_CONDVAR(Vehicle, running_ticks,         SLE_UINT8,                   88, SL_MAX_VERSION),
+
+		     SLE_VAR(Vehicle, cur_order_index,       SLE_UINT8),
+		/* num_orders is now part of OrderList and is not saved but counted */
+		SLE_CONDNULL(1,                                                            0, 104),
+
+		/* This next line is for version 4 and prior compatibility.. it temporarily reads
+		 type and flags (which were both 4 bits) into type. Later on this is
+		 converted correctly */
+		SLE_CONDVARX(cpp_offsetof(Vehicle, current_order) + cpp_offsetof(Order, type),           SLE_UINT8,                    0,   4),
+		SLE_CONDVARX(cpp_offsetof(Vehicle, current_order) + cpp_offsetof(Order, dest),           SLE_FILE_U8  | SLE_VAR_U16,   0,   4),
+
+		/* Orders for version 5 and on */
+		SLE_CONDVARX(cpp_offsetof(Vehicle, current_order) + cpp_offsetof(Order, type),           SLE_UINT8,                    5, SL_MAX_VERSION),
+		SLE_CONDVARX(cpp_offsetof(Vehicle, current_order) + cpp_offsetof(Order, flags),          SLE_UINT8,                    5, SL_MAX_VERSION),
+		SLE_CONDVARX(cpp_offsetof(Vehicle, current_order) + cpp_offsetof(Order, dest),           SLE_UINT16,                   5, SL_MAX_VERSION),
+
+		/* Refit in current order */
+		SLE_CONDVARX(cpp_offsetof(Vehicle, current_order) + cpp_offsetof(Order, refit_cargo),    SLE_UINT8,                   36, SL_MAX_VERSION),
+		SLE_CONDVARX(cpp_offsetof(Vehicle, current_order) + cpp_offsetof(Order, refit_subtype),  SLE_UINT8,                   36, SL_MAX_VERSION),
+
+		/* Timetable in current order */
+		SLE_CONDVARX(cpp_offsetof(Vehicle, current_order) + cpp_offsetof(Order, wait_time),      SLE_UINT16,                  67, SL_MAX_VERSION),
+		SLE_CONDVARX(cpp_offsetof(Vehicle, current_order) + cpp_offsetof(Order, travel_time),    SLE_UINT16,                  67, SL_MAX_VERSION),
+
+		 SLE_CONDREF(Vehicle, orders,                REF_ORDER,                    0, 104),
+		 SLE_CONDREF(Vehicle, orders,                REF_ORDERLIST,              105, SL_MAX_VERSION),
+
+		 SLE_CONDVAR(Vehicle, age,                   SLE_FILE_U16 | SLE_VAR_I32,   0,  30),
+		 SLE_CONDVAR(Vehicle, age,                   SLE_INT32,                   31, SL_MAX_VERSION),
+		 SLE_CONDVAR(Vehicle, max_age,               SLE_FILE_U16 | SLE_VAR_I32,   0,  30),
+		 SLE_CONDVAR(Vehicle, max_age,               SLE_INT32,                   31, SL_MAX_VERSION),
+		 SLE_CONDVAR(Vehicle, date_of_last_service,  SLE_FILE_U16 | SLE_VAR_I32,   0,  30),
+		 SLE_CONDVAR(Vehicle, date_of_last_service,  SLE_INT32,                   31, SL_MAX_VERSION),
+		 SLE_CONDVAR(Vehicle, service_interval,      SLE_FILE_U16 | SLE_VAR_I32,   0,  30),
+		 SLE_CONDVAR(Vehicle, service_interval,      SLE_INT32,                   31, SL_MAX_VERSION),
+		     SLE_VAR(Vehicle, reliability,           SLE_UINT16),
+		     SLE_VAR(Vehicle, reliability_spd_dec,   SLE_UINT16),
+		     SLE_VAR(Vehicle, breakdown_ctr,         SLE_UINT8),
+		     SLE_VAR(Vehicle, breakdown_delay,       SLE_UINT8),
+		     SLE_VAR(Vehicle, breakdowns_since_last_service, SLE_UINT8),
+		     SLE_VAR(Vehicle, breakdown_chance,      SLE_UINT8),
+		 SLE_CONDVAR(Vehicle, build_year,            SLE_FILE_U8 | SLE_VAR_I32,    0,  30),
+		 SLE_CONDVAR(Vehicle, build_year,            SLE_INT32,                   31, SL_MAX_VERSION),
+
+		     SLE_VAR(Vehicle, load_unload_time_rem,  SLE_UINT16),
+		SLEG_CONDVAR(         _cargo_paid_for,       SLE_UINT16,                  45, SL_MAX_VERSION),
+		 SLE_CONDVAR(Vehicle, vehicle_flags,         SLE_UINT8,                   40, SL_MAX_VERSION),
+
+		 SLE_CONDVAR(Vehicle, profit_this_year,      SLE_FILE_I32 | SLE_VAR_I64,   0,  64),
+		 SLE_CONDVAR(Vehicle, profit_this_year,      SLE_INT64,                   65, SL_MAX_VERSION),
+		 SLE_CONDVAR(Vehicle, profit_last_year,      SLE_FILE_I32 | SLE_VAR_I64,   0,  64),
+		 SLE_CONDVAR(Vehicle, profit_last_year,      SLE_INT64,                   65, SL_MAX_VERSION),
+		SLEG_CONDVAR(         _cargo_feeder_share,   SLE_FILE_I32 | SLE_VAR_I64,  51,  64),
+		SLEG_CONDVAR(         _cargo_feeder_share,   SLE_INT64,                   65,  67),
+		SLEG_CONDVAR(         _cargo_loaded_at_xy,   SLE_UINT32,                  51,  67),
+		 SLE_CONDVAR(Vehicle, value,                 SLE_FILE_I32 | SLE_VAR_I64,   0,  64),
+		 SLE_CONDVAR(Vehicle, value,                 SLE_INT64,                   65, SL_MAX_VERSION),
+
+		 SLE_CONDVAR(Vehicle, random_bits,           SLE_UINT8,                    2, SL_MAX_VERSION),
+		 SLE_CONDVAR(Vehicle, waiting_triggers,      SLE_UINT8,                    2, SL_MAX_VERSION),
+
+		 SLE_CONDREF(Vehicle, next_shared,           REF_VEHICLE,                  2, SL_MAX_VERSION),
+		SLE_CONDNULL(2,                                                            2,  68),
+		SLE_CONDNULL(4,                                                           69, 100),
+
+		 SLE_CONDVAR(Vehicle, group_id,              SLE_UINT16,                  60, SL_MAX_VERSION),
+
+		 SLE_CONDVAR(Vehicle, current_order_time,    SLE_UINT32,                  67, SL_MAX_VERSION),
+		 SLE_CONDVAR(Vehicle, lateness_counter,      SLE_INT32,                   67, SL_MAX_VERSION),
+
+		/* reserve extra space in savegame here. (currently 10 bytes) */
+		SLE_CONDNULL(10,                                                           2, SL_MAX_VERSION),
+
+		     SLE_END()
+	};
+
+
+	static const SaveLoad _train_desc[] = {
+		SLE_WRITEBYTE(Vehicle, type, VEH_TRAIN),
+		SLE_VEH_INCLUDEX(),
+		    SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRail, crash_anim_pos),      SLE_UINT16),
+		    SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRail, force_proceed),       SLE_UINT8),
+		    SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRail, railtype),            SLE_UINT8),
+		    SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRail, track),               SLE_UINT8),
+
+		SLE_CONDVARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRail, flags),               SLE_FILE_U8  | SLE_VAR_U16,   2,  99),
+		SLE_CONDVARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRail, flags),               SLE_UINT16,                 100, SL_MAX_VERSION),
+		SLE_CONDNULL(2, 2, 59),
+
+		SLE_CONDNULL(2, 2, 19),
+		/* reserve extra space in savegame here. (currently 11 bytes) */
+		SLE_CONDNULL(11, 2, SL_MAX_VERSION),
+
+		     SLE_END()
+	};
+
+	static const SaveLoad _roadveh_desc[] = {
+		SLE_WRITEBYTE(Vehicle, type, VEH_ROAD),
+		SLE_VEH_INCLUDEX(),
+		    SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRoad, state),                SLE_UINT8),
+		    SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRoad, frame),                SLE_UINT8),
+		    SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRoad, blocked_ctr),          SLE_UINT16),
+		    SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRoad, overtaking),           SLE_UINT8),
+		    SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRoad, overtaking_ctr),       SLE_UINT8),
+		    SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRoad, crashed_ctr),          SLE_UINT16),
+		    SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRoad, reverse_ctr),          SLE_UINT8),
+
+		SLE_CONDREFX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRoad, slot),                 REF_ROADSTOPS,                6, SL_MAX_VERSION),
+		SLE_CONDNULL(1,                                                            6, SL_MAX_VERSION),
+		SLE_CONDVARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRoad, slot_age),             SLE_UINT8,                    6, SL_MAX_VERSION),
+		/* reserve extra space in savegame here. (currently 16 bytes) */
+		SLE_CONDNULL(16,                                                           2, SL_MAX_VERSION),
+
+		     SLE_END()
+	};
+
+	static const SaveLoad _ship_desc[] = {
+		SLE_WRITEBYTE(Vehicle, type, VEH_SHIP),
+		SLE_VEH_INCLUDEX(),
+		    SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleShip, state),  SLE_UINT8),
+
+		/* reserve extra space in savegame here. (currently 16 bytes) */
+		SLE_CONDNULL(16, 2, SL_MAX_VERSION),
+
+		     SLE_END()
+	};
+
+	static const SaveLoad _aircraft_desc[] = {
+		SLE_WRITEBYTE(Vehicle, type, VEH_AIRCRAFT),
+		SLE_VEH_INCLUDEX(),
+		    SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleAir, crashed_counter),       SLE_UINT16),
+		    SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleAir, pos),                   SLE_UINT8),
+
+		SLE_CONDVARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleAir, targetairport),         SLE_FILE_U8  | SLE_VAR_U16,   0, 4),
+		SLE_CONDVARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleAir, targetairport),         SLE_UINT16,                   5, SL_MAX_VERSION),
+
+		    SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleAir, state),                 SLE_UINT8),
+
+		SLE_CONDVARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleAir, previous_pos),          SLE_UINT8,                    2, SL_MAX_VERSION),
+
+		/* reserve extra space in savegame here. (currently 15 bytes) */
+		SLE_CONDNULL(15,                                                           2, SL_MAX_VERSION),
+
+		     SLE_END()
+	};
+
+	static const SaveLoad _special_desc[] = {
+		SLE_WRITEBYTE(Vehicle, type, VEH_EFFECT),
+
+		     SLE_VAR(Vehicle, subtype,               SLE_UINT8),
+
+		 SLE_CONDVAR(Vehicle, tile,                  SLE_FILE_U16 | SLE_VAR_U32,   0,   5),
+		 SLE_CONDVAR(Vehicle, tile,                  SLE_UINT32,                   6, SL_MAX_VERSION),
+
+		 SLE_CONDVAR(Vehicle, x_pos,                 SLE_FILE_I16 | SLE_VAR_I32,   0,   5),
+		 SLE_CONDVAR(Vehicle, x_pos,                 SLE_INT32,                    6, SL_MAX_VERSION),
+		 SLE_CONDVAR(Vehicle, y_pos,                 SLE_FILE_I16 | SLE_VAR_I32,   0,   5),
+		 SLE_CONDVAR(Vehicle, y_pos,                 SLE_INT32,                    6, SL_MAX_VERSION),
+		     SLE_VAR(Vehicle, z_pos,                 SLE_UINT8),
+
+		     SLE_VAR(Vehicle, cur_image,             SLE_UINT16),
+		SLE_CONDNULL(5,                                                            0,  57),
+		     SLE_VAR(Vehicle, progress,              SLE_UINT8),
+		     SLE_VAR(Vehicle, vehstatus,             SLE_UINT8),
+
+		    SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleEffect, animation_state),    SLE_UINT16),
+		    SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleEffect, animation_substate), SLE_UINT8),
+
+		 SLE_CONDVAR(Vehicle, spritenum,             SLE_UINT8,                    2, SL_MAX_VERSION),
+
+		/* reserve extra space in savegame here. (currently 15 bytes) */
+		SLE_CONDNULL(15,                                                           2, SL_MAX_VERSION),
+
+		     SLE_END()
+	};
+
+	static const SaveLoad _disaster_desc[] = {
+		SLE_WRITEBYTE(Vehicle, type, VEH_DISASTER),
+
+		     SLE_REF(Vehicle, next,                  REF_VEHICLE_OLD),
+
+		     SLE_VAR(Vehicle, subtype,               SLE_UINT8),
+		 SLE_CONDVAR(Vehicle, tile,                  SLE_FILE_U16 | SLE_VAR_U32,   0,   5),
+		 SLE_CONDVAR(Vehicle, tile,                  SLE_UINT32,                   6, SL_MAX_VERSION),
+		 SLE_CONDVAR(Vehicle, dest_tile,             SLE_FILE_U16 | SLE_VAR_U32,   0,   5),
+		 SLE_CONDVAR(Vehicle, dest_tile,             SLE_UINT32,                   6, SL_MAX_VERSION),
+
+		 SLE_CONDVAR(Vehicle, x_pos,                 SLE_FILE_I16 | SLE_VAR_I32,   0,   5),
+		 SLE_CONDVAR(Vehicle, x_pos,                 SLE_INT32,                    6, SL_MAX_VERSION),
+		 SLE_CONDVAR(Vehicle, y_pos,                 SLE_FILE_I16 | SLE_VAR_I32,   0,   5),
+		 SLE_CONDVAR(Vehicle, y_pos,                 SLE_INT32,                    6, SL_MAX_VERSION),
+		     SLE_VAR(Vehicle, z_pos,                 SLE_UINT8),
+		     SLE_VAR(Vehicle, direction,             SLE_UINT8),
+
+		SLE_CONDNULL(5,                                                            0,  57),
+		     SLE_VAR(Vehicle, owner,                 SLE_UINT8),
+		     SLE_VAR(Vehicle, vehstatus,             SLE_UINT8),
+		SLE_CONDVARX(cpp_offsetof(Vehicle, current_order) + cpp_offsetof(Order, dest),           SLE_FILE_U8 | SLE_VAR_U16,   0,   4),
+		SLE_CONDVARX(cpp_offsetof(Vehicle, current_order) + cpp_offsetof(Order, dest),           SLE_UINT16,                  5, SL_MAX_VERSION),
+
+		     SLE_VAR(Vehicle, cur_image,             SLE_UINT16),
+		 SLE_CONDVAR(Vehicle, age,                   SLE_FILE_U16 | SLE_VAR_I32,   0,  30),
+		 SLE_CONDVAR(Vehicle, age,                   SLE_INT32,                   31, SL_MAX_VERSION),
+		     SLE_VAR(Vehicle, tick_counter,          SLE_UINT8),
+
+		    SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleDisaster, image_override),            SLE_UINT16),
+		    SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleDisaster, big_ufo_destroyer_target),  SLE_UINT16),
+
+		/* reserve extra space in savegame here. (currently 16 bytes) */
+		SLE_CONDNULL(16,                                                           2, SL_MAX_VERSION),
+
+		     SLE_END()
+	};
+
+
+	static const SaveLoad *_veh_descs[] = {
+		_train_desc,
+		_roadveh_desc,
+		_ship_desc,
+		_aircraft_desc,
+		_special_desc,
+		_disaster_desc,
+		_common_veh_desc,
+	};
+
+	return _veh_descs[vt];
+}
+
+/** Will be called when the vehicles need to be saved. */
+static void Save_VEHS()
+{
+	Vehicle *v;
+	/* Write the vehicles */
+	FOR_ALL_VEHICLES(v) {
+		SlSetArrayIndex(v->index);
+		SlObject(v, GetVehicleDescription(v->type));
+	}
+}
+
+/** Will be called when vehicles need to be loaded. */
+void Load_VEHS()
+{
+	int index;
+
+	_cargo_count = 0;
+
+	while ((index = SlIterateArray()) != -1) {
+		Vehicle *v;
+		VehicleType vtype = (VehicleType)SlReadByte();
+
+		switch (vtype) {
+			case VEH_TRAIN:    v = new (index) Train();           break;
+			case VEH_ROAD:     v = new (index) RoadVehicle();     break;
+			case VEH_SHIP:     v = new (index) Ship();            break;
+			case VEH_AIRCRAFT: v = new (index) Aircraft();        break;
+			case VEH_EFFECT:   v = new (index) EffectVehicle();   break;
+			case VEH_DISASTER: v = new (index) DisasterVehicle(); break;
+			case VEH_INVALID:  v = new (index) InvalidVehicle();  break;
+			default: NOT_REACHED();
+		}
+
+		SlObject(v, GetVehicleDescription(vtype));
+
+		if (_cargo_count != 0 && IsCompanyBuildableVehicleType(v)) {
+			/* Don't construct the packet with station here, because that'll fail with old savegames */
+			CargoPacket *cp = new CargoPacket();
+			cp->source          = _cargo_source;
+			cp->source_xy       = _cargo_source_xy;
+			cp->count           = _cargo_count;
+			cp->days_in_transit = _cargo_days;
+			cp->feeder_share    = _cargo_feeder_share;
+			cp->loaded_at_xy    = _cargo_loaded_at_xy;
+			v->cargo.Append(cp);
+		}
+
+		/* Old savegames used 'last_station_visited = 0xFF' */
+		if (CheckSavegameVersion(5) && v->last_station_visited == 0xFF)
+			v->last_station_visited = INVALID_STATION;
+
+		if (CheckSavegameVersion(5)) {
+			/* Convert the current_order.type (which is a mix of type and flags, because
+			 *  in those versions, they both were 4 bits big) to type and flags */
+			v->current_order.flags = GB(v->current_order.type, 4, 4);
+			v->current_order.type &= 0x0F;
+		}
+
+		/* Advanced vehicle lists got added */
+		if (CheckSavegameVersion(60)) v->group_id = DEFAULT_GROUP;
+	}
+}
+
+extern const ChunkHandler _veh_chunk_handlers[] = {
+	{ 'VEHS', Save_VEHS, Load_VEHS, CH_SPARSE_ARRAY | CH_LAST},
+};
new file mode 100644
--- /dev/null
+++ b/src/saveload/waypoint_sl.cpp
@@ -0,0 +1,96 @@
+/* $Id$ */
+
+/** @file waypoint_sl.cpp Code handling saving and loading of waypoints */
+
+#include "../stdafx.h"
+#include "../waypoint.h"
+#include "../newgrf_station.h"
+#include "../town.h"
+
+#include "table/strings.h"
+
+#include "saveload.h"
+
+/**
+ * Update waypoint graphics id against saved GRFID/localidx.
+ * This is to ensure the chosen graphics are correct if GRF files are changed.
+ */
+void AfterLoadWaypoints()
+{
+	Waypoint *wp;
+
+	FOR_ALL_WAYPOINTS(wp) {
+		uint i;
+
+		if (wp->grfid == 0) continue;
+
+		for (i = 0; i < GetNumCustomStations(STAT_CLASS_WAYP); i++) {
+			const StationSpec *statspec = GetCustomStationSpec(STAT_CLASS_WAYP, i);
+			if (statspec != NULL && statspec->grffile->grfid == wp->grfid && statspec->localidx == wp->localidx) {
+				wp->stat_id = i;
+				break;
+			}
+		}
+	}
+}
+
+/**
+ * Fix savegames which stored waypoints in their old format
+ */
+void FixOldWaypoints()
+{
+	Waypoint *wp;
+
+	/* Convert the old 'town_or_string', to 'string' / 'town' / 'town_cn' */
+	FOR_ALL_WAYPOINTS(wp) {
+		wp->town_index = ClosestTownFromTile(wp->xy, UINT_MAX)->index;
+		wp->town_cn = 0;
+		if (wp->string & 0xC000) {
+			wp->town_cn = wp->string & 0x3F;
+			wp->string = STR_NULL;
+		}
+	}
+}
+
+static const SaveLoad _waypoint_desc[] = {
+	SLE_CONDVAR(Waypoint, xy,         SLE_FILE_U16 | SLE_VAR_U32,  0, 5),
+	SLE_CONDVAR(Waypoint, xy,         SLE_UINT32,                  6, SL_MAX_VERSION),
+	SLE_CONDVAR(Waypoint, town_index, SLE_UINT16,                 12, SL_MAX_VERSION),
+	SLE_CONDVAR(Waypoint, town_cn,    SLE_FILE_U8 | SLE_VAR_U16,  12, 88),
+	SLE_CONDVAR(Waypoint, town_cn,    SLE_UINT16,                 89, SL_MAX_VERSION),
+	SLE_CONDVAR(Waypoint, string,     SLE_STRINGID,                0, 83),
+	SLE_CONDSTR(Waypoint, name,       SLE_STR, 0,                 84, SL_MAX_VERSION),
+	    SLE_VAR(Waypoint, deleted,    SLE_UINT8),
+
+	SLE_CONDVAR(Waypoint, build_date, SLE_FILE_U16 | SLE_VAR_I32,  3, 30),
+	SLE_CONDVAR(Waypoint, build_date, SLE_INT32,                  31, SL_MAX_VERSION),
+	SLE_CONDVAR(Waypoint, localidx,   SLE_UINT8,                   3, SL_MAX_VERSION),
+	SLE_CONDVAR(Waypoint, grfid,      SLE_UINT32,                 17, SL_MAX_VERSION),
+	SLE_CONDVAR(Waypoint, owner,      SLE_UINT8,                 101, SL_MAX_VERSION),
+
+	SLE_END()
+};
+
+static void Save_WAYP()
+{
+	Waypoint *wp;
+
+	FOR_ALL_WAYPOINTS(wp) {
+		SlSetArrayIndex(wp->index);
+		SlObject(wp, _waypoint_desc);
+	}
+}
+
+static void Load_WAYP()
+{
+	int index;
+
+	while ((index = SlIterateArray()) != -1) {
+		Waypoint *wp = new (index) Waypoint();
+		SlObject(wp, _waypoint_desc);
+	}
+}
+
+extern const ChunkHandler _waypoint_chunk_handlers[] = {
+	{ 'CHKP', Save_WAYP, Load_WAYP, CH_ARRAY | CH_LAST},
+};
--- a/src/screenshot.cpp
+++ b/src/screenshot.cpp
@@ -17,7 +17,7 @@
 #include "core/alloc_func.hpp"
 #include "core/endian_func.hpp"
 #include "map_func.h"
-#include "saveload.h"
+#include "saveload/saveload.h"
 #include "company_func.h"
 
 #include "table/strings.h"
--- a/src/settings.cpp
+++ b/src/settings.cpp
@@ -29,7 +29,6 @@
 #include "settings_internal.h"
 #include "command_func.h"
 #include "console_func.h"
-#include "saveload.h"
 #include "npf.h"
 #include "yapf/yapf.h"
 #include "newgrf.h"
--- a/src/settings_internal.h
+++ b/src/settings_internal.h
@@ -5,7 +5,7 @@
 #ifndef SETTINGS_INTERNAL_H
 #define SETTINGS_INTERNAL_H
 
-#include "saveload.h"
+#include "saveload/saveload.h"
 #include "settings_type.h"
 
 /** Convention/Type of settings. This is then further specified if necessary
--- a/src/signs.cpp
+++ b/src/signs.cpp
@@ -8,7 +8,6 @@
 #include "company_func.h"
 #include "signs_base.h"
 #include "signs_func.h"
-#include "saveload.h"
 #include "command_func.h"
 #include "variables.h"
 #include "strings_func.h"
@@ -56,17 +55,12 @@
 	UpdateViewportSignPos(&si->sign, pt.x, pt.y - 6, STR_2806);
 }
 
-/**
- *
- * Update the coordinates of all signs
- *
- */
+/** Update the coordinates of all signs */
 void UpdateAllSignVirtCoords()
 {
 	Sign *si;
 
 	FOR_ALL_SIGNS(si) UpdateSignVirtCoords(si);
-
 }
 
 /**
@@ -203,48 +197,3 @@
 	_Sign_pool.CleanPool();
 	_Sign_pool.AddBlockToPool();
 }
-
-static const SaveLoad _sign_desc[] = {
-  SLE_CONDVAR(Sign, name,  SLE_NAME,                   0, 83),
-  SLE_CONDSTR(Sign, name,  SLE_STR, 0,                84, SL_MAX_VERSION),
-  SLE_CONDVAR(Sign, x,     SLE_FILE_I16 | SLE_VAR_I32, 0, 4),
-  SLE_CONDVAR(Sign, y,     SLE_FILE_I16 | SLE_VAR_I32, 0, 4),
-  SLE_CONDVAR(Sign, x,     SLE_INT32,                  5, SL_MAX_VERSION),
-  SLE_CONDVAR(Sign, y,     SLE_INT32,                  5, SL_MAX_VERSION),
-  SLE_CONDVAR(Sign, owner, SLE_UINT8,                  6, SL_MAX_VERSION),
-      SLE_VAR(Sign, z,     SLE_UINT8),
-	SLE_END()
-};
-
-/**
- *
- * Save all signs
- *
- */
-static void Save_SIGN()
-{
-	Sign *si;
-
-	FOR_ALL_SIGNS(si) {
-		SlSetArrayIndex(si->index);
-		SlObject(si, _sign_desc);
-	}
-}
-
-/**
- *
- * Load all signs
- *
- */
-static void Load_SIGN()
-{
-	int index;
-	while ((index = SlIterateArray()) != -1) {
-		Sign *si = new (index) Sign();
-		SlObject(si, _sign_desc);
-	}
-}
-
-extern const ChunkHandler _sign_chunk_handlers[] = {
-	{ 'SIGN', Save_SIGN, Load_SIGN, CH_ARRAY | CH_LAST},
-};
--- a/src/signs_base.h
+++ b/src/signs_base.h
@@ -7,6 +7,7 @@
 
 #include "signs_type.h"
 #include "viewport_type.h"
+#include "tile_type.h"
 #include "oldpool.h"
 
 DECLARE_OLD_POOL(Sign, Sign, 2, 16000)
--- a/src/station.cpp
+++ b/src/station.cpp
@@ -9,7 +9,6 @@
 #include "station_map.h"
 #include "station_base.h"
 #include "town.h"
-#include "saveload.h"
 #include "company_func.h"
 #include "airport.h"
 #include "sprite.h"
--- a/src/station_cmd.cpp
+++ b/src/station_cmd.cpp
@@ -15,7 +15,6 @@
 #include "command_func.h"
 #include "town.h"
 #include "news_func.h"
-#include "saveload.h"
 #include "airport.h"
 #include "sprite.h"
 #include "train.h"
@@ -3185,24 +3184,6 @@
 	_station_tick_ctr = 0;
 }
 
-
-void AfterLoadStations()
-{
-	/* Update the speclists of all stations to point to the currently loaded custom stations. */
-	Station *st;
-	FOR_ALL_STATIONS(st) {
-		for (uint i = 0; i < st->num_specs; i++) {
-			if (st->speclist[i].grfid == 0) continue;
-
-			st->speclist[i].spec = GetCustomStationSpecByGrf(st->speclist[i].grfid, st->speclist[i].localidx);
-		}
-
-		for (CargoID c = 0; c < NUM_CARGO; c++) st->goods[c].cargo.InvalidateCache();
-
-		StationUpdateAnimTriggers(st);
-	}
-}
-
 static CommandCost TerraformTile_Station(TileIndex tile, uint32 flags, uint z_new, Slope tileh_new)
 {
 	if (_settings_game.construction.build_on_slopes && AutoslopeEnabled()) {
@@ -3255,200 +3236,3 @@
 	GetFoundation_Station,      /* get_foundation_proc */
 	TerraformTile_Station,      /* terraform_tile_proc */
 };
-
-static const SaveLoad _roadstop_desc[] = {
-	SLE_VAR(RoadStop, xy,           SLE_UINT32),
-	SLE_CONDNULL(1, 0, 44),
-	SLE_VAR(RoadStop, status,       SLE_UINT8),
-	/* Index was saved in some versions, but this is not needed */
-	SLE_CONDNULL(4, 0, 8),
-	SLE_CONDNULL(2, 0, 44),
-	SLE_CONDNULL(1, 0, 25),
-
-	SLE_REF(RoadStop, next,         REF_ROADSTOPS),
-	SLE_CONDNULL(2, 0, 44),
-
-	SLE_CONDNULL(4, 0, 24),
-	SLE_CONDNULL(1, 25, 25),
-
-	SLE_END()
-};
-
-static const SaveLoad _station_desc[] = {
-	SLE_CONDVAR(Station, xy,                         SLE_FILE_U16 | SLE_VAR_U32,  0, 5),
-	SLE_CONDVAR(Station, xy,                         SLE_UINT32,                  6, SL_MAX_VERSION),
-	SLE_CONDNULL(4, 0, 5),  ///< bus/lorry tile
-	SLE_CONDVAR(Station, train_tile,                 SLE_FILE_U16 | SLE_VAR_U32,  0, 5),
-	SLE_CONDVAR(Station, train_tile,                 SLE_UINT32,                  6, SL_MAX_VERSION),
-	SLE_CONDVAR(Station, airport_tile,               SLE_FILE_U16 | SLE_VAR_U32,  0, 5),
-	SLE_CONDVAR(Station, airport_tile,               SLE_UINT32,                  6, SL_MAX_VERSION),
-	SLE_CONDVAR(Station, dock_tile,                  SLE_FILE_U16 | SLE_VAR_U32,  0, 5),
-	SLE_CONDVAR(Station, dock_tile,                  SLE_UINT32,                  6, SL_MAX_VERSION),
-	    SLE_REF(Station, town,                       REF_TOWN),
-	    SLE_VAR(Station, trainst_w,                  SLE_UINT8),
-	SLE_CONDVAR(Station, trainst_h,                  SLE_UINT8,                   2, SL_MAX_VERSION),
-
-	SLE_CONDNULL(1, 0, 3),  ///< alpha_order
-
-	    SLE_VAR(Station, string_id,                  SLE_STRINGID),
-	SLE_CONDSTR(Station, name,                       SLE_STR, 0,                 84, SL_MAX_VERSION),
-	SLE_CONDVAR(Station, indtype,                    SLE_UINT8,                 103, SL_MAX_VERSION),
-	    SLE_VAR(Station, had_vehicle_of_type,        SLE_UINT16),
-
-	    SLE_VAR(Station, time_since_load,            SLE_UINT8),
-	    SLE_VAR(Station, time_since_unload,          SLE_UINT8),
-	    SLE_VAR(Station, delete_ctr,                 SLE_UINT8),
-	    SLE_VAR(Station, owner,                      SLE_UINT8),
-	    SLE_VAR(Station, facilities,                 SLE_UINT8),
-	    SLE_VAR(Station, airport_type,               SLE_UINT8),
-
-	SLE_CONDNULL(2, 0, 5),  ///< Truck/bus stop status
-	SLE_CONDNULL(1, 0, 4),  ///< Blocked months
-
-	SLE_CONDVAR(Station, airport_flags,              SLE_VAR_U64 | SLE_FILE_U16,  0,  2),
-	SLE_CONDVAR(Station, airport_flags,              SLE_VAR_U64 | SLE_FILE_U32,  3, 45),
-	SLE_CONDVAR(Station, airport_flags,              SLE_UINT64,                 46, SL_MAX_VERSION),
-
-	SLE_CONDNULL(2, 0, 25), ///< last-vehicle
-	SLE_CONDVAR(Station, last_vehicle_type,          SLE_UINT8,                  26, SL_MAX_VERSION),
-
-	SLE_CONDNULL(2, 3, 25), ///< custom station class and id
-	SLE_CONDVAR(Station, build_date,                 SLE_FILE_U16 | SLE_VAR_I32,  3, 30),
-	SLE_CONDVAR(Station, build_date,                 SLE_INT32,                  31, SL_MAX_VERSION),
-
-	SLE_CONDREF(Station, bus_stops,                  REF_ROADSTOPS,               6, SL_MAX_VERSION),
-	SLE_CONDREF(Station, truck_stops,                REF_ROADSTOPS,               6, SL_MAX_VERSION),
-
-	/* Used by newstations for graphic variations */
-	SLE_CONDVAR(Station, random_bits,                SLE_UINT16,                 27, SL_MAX_VERSION),
-	SLE_CONDVAR(Station, waiting_triggers,           SLE_UINT8,                  27, SL_MAX_VERSION),
-	SLE_CONDVAR(Station, num_specs,                  SLE_UINT8,                  27, SL_MAX_VERSION),
-
-	SLE_CONDLST(Station, loading_vehicles,           REF_VEHICLE,                57, SL_MAX_VERSION),
-
-	/* reserve extra space in savegame here. (currently 32 bytes) */
-	SLE_CONDNULL(32, 2, SL_MAX_VERSION),
-
-	SLE_END()
-};
-
-static uint16 _waiting_acceptance;
-static uint16 _cargo_source;
-static uint32 _cargo_source_xy;
-static uint16 _cargo_days;
-static Money  _cargo_feeder_share;
-
-static const SaveLoad _station_speclist_desc[] = {
-	SLE_CONDVAR(StationSpecList, grfid,    SLE_UINT32, 27, SL_MAX_VERSION),
-	SLE_CONDVAR(StationSpecList, localidx, SLE_UINT8,  27, SL_MAX_VERSION),
-
-	SLE_END()
-};
-
-
-void SaveLoad_STNS(Station *st)
-{
-	static const SaveLoad _goods_desc[] = {
-		SLEG_CONDVAR(            _waiting_acceptance, SLE_UINT16,                  0, 67),
-		 SLE_CONDVAR(GoodsEntry, acceptance_pickup,   SLE_UINT8,                  68, SL_MAX_VERSION),
-		SLE_CONDNULL(2,                                                           51, 67),
-		     SLE_VAR(GoodsEntry, days_since_pickup,   SLE_UINT8),
-		     SLE_VAR(GoodsEntry, rating,              SLE_UINT8),
-		SLEG_CONDVAR(            _cargo_source,       SLE_FILE_U8 | SLE_VAR_U16,   0, 6),
-		SLEG_CONDVAR(            _cargo_source,       SLE_UINT16,                  7, 67),
-		SLEG_CONDVAR(            _cargo_source_xy,    SLE_UINT32,                 44, 67),
-		SLEG_CONDVAR(            _cargo_days,         SLE_UINT8,                   0, 67),
-		     SLE_VAR(GoodsEntry, last_speed,          SLE_UINT8),
-		     SLE_VAR(GoodsEntry, last_age,            SLE_UINT8),
-		SLEG_CONDVAR(            _cargo_feeder_share, SLE_FILE_U32 | SLE_VAR_I64, 14, 64),
-		SLEG_CONDVAR(            _cargo_feeder_share, SLE_INT64,                  65, 67),
-		 SLE_CONDLST(GoodsEntry, cargo.packets,       REF_CARGO_PACKET,           68, SL_MAX_VERSION),
-
-		SLE_END()
-};
-
-
-	SlObject(st, _station_desc);
-
-	_waiting_acceptance = 0;
-
-	uint num_cargo = CheckSavegameVersion(55) ? 12 : NUM_CARGO;
-	for (CargoID i = 0; i < num_cargo; i++) {
-		GoodsEntry *ge = &st->goods[i];
-		SlObject(ge, _goods_desc);
-		if (CheckSavegameVersion(68)) {
-			SB(ge->acceptance_pickup, GoodsEntry::ACCEPTANCE, 1, HasBit(_waiting_acceptance, 15));
-			if (GB(_waiting_acceptance, 0, 12) != 0) {
-				/* Don't construct the packet with station here, because that'll fail with old savegames */
-				CargoPacket *cp = new CargoPacket();
-				/* In old versions, enroute_from used 0xFF as INVALID_STATION */
-				cp->source          = (CheckSavegameVersion(7) && _cargo_source == 0xFF) ? INVALID_STATION : _cargo_source;
-				cp->count           = GB(_waiting_acceptance, 0, 12);
-				cp->days_in_transit = _cargo_days;
-				cp->feeder_share    = _cargo_feeder_share;
-				cp->source_xy       = _cargo_source_xy;
-				cp->days_in_transit = _cargo_days;
-				cp->feeder_share    = _cargo_feeder_share;
-				SB(ge->acceptance_pickup, GoodsEntry::PICKUP, 1, 1);
-				ge->cargo.Append(cp);
-			}
-		}
-	}
-
-	if (st->num_specs != 0) {
-		/* Allocate speclist memory when loading a game */
-		if (st->speclist == NULL) st->speclist = CallocT<StationSpecList>(st->num_specs);
-		for (uint i = 0; i < st->num_specs; i++) {
-			SlObject(&st->speclist[i], _station_speclist_desc);
-		}
-	}
-}
-
-static void Save_STNS()
-{
-	Station *st;
-	/* Write the stations */
-	FOR_ALL_STATIONS(st) {
-		SlSetArrayIndex(st->index);
-		SlAutolength((AutolengthProc*)SaveLoad_STNS, st);
-	}
-}
-
-static void Load_STNS()
-{
-	int index;
-	while ((index = SlIterateArray()) != -1) {
-		Station *st = new (index) Station();
-
-		SaveLoad_STNS(st);
-	}
-
-	/* This is to ensure all pointers are within the limits of _stations_size */
-	if (_station_tick_ctr > GetMaxStationIndex()) _station_tick_ctr = 0;
-}
-
-static void Save_ROADSTOP()
-{
-	RoadStop *rs;
-
-	FOR_ALL_ROADSTOPS(rs) {
-		SlSetArrayIndex(rs->index);
-		SlObject(rs, _roadstop_desc);
-	}
-}
-
-static void Load_ROADSTOP()
-{
-	int index;
-
-	while ((index = SlIterateArray()) != -1) {
-		RoadStop *rs = new (index) RoadStop(INVALID_TILE);
-
-		SlObject(rs, _roadstop_desc);
-	}
-}
-
-extern const ChunkHandler _station_chunk_handlers[] = {
-	{ 'STNS', Save_STNS,      Load_STNS,      CH_ARRAY },
-	{ 'ROAD', Save_ROADSTOP,  Load_ROADSTOP,  CH_ARRAY | CH_LAST},
-};
--- a/src/station_func.h
+++ b/src/station_func.h
@@ -25,7 +25,6 @@
 void ShowStationViewWindow(StationID station);
 void UpdateAllStationVirtCoord();
 
-void AfterLoadStations();
 void GetProductionAroundTiles(AcceptedCargo produced, TileIndex tile, int w, int h, int rad);
 void GetAcceptanceAroundTiles(AcceptedCargo accepts, TileIndex tile, int w, int h, int rad);
 
--- a/src/strings.cpp
+++ b/src/strings.cpp
@@ -39,7 +39,6 @@
 #include "video/video_driver.hpp"
 #include "engine_func.h"
 #include "engine_base.h"
-#include "saveload.h"
 #include "strgen/strgen.h"
 
 #include "table/strings.h"
@@ -1593,114 +1592,3 @@
 
 /* --- Handling of saving/loading string IDs from old savegames --- */
 
-/**
- * Remap a string ID from the old format to the new format
- * @param s StringID that requires remapping
- * @return translated ID
- */
-StringID RemapOldStringID(StringID s)
-{
-	switch (s) {
-		case 0x0006: return STR_SV_EMPTY;
-		case 0x7000: return STR_SV_UNNAMED;
-		case 0x70E4: return SPECSTR_PLAYERNAME_ENGLISH;
-		case 0x70E9: return SPECSTR_PLAYERNAME_ENGLISH;
-		case 0x8864: return STR_SV_TRAIN_NAME;
-		case 0x902B: return STR_SV_ROADVEH_NAME;
-		case 0x9830: return STR_SV_SHIP_NAME;
-		case 0xA02F: return STR_SV_AIRCRAFT_NAME;
-
-		default:
-			if (IsInsideMM(s, 0x300F, 0x3030)) {
-				return s - 0x300F + STR_SV_STNAME;
-			} else {
-				return s;
-			}
-	}
-}
-
-/** Location to load the old names to. */
-char *_old_name_array = NULL;
-
-/**
- * Copy and convert old custom names to UTF-8.
- * They were all stored in a 512 by 32 long string array and are
- * now stored with stations, waypoints and other places with names.
- * @param id the StringID of the custom name to clone.
- * @return the clones custom name.
- */
-char *CopyFromOldName(StringID id)
-{
-	/* Is this name an (old) custom name? */
-	if (GB(id, 11, 5) != 15) return NULL;
-
-	if (CheckSavegameVersion(37)) {
-		/* Old names were 32 characters long, so 128 characters should be
-		 * plenty to allow for expansion when converted to UTF-8. */
-		char tmp[128];
-		const char *strfrom = &_old_name_array[32 * GB(id, 0, 9)];
-		char *strto = tmp;
-
-		for (; *strfrom != '\0'; strfrom++) {
-			WChar c = (byte)*strfrom;
-
-			/* Map from non-ISO8859-15 characters to UTF-8. */
-			switch (c) {
-				case 0xA4: c = 0x20AC; break; // Euro
-				case 0xA6: c = 0x0160; break; // S with caron
-				case 0xA8: c = 0x0161; break; // s with caron
-				case 0xB4: c = 0x017D; break; // Z with caron
-				case 0xB8: c = 0x017E; break; // z with caron
-				case 0xBC: c = 0x0152; break; // OE ligature
-				case 0xBD: c = 0x0153; break; // oe ligature
-				case 0xBE: c = 0x0178; break; // Y with diaresis
-				default: break;
-			}
-
-			/* Check character will fit into our buffer. */
-			if (strto + Utf8CharLen(c) > lastof(tmp)) break;
-
-			strto += Utf8Encode(strto, c);
-		}
-
-		/* Terminate the new string and copy it back to the name array */
-		*strto = '\0';
-
-		return strdup(tmp);
-	} else {
-		/* Name will already be in UTF-8. */
-		return strdup(&_old_name_array[32 * GB(id, 0, 9)]);
-	}
-}
-
-/**
- * Free the memory of the old names array.
- * Should be called once the old names have all been converted.
- */
-void ResetOldNames()
-{
-	free(_old_name_array);
-	_old_name_array = NULL;
-}
-
-/**
- * Initialize the old names table memory.
- */
-void InitializeOldNames()
-{
-	free(_old_name_array);
-	_old_name_array = CallocT<char>(512 * 32);
-}
-
-static void Load_NAME()
-{
-	int index;
-
-	while ((index = SlIterateArray()) != -1) {
-		SlArray(&_old_name_array[32 * index], SlGetFieldLength(), SLE_UINT8);
-	}
-}
-
-extern const ChunkHandler _name_chunk_handlers[] = {
-	{ 'NAME', NULL, Load_NAME, CH_ARRAY | CH_LAST},
-};
--- a/src/strings_func.h
+++ b/src/strings_func.h
@@ -68,7 +68,4 @@
 
 void CheckForMissingGlyphsInLoadedLanguagePack();
 
-StringID RemapOldStringID(StringID s);
-char *CopyFromOldName(StringID id);
-
 #endif /* STRINGS_TYPE_H */
--- a/src/town.h
+++ b/src/town.h
@@ -362,7 +362,6 @@
 void ResetHouses();
 
 void ClearTownHouse(Town *t, TileIndex tile);
-void AfterLoadTown();
 void UpdateTownMaxPass(Town *t);
 void UpdateTownRadius(Town *t);
 bool CheckIfAuthorityAllows(TileIndex tile);
--- a/src/town_cmd.cpp
+++ b/src/town_cmd.cpp
@@ -19,7 +19,6 @@
 #include "station_base.h"
 #include "company_base.h"
 #include "news_func.h"
-#include "saveload.h"
 #include "gui.h"
 #include "unmovable_map.h"
 #include "water_map.h"
@@ -2676,155 +2675,6 @@
 	TerraformTile_Town,      // terraform_tile_proc
 };
 
-
-/** Save and load of towns. */
-static const SaveLoad _town_desc[] = {
-	SLE_CONDVAR(Town, xy,                    SLE_FILE_U16 | SLE_VAR_U32, 0, 5),
-	SLE_CONDVAR(Town, xy,                    SLE_UINT32,                 6, SL_MAX_VERSION),
-
-	SLE_CONDNULL(2, 0, 2),                   ///< population, no longer in use
-	SLE_CONDNULL(4, 3, 84),                  ///< population, no longer in use
-	SLE_CONDNULL(2, 0, 91),                  ///< num_houses, no longer in use
-
-	SLE_CONDVAR(Town, townnamegrfid,         SLE_UINT32, 66, SL_MAX_VERSION),
-	    SLE_VAR(Town, townnametype,          SLE_UINT16),
-	    SLE_VAR(Town, townnameparts,         SLE_UINT32),
-	SLE_CONDSTR(Town, name,                  SLE_STR, 0, 84, SL_MAX_VERSION),
-
-	    SLE_VAR(Town, flags12,               SLE_UINT8),
-	SLE_CONDVAR(Town, statues,               SLE_FILE_U8  | SLE_VAR_U16, 0, 103),
-	SLE_CONDVAR(Town, statues,               SLE_UINT16,               104, SL_MAX_VERSION),
-
-	SLE_CONDNULL(1, 0, 1),                   ///< sort_index, no longer in use
-
-	SLE_CONDVAR(Town, have_ratings,          SLE_FILE_U8  | SLE_VAR_U16, 0, 103),
-	SLE_CONDVAR(Town, have_ratings,          SLE_UINT16,               104, SL_MAX_VERSION),
-	SLE_CONDARR(Town, ratings,               SLE_INT16, 8,               0, 103),
-	SLE_CONDARR(Town, ratings,               SLE_INT16, MAX_COMPANIES, 104, SL_MAX_VERSION),
-	/* failed bribe attempts are stored since savegame format 4 */
-	SLE_CONDARR(Town, unwanted,              SLE_INT8,  8,               4, 103),
-	SLE_CONDARR(Town, unwanted,              SLE_INT8,  MAX_COMPANIES, 104, SL_MAX_VERSION),
-
-	SLE_CONDVAR(Town, max_pass,              SLE_FILE_U16 | SLE_VAR_U32, 0, 8),
-	SLE_CONDVAR(Town, max_mail,              SLE_FILE_U16 | SLE_VAR_U32, 0, 8),
-	SLE_CONDVAR(Town, new_max_pass,          SLE_FILE_U16 | SLE_VAR_U32, 0, 8),
-	SLE_CONDVAR(Town, new_max_mail,          SLE_FILE_U16 | SLE_VAR_U32, 0, 8),
-	SLE_CONDVAR(Town, act_pass,              SLE_FILE_U16 | SLE_VAR_U32, 0, 8),
-	SLE_CONDVAR(Town, act_mail,              SLE_FILE_U16 | SLE_VAR_U32, 0, 8),
-	SLE_CONDVAR(Town, new_act_pass,          SLE_FILE_U16 | SLE_VAR_U32, 0, 8),
-	SLE_CONDVAR(Town, new_act_mail,          SLE_FILE_U16 | SLE_VAR_U32, 0, 8),
-
-	SLE_CONDVAR(Town, max_pass,              SLE_UINT32,                 9, SL_MAX_VERSION),
-	SLE_CONDVAR(Town, max_mail,              SLE_UINT32,                 9, SL_MAX_VERSION),
-	SLE_CONDVAR(Town, new_max_pass,          SLE_UINT32,                 9, SL_MAX_VERSION),
-	SLE_CONDVAR(Town, new_max_mail,          SLE_UINT32,                 9, SL_MAX_VERSION),
-	SLE_CONDVAR(Town, act_pass,              SLE_UINT32,                 9, SL_MAX_VERSION),
-	SLE_CONDVAR(Town, act_mail,              SLE_UINT32,                 9, SL_MAX_VERSION),
-	SLE_CONDVAR(Town, new_act_pass,          SLE_UINT32,                 9, SL_MAX_VERSION),
-	SLE_CONDVAR(Town, new_act_mail,          SLE_UINT32,                 9, SL_MAX_VERSION),
-
-	    SLE_VAR(Town, pct_pass_transported,  SLE_UINT8),
-	    SLE_VAR(Town, pct_mail_transported,  SLE_UINT8),
-
-	    SLE_VAR(Town, act_food,              SLE_UINT16),
-	    SLE_VAR(Town, act_water,             SLE_UINT16),
-	    SLE_VAR(Town, new_act_food,          SLE_UINT16),
-	    SLE_VAR(Town, new_act_water,         SLE_UINT16),
-
-	SLE_CONDVAR(Town, time_until_rebuild,    SLE_UINT8,                  0, 53),
-	SLE_CONDVAR(Town, grow_counter,          SLE_UINT8,                  0, 53),
-	SLE_CONDVAR(Town, growth_rate,           SLE_UINT8,                  0, 53),
-
-	SLE_CONDVAR(Town, time_until_rebuild,    SLE_UINT16,                54, SL_MAX_VERSION),
-	SLE_CONDVAR(Town, grow_counter,          SLE_UINT16,                54, SL_MAX_VERSION),
-	SLE_CONDVAR(Town, growth_rate,           SLE_INT16,                 54, SL_MAX_VERSION),
-
-	    SLE_VAR(Town, fund_buildings_months, SLE_UINT8),
-	    SLE_VAR(Town, road_build_months,     SLE_UINT8),
-
-	SLE_CONDVAR(Town, exclusivity,           SLE_UINT8,                  2, SL_MAX_VERSION),
-	SLE_CONDVAR(Town, exclusive_counter,     SLE_UINT8,                  2, SL_MAX_VERSION),
-
-	SLE_CONDVAR(Town, larger_town,           SLE_BOOL,                  56, SL_MAX_VERSION),
-
-	/* reserve extra space in savegame here. (currently 30 bytes) */
-	SLE_CONDNULL(30, 2, SL_MAX_VERSION),
-
-	SLE_END()
-};
-
-/* Save and load the mapping between the house id on the map, and the grf file
- * it came from. */
-static const SaveLoad _house_id_mapping_desc[] = {
-	SLE_VAR(EntityIDMapping, grfid,         SLE_UINT32),
-	SLE_VAR(EntityIDMapping, entity_id,     SLE_UINT8),
-	SLE_VAR(EntityIDMapping, substitute_id, SLE_UINT8),
-	SLE_END()
-};
-
-static void Save_HOUSEIDS()
-{
-	uint j = _house_mngr.GetMaxMapping();
-
-	for (uint i = 0; i < j; i++) {
-		SlSetArrayIndex(i);
-		SlObject(&_house_mngr.mapping_ID[i], _house_id_mapping_desc);
-	}
-}
-
-static void Load_HOUSEIDS()
-{
-	int index;
-
-	_house_mngr.ResetMapping();
-	uint max_id = _house_mngr.GetMaxMapping();
-
-	while ((index = SlIterateArray()) != -1) {
-		if ((uint)index >= max_id) break;
-		SlObject(&_house_mngr.mapping_ID[index], _house_id_mapping_desc);
-	}
-}
-
-static void Save_TOWN()
-{
-	Town *t;
-
-	FOR_ALL_TOWNS(t) {
-		SlSetArrayIndex(t->index);
-		SlObject(t, _town_desc);
-	}
-}
-
-static void Load_TOWN()
-{
-	int index;
-
-	_total_towns = 0;
-
-	while ((index = SlIterateArray()) != -1) {
-		Town *t = new (index) Town();
-		SlObject(t, _town_desc);
-
-		_total_towns++;
-	}
-
-	/* This is to ensure all pointers are within the limits of
-	 *  the size of the TownPool */
-	if (_cur_town_ctr > GetMaxTownIndex())
-		_cur_town_ctr = 0;
-}
-
-void AfterLoadTown()
-{
-	Town *t;
-	FOR_ALL_TOWNS(t) t->InitializeLayout();
-}
-
-extern const ChunkHandler _town_chunk_handlers[] = {
-	{ 'HIDS', Save_HOUSEIDS, Load_HOUSEIDS, CH_ARRAY },
-	{ 'CITY', Save_TOWN,     Load_TOWN,     CH_ARRAY | CH_LAST},
-};
-
 void ResetHouses()
 {
 	memset(&_house_specs, 0, sizeof(_house_specs));
--- a/src/train.h
+++ b/src/train.h
@@ -287,9 +287,6 @@
 	return w;
 }
 
-void ConvertOldMultiheadToNew();
-void ConnectMultiheadedTrains();
-
 void CcBuildLoco(bool success, TileIndex tile, uint32 p1, uint32 p2);
 void CcBuildWagon(bool success, TileIndex tile, uint32 p1, uint32 p2);
 
--- a/src/train_cmd.cpp
+++ b/src/train_cmd.cpp
@@ -4500,146 +4500,3 @@
 {
 	_age_cargo_skip_counter = 1;
 }
-
-/*
- * Link front and rear multiheaded engines to each other
- * This is done when loading a savegame
- */
-void ConnectMultiheadedTrains()
-{
-	Vehicle *v;
-
-	FOR_ALL_VEHICLES(v) {
-		if (v->type == VEH_TRAIN) {
-			v->u.rail.other_multiheaded_part = NULL;
-		}
-	}
-
-	FOR_ALL_VEHICLES(v) {
-		if (v->type == VEH_TRAIN && (IsFrontEngine(v) || IsFreeWagon(v))) {
-			/* Two ways to associate multiheaded parts to each other:
-			 * sequential-matching: Trains shall be arranged to look like <..>..<..>..<..>..
-			 * bracket-matching:    Free vehicle chains shall be arranged to look like ..<..<..>..<..>..>..
-			 *
-			 * Note: Old savegames might contain chains which do not comply with these rules, e.g.
-			 *   - the front and read parts have invalid orders
-			 *   - different engine types might be combined
-			 *   - there might be different amounts of front and rear parts.
-			 *
-			 * Note: The multiheaded parts need to be matched exactly like they are matched on the server, else desyncs will occur.
-			 *   This is why two matching strategies are needed.
-			 */
-
-			bool sequential_matching = IsFrontEngine(v);
-
-			for (Vehicle *u = v; u != NULL; u = GetNextVehicle(u)) {
-				if (u->u.rail.other_multiheaded_part != NULL) continue; // we already linked this one
-
-				if (IsMultiheaded(u)) {
-					if (!IsTrainEngine(u)) {
-						/* we got a rear car without a front car. We will convert it to a front one */
-						SetTrainEngine(u);
-						u->spritenum--;
-					}
-
-					/* Find a matching back part */
-					EngineID eid = u->engine_type;
-					Vehicle *w;
-					if (sequential_matching) {
-						for (w = GetNextVehicle(u); w != NULL; w = GetNextVehicle(w)) {
-							if (w->engine_type != eid || w->u.rail.other_multiheaded_part != NULL || !IsMultiheaded(w)) continue;
-
-							/* we found a car to partner with this engine. Now we will make sure it face the right way */
-							if (IsTrainEngine(w)) {
-								ClearTrainEngine(w);
-								w->spritenum++;
-							}
-							break;
-						}
-					} else {
-						uint stack_pos = 0;
-						for (w = GetNextVehicle(u); w != NULL; w = GetNextVehicle(w)) {
-							if (w->engine_type != eid || w->u.rail.other_multiheaded_part != NULL || !IsMultiheaded(w)) continue;
-
-							if (IsTrainEngine(w)) {
-								stack_pos++;
-							} else {
-								if (stack_pos == 0) break;
-								stack_pos--;
-							}
-						}
-					}
-
-					if (w != NULL) {
-						w->u.rail.other_multiheaded_part = u;
-						u->u.rail.other_multiheaded_part = w;
-					} else {
-						/* we got a front car and no rear cars. We will fake this one for forget that it should have been multiheaded */
-						ClearMultiheaded(u);
-					}
-				}
-			}
-		}
-	}
-}
-
-/**
- *  Converts all trains to the new subtype format introduced in savegame 16.2
- *  It also links multiheaded engines or make them forget they are multiheaded if no suitable partner is found
- */
-void ConvertOldMultiheadToNew()
-{
-	Vehicle *v;
-	FOR_ALL_VEHICLES(v) {
-		if (v->type == VEH_TRAIN) {
-			SetBit(v->subtype, 7); // indicates that it's the old format and needs to be converted in the next loop
-		}
-	}
-
-	FOR_ALL_VEHICLES(v) {
-		if (v->type == VEH_TRAIN) {
-			if (HasBit(v->subtype, 7) && ((v->subtype & ~0x80) == 0 || (v->subtype & ~0x80) == 4)) {
-				for (Vehicle *u = v; u != NULL; u = u->Next()) {
-					const RailVehicleInfo *rvi = RailVehInfo(u->engine_type);
-
-					ClrBit(u->subtype, 7);
-					switch (u->subtype) {
-						case 0: /* TS_Front_Engine */
-							if (rvi->railveh_type == RAILVEH_MULTIHEAD) SetMultiheaded(u);
-							SetFrontEngine(u);
-							SetTrainEngine(u);
-							break;
-
-						case 1: /* TS_Artic_Part */
-							u->subtype = 0;
-							SetArticulatedPart(u);
-							break;
-
-						case 2: /* TS_Not_First */
-							u->subtype = 0;
-							if (rvi->railveh_type == RAILVEH_WAGON) {
-								// normal wagon
-								SetTrainWagon(u);
-								break;
-							}
-							if (rvi->railveh_type == RAILVEH_MULTIHEAD && rvi->image_index == u->spritenum - 1) {
-								// rear end of a multiheaded engine
-								SetMultiheaded(u);
-								break;
-							}
-							if (rvi->railveh_type == RAILVEH_MULTIHEAD) SetMultiheaded(u);
-							SetTrainEngine(u);
-							break;
-
-						case 4: /* TS_Free_Car */
-							u->subtype = 0;
-							SetTrainWagon(u);
-							SetFreeWagon(u);
-							break;
-						default: NOT_REACHED(); break;
-					}
-				}
-			}
-		}
-	}
-}
--- a/src/variables.h
+++ b/src/variables.h
@@ -33,10 +33,6 @@
 /* Determines how often to run the tree loop */
 VARDEF byte _trees_tick_ctr;
 
-/* Keep track of current game position */
-VARDEF int _saved_scrollpos_x;
-VARDEF int _saved_scrollpos_y;
-
 /* NOSAVE: Used in palette animations only, not really important. */
 VARDEF int _palette_animation_counter;
 
--- a/src/vehicle.cpp
+++ b/src/vehicle.cpp
@@ -15,7 +15,7 @@
 #include "gfx_func.h"
 #include "news_func.h"
 #include "command_func.h"
-#include "saveload.h"
+#include "saveload/saveload.h"
 #include "company_func.h"
 #include "debug.h"
 #include "vehicle_gui.h"
@@ -59,9 +59,6 @@
 #include "table/sprites.h"
 #include "table/strings.h"
 
-#include <map>
-
-#define INVALID_COORD (0x7fffffff)
 #define GEN_HASH(x, y) ((GB((y), 6, 6) << 6) + GB((x), 7, 6))
 
 VehicleID _vehicle_id_ctr_day;
@@ -222,120 +219,6 @@
 	v->bottom_coord = pt.y + spr->height + 2;
 }
 
-/** Called after load to update coordinates */
-void AfterLoadVehicles(bool part_of_load)
-{
-	Vehicle *v;
-
-	FOR_ALL_VEHICLES(v) {
-		/* Reinstate the previous pointer */
-		if (v->Next() != NULL) v->Next()->previous = v;
-		if (v->NextShared() != NULL) v->NextShared()->previous_shared = v;
-
-		v->UpdateDeltaXY(v->direction);
-
-		if (part_of_load) v->fill_percent_te_id = INVALID_TE_ID;
-		v->first = NULL;
-		if (v->type == VEH_TRAIN) v->u.rail.first_engine = INVALID_ENGINE;
-		if (v->type == VEH_ROAD)  v->u.road.first_engine = INVALID_ENGINE;
-
-		v->cargo.InvalidateCache();
-	}
-
-	/* AfterLoadVehicles may also be called in case of NewGRF reload, in this
-	 * case we may not convert orders again. */
-	if (part_of_load) {
-		/* Create shared vehicle chain for very old games (pre 5,2) and create
-		 * OrderList from shared vehicle chains. For this to work correctly, the
-		 * following conditions must be fulfilled:
-		 * a) both next_shared and previous_shared are not set for pre 5,2 games
-		 * b) both next_shared and previous_shared are set for later games
-		 */
-		std::map<Order*, OrderList*> mapping;
-
-		FOR_ALL_VEHICLES(v) {
-			if (v->orders.old != NULL) {
-				if (CheckSavegameVersion(105)) { // Pre-105 didn't save an OrderList
-					if (mapping[v->orders.old] == NULL) {
-						/* This adds the whole shared vehicle chain for case b */
-						v->orders.list = mapping[v->orders.old] = new OrderList(v->orders.old, v);
-					} else {
-						v->orders.list = mapping[v->orders.old];
-						/* For old games (case a) we must create the shared vehicle chain */
-						if (CheckSavegameVersionOldStyle(5, 2)) {
-							v->AddToShared(v->orders.list->GetFirstSharedVehicle());
-						}
-					}
-				} else { // OrderList was saved as such, only recalculate not saved values
-					if (v->PreviousShared() == NULL) {
-						new (v->orders.list) OrderList(v->orders.list->GetFirstOrder(), v);
-					}
-				}
-			}
-		}
-	}
-
-	FOR_ALL_VEHICLES(v) {
-		/* Fill the first pointers */
-		if (v->Previous() == NULL) {
-			for (Vehicle *u = v; u != NULL; u = u->Next()) {
-				u->first = v;
-			}
-		}
-	}
-
-	FOR_ALL_VEHICLES(v) {
-		assert(v->first != NULL);
-
-		if (v->type == VEH_TRAIN && (IsFrontEngine(v) || IsFreeWagon(v))) {
-			if (IsFrontEngine(v)) v->u.rail.last_speed = v->cur_speed; // update displayed train speed
-			TrainConsistChanged(v, false);
-		} else if (v->type == VEH_ROAD && IsRoadVehFront(v)) {
-			RoadVehUpdateCache(v);
-		}
-	}
-
-	/* Stop non-front engines */
-	FOR_ALL_VEHICLES(v) {
-		if (v->type == VEH_TRAIN && IsTrainEngine(v) && !IsFrontEngine(v)) v->vehstatus |= VS_STOPPED;
-	}
-
-	FOR_ALL_VEHICLES(v) {
-		switch (v->type) {
-			case VEH_ROAD:
-				v->u.road.roadtype = HasBit(EngInfo(v->engine_type)->misc_flags, EF_ROAD_TRAM) ? ROADTYPE_TRAM : ROADTYPE_ROAD;
-				v->u.road.compatible_roadtypes = RoadTypeToRoadTypes(v->u.road.roadtype);
-				/* FALL THROUGH */
-			case VEH_TRAIN:
-			case VEH_SHIP:
-				v->cur_image = v->GetImage(v->direction);
-				break;
-
-			case VEH_AIRCRAFT:
-				if (IsNormalAircraft(v)) {
-					v->cur_image = v->GetImage(v->direction);
-
-					/* The plane's shadow will have the same image as the plane */
-					Vehicle *shadow = v->Next();
-					shadow->cur_image = v->cur_image;
-
-					/* In the case of a helicopter we will update the rotor sprites */
-					if (v->subtype == AIR_HELICOPTER) {
-						Vehicle *rotor = shadow->Next();
-						rotor->cur_image = GetRotorImage(v);
-					}
-
-					UpdateAircraftCache(v);
-				}
-				break;
-			default: break;
-		}
-
-		v->left_coord = INVALID_COORD;
-		VehiclePositionChanged(v);
-	}
-}
-
 Vehicle::Vehicle()
 {
 	this->type               = VEH_INVALID;
@@ -622,11 +505,19 @@
 	FOR_ALL_VEHICLES(v) { v->colormap = PAL_NONE; }
 }
 
+/**
+ * List of vehicles that should check for autoreplace this tick.
+ * Mapping of vehicle -> leave depot immediatelly after autoreplace.
+ */
+typedef SmallMap<Vehicle *, bool, 4> AutoreplaceMap;
+static AutoreplaceMap _vehicles_to_autoreplace;
+
 void InitializeVehicles()
 {
 	_Vehicle_pool.CleanPool();
 	_Vehicle_pool.AddBlockToPool();
 
+	_vehicles_to_autoreplace.Reset();
 	ResetVehiclePosHash();
 }
 
@@ -739,13 +630,6 @@
 	new (this) InvalidVehicle();
 }
 
-/**
- * List of vehicles that should check for autoreplace this tick.
- * Mapping of vehicle -> leave depot immediatelly after autoreplace.
- */
-typedef SmallMap<Vehicle *, bool, 4> AutoreplaceMap;
-static AutoreplaceMap _vehicles_to_autoreplace;
-
 /** Adds a vehicle to the list of vehicles, that visited a depot this tick
  * @param *v vehicle to add
  */
@@ -2128,367 +2012,6 @@
 	return GetEngineColourMap(v->engine_type, v->owner, INVALID_ENGINE, v);
 }
 
-static uint8  _cargo_days;
-static uint16 _cargo_source;
-static uint32 _cargo_source_xy;
-static uint16 _cargo_count;
-static uint16 _cargo_paid_for;
-static Money  _cargo_feeder_share;
-static uint32 _cargo_loaded_at_xy;
-
-/**
- * Make it possible to make the saveload tables "friends" of other classes.
- * @param vt the vehicle type. Can be VEH_END for the common vehicle description data
- * @return the saveload description
- */
-const SaveLoad *GetVehicleDescription(VehicleType vt)
-{
-/** Save and load of vehicles */
-static const SaveLoad _common_veh_desc[] = {
-	    SLE_VAR(Vehicle, subtype,              SLE_UINT8),
-
-	    SLE_REF(Vehicle, next,                 REF_VEHICLE_OLD),
-	SLE_CONDVAR(Vehicle, name,                 SLE_NAME,                    0, 83),
-	SLE_CONDSTR(Vehicle, name,                 SLE_STR, 0,                 84, SL_MAX_VERSION),
-	SLE_CONDVAR(Vehicle, unitnumber,           SLE_FILE_U8  | SLE_VAR_U16,  0, 7),
-	SLE_CONDVAR(Vehicle, unitnumber,           SLE_UINT16,                  8, SL_MAX_VERSION),
-	    SLE_VAR(Vehicle, owner,                SLE_UINT8),
-	SLE_CONDVAR(Vehicle, tile,                 SLE_FILE_U16 | SLE_VAR_U32,  0, 5),
-	SLE_CONDVAR(Vehicle, tile,                 SLE_UINT32,                  6, SL_MAX_VERSION),
-	SLE_CONDVAR(Vehicle, dest_tile,            SLE_FILE_U16 | SLE_VAR_U32,  0, 5),
-	SLE_CONDVAR(Vehicle, dest_tile,            SLE_UINT32,                  6, SL_MAX_VERSION),
-
-	SLE_CONDVAR(Vehicle, x_pos,                SLE_FILE_U16 | SLE_VAR_U32,  0, 5),
-	SLE_CONDVAR(Vehicle, x_pos,                SLE_UINT32,                  6, SL_MAX_VERSION),
-	SLE_CONDVAR(Vehicle, y_pos,                SLE_FILE_U16 | SLE_VAR_U32,  0, 5),
-	SLE_CONDVAR(Vehicle, y_pos,                SLE_UINT32,                  6, SL_MAX_VERSION),
-	    SLE_VAR(Vehicle, z_pos,                SLE_UINT8),
-	    SLE_VAR(Vehicle, direction,            SLE_UINT8),
-
-	SLE_CONDNULL(2,                                                         0, 57),
-	    SLE_VAR(Vehicle, spritenum,            SLE_UINT8),
-	SLE_CONDNULL(5,                                                         0, 57),
-	    SLE_VAR(Vehicle, engine_type,          SLE_UINT16),
-
-	    SLE_VAR(Vehicle, max_speed,            SLE_UINT16),
-	    SLE_VAR(Vehicle, cur_speed,            SLE_UINT16),
-	    SLE_VAR(Vehicle, subspeed,             SLE_UINT8),
-	    SLE_VAR(Vehicle, acceleration,         SLE_UINT8),
-	    SLE_VAR(Vehicle, progress,             SLE_UINT8),
-
-	    SLE_VAR(Vehicle, vehstatus,            SLE_UINT8),
-	SLE_CONDVAR(Vehicle, last_station_visited, SLE_FILE_U8  | SLE_VAR_U16,  0, 4),
-	SLE_CONDVAR(Vehicle, last_station_visited, SLE_UINT16,                  5, SL_MAX_VERSION),
-
-	     SLE_VAR(Vehicle, cargo_type,           SLE_UINT8),
-	 SLE_CONDVAR(Vehicle, cargo_subtype,        SLE_UINT8,                  35, SL_MAX_VERSION),
-	SLEG_CONDVAR(         _cargo_days,          SLE_UINT8,                   0, 67),
-	SLEG_CONDVAR(         _cargo_source,        SLE_FILE_U8  | SLE_VAR_U16,  0, 6),
-	SLEG_CONDVAR(         _cargo_source,        SLE_UINT16,                  7, 67),
-	SLEG_CONDVAR(         _cargo_source_xy,     SLE_UINT32,                 44, 67),
-	     SLE_VAR(Vehicle, cargo_cap,            SLE_UINT16),
-	SLEG_CONDVAR(         _cargo_count,         SLE_UINT16,                  0, 67),
-	 SLE_CONDLST(Vehicle, cargo,                REF_CARGO_PACKET,           68, SL_MAX_VERSION),
-
-	    SLE_VAR(Vehicle, day_counter,          SLE_UINT8),
-	    SLE_VAR(Vehicle, tick_counter,         SLE_UINT8),
-	SLE_CONDVAR(Vehicle, running_ticks,        SLE_UINT8,                   88, SL_MAX_VERSION),
-
-	    SLE_VAR(Vehicle, cur_order_index,      SLE_UINT8),
-	/* num_orders is now part of OrderList and is not saved but counted */
-	SLE_CONDNULL(1,                                                          0, 104),
-
-	/* This next line is for version 4 and prior compatibility.. it temporarily reads
-	    type and flags (which were both 4 bits) into type. Later on this is
-	    converted correctly */
-	SLE_CONDVARX(cpp_offsetof(Vehicle, current_order) + cpp_offsetof(Order, type), SLE_UINT8,                 0, 4),
-	SLE_CONDVARX(cpp_offsetof(Vehicle, current_order) + cpp_offsetof(Order, dest), SLE_FILE_U8 | SLE_VAR_U16, 0, 4),
-
-	/* Orders for version 5 and on */
-	SLE_CONDVARX(cpp_offsetof(Vehicle, current_order) + cpp_offsetof(Order, type),  SLE_UINT8,  5, SL_MAX_VERSION),
-	SLE_CONDVARX(cpp_offsetof(Vehicle, current_order) + cpp_offsetof(Order, flags), SLE_UINT8,  5, SL_MAX_VERSION),
-	SLE_CONDVARX(cpp_offsetof(Vehicle, current_order) + cpp_offsetof(Order, dest),  SLE_UINT16, 5, SL_MAX_VERSION),
-
-	/* Refit in current order */
-	SLE_CONDVARX(cpp_offsetof(Vehicle, current_order) + cpp_offsetof(Order, refit_cargo),    SLE_UINT8, 36, SL_MAX_VERSION),
-	SLE_CONDVARX(cpp_offsetof(Vehicle, current_order) + cpp_offsetof(Order, refit_subtype),  SLE_UINT8, 36, SL_MAX_VERSION),
-
-	/* Timetable in current order */
-	SLE_CONDVARX(cpp_offsetof(Vehicle, current_order) + cpp_offsetof(Order, wait_time),      SLE_UINT16, 67, SL_MAX_VERSION),
-	SLE_CONDVARX(cpp_offsetof(Vehicle, current_order) + cpp_offsetof(Order, travel_time),    SLE_UINT16, 67, SL_MAX_VERSION),
-
-	SLE_CONDREF(Vehicle, orders,               REF_ORDER,                   0, 104),
-	SLE_CONDREF(Vehicle, orders,               REF_ORDERLIST,             105, SL_MAX_VERSION),
-
-	SLE_CONDVAR(Vehicle, age,                  SLE_FILE_U16 | SLE_VAR_I32,  0, 30),
-	SLE_CONDVAR(Vehicle, age,                  SLE_INT32,                  31, SL_MAX_VERSION),
-	SLE_CONDVAR(Vehicle, max_age,              SLE_FILE_U16 | SLE_VAR_I32,  0, 30),
-	SLE_CONDVAR(Vehicle, max_age,              SLE_INT32,                  31, SL_MAX_VERSION),
-	SLE_CONDVAR(Vehicle, date_of_last_service, SLE_FILE_U16 | SLE_VAR_I32,  0, 30),
-	SLE_CONDVAR(Vehicle, date_of_last_service, SLE_INT32,                  31, SL_MAX_VERSION),
-	SLE_CONDVAR(Vehicle, service_interval,     SLE_FILE_U16 | SLE_VAR_I32,  0, 30),
-	SLE_CONDVAR(Vehicle, service_interval,     SLE_INT32,                  31, SL_MAX_VERSION),
-	    SLE_VAR(Vehicle, reliability,          SLE_UINT16),
-	    SLE_VAR(Vehicle, reliability_spd_dec,  SLE_UINT16),
-	    SLE_VAR(Vehicle, breakdown_ctr,        SLE_UINT8),
-	    SLE_VAR(Vehicle, breakdown_delay,      SLE_UINT8),
-	    SLE_VAR(Vehicle, breakdowns_since_last_service, SLE_UINT8),
-	    SLE_VAR(Vehicle, breakdown_chance,     SLE_UINT8),
-	SLE_CONDVAR(Vehicle, build_year,           SLE_FILE_U8 | SLE_VAR_I32,  0, 30),
-	SLE_CONDVAR(Vehicle, build_year,           SLE_INT32,                 31, SL_MAX_VERSION),
-
-	     SLE_VAR(Vehicle, load_unload_time_rem, SLE_UINT16),
-	SLEG_CONDVAR(         _cargo_paid_for,      SLE_UINT16,                45, SL_MAX_VERSION),
-	 SLE_CONDVAR(Vehicle, vehicle_flags,        SLE_UINT8,                 40, SL_MAX_VERSION),
-
-	 SLE_CONDVAR(Vehicle, profit_this_year,     SLE_FILE_I32 | SLE_VAR_I64, 0, 64),
-	 SLE_CONDVAR(Vehicle, profit_this_year,     SLE_INT64,                 65, SL_MAX_VERSION),
-	 SLE_CONDVAR(Vehicle, profit_last_year,     SLE_FILE_I32 | SLE_VAR_I64, 0, 64),
-	 SLE_CONDVAR(Vehicle, profit_last_year,     SLE_INT64,                 65, SL_MAX_VERSION),
-	SLEG_CONDVAR(         _cargo_feeder_share,  SLE_FILE_I32 | SLE_VAR_I64,51, 64),
-	SLEG_CONDVAR(         _cargo_feeder_share,  SLE_INT64,                 65, 67),
-	SLEG_CONDVAR(         _cargo_loaded_at_xy,  SLE_UINT32,                51, 67),
-	 SLE_CONDVAR(Vehicle, value,                SLE_FILE_I32 | SLE_VAR_I64, 0, 64),
-	 SLE_CONDVAR(Vehicle, value,                SLE_INT64,                 65, SL_MAX_VERSION),
-
-	 SLE_CONDVAR(Vehicle, random_bits,          SLE_UINT8,                 2, SL_MAX_VERSION),
-	 SLE_CONDVAR(Vehicle, waiting_triggers,     SLE_UINT8,                 2, SL_MAX_VERSION),
-
-	 SLE_CONDREF(Vehicle, next_shared,        REF_VEHICLE,                 2, SL_MAX_VERSION),
-	SLE_CONDNULL(2,                                                        2, 68),
-	SLE_CONDNULL(4,                                                       69, 100),
-
-	SLE_CONDVAR(Vehicle, group_id,             SLE_UINT16,                60, SL_MAX_VERSION),
-
-	SLE_CONDVAR(Vehicle, current_order_time,   SLE_UINT32,                67, SL_MAX_VERSION),
-	SLE_CONDVAR(Vehicle, lateness_counter,     SLE_INT32,                 67, SL_MAX_VERSION),
-
-	/* reserve extra space in savegame here. (currently 10 bytes) */
-	SLE_CONDNULL(10,                                                       2, SL_MAX_VERSION),
-
-	SLE_END()
-};
-
-
-static const SaveLoad _train_desc[] = {
-	SLE_WRITEBYTE(Vehicle, type, VEH_TRAIN),
-	SLE_VEH_INCLUDEX(),
-	    SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRail, crash_anim_pos),         SLE_UINT16),
-	    SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRail, force_proceed),          SLE_UINT8),
-	    SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRail, railtype),               SLE_UINT8),
-	    SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRail, track),                  SLE_UINT8),
-
-	SLE_CONDVARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRail, flags), SLE_FILE_U8  | SLE_VAR_U16,  2, 99),
-	SLE_CONDVARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRail, flags),                 SLE_UINT16,100, SL_MAX_VERSION),
-	SLE_CONDNULL(2, 2, 59),
-
-	SLE_CONDNULL(2, 2, 19),
-	/* reserve extra space in savegame here. (currently 11 bytes) */
-	SLE_CONDNULL(11, 2, SL_MAX_VERSION),
-
-	SLE_END()
-};
-
-static const SaveLoad _roadveh_desc[] = {
-	SLE_WRITEBYTE(Vehicle, type, VEH_ROAD),
-	SLE_VEH_INCLUDEX(),
-	    SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRoad, state),          SLE_UINT8),
-	    SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRoad, frame),          SLE_UINT8),
-	    SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRoad, blocked_ctr),    SLE_UINT16),
-	    SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRoad, overtaking),     SLE_UINT8),
-	    SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRoad, overtaking_ctr), SLE_UINT8),
-	    SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRoad, crashed_ctr),    SLE_UINT16),
-	    SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRoad, reverse_ctr),    SLE_UINT8),
-
-	SLE_CONDREFX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRoad, slot),     REF_ROADSTOPS, 6, SL_MAX_VERSION),
-	SLE_CONDNULL(1,                                                                     6, SL_MAX_VERSION),
-	SLE_CONDVARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRoad, slot_age), SLE_UINT8,     6, SL_MAX_VERSION),
-	/* reserve extra space in savegame here. (currently 16 bytes) */
-	SLE_CONDNULL(16,                                                                    2, SL_MAX_VERSION),
-
-	SLE_END()
-};
-
-static const SaveLoad _ship_desc[] = {
-	SLE_WRITEBYTE(Vehicle, type, VEH_SHIP),
-	SLE_VEH_INCLUDEX(),
-	SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleShip, state), SLE_UINT8),
-
-	/* reserve extra space in savegame here. (currently 16 bytes) */
-	SLE_CONDNULL(16, 2, SL_MAX_VERSION),
-
-	SLE_END()
-};
-
-static const SaveLoad _aircraft_desc[] = {
-	SLE_WRITEBYTE(Vehicle, type, VEH_AIRCRAFT),
-	SLE_VEH_INCLUDEX(),
-	    SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleAir, crashed_counter), SLE_UINT16),
-	    SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleAir, pos),             SLE_UINT8),
-
-	SLE_CONDVARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleAir, targetairport),   SLE_FILE_U8 | SLE_VAR_U16, 0, 4),
-	SLE_CONDVARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleAir, targetairport),   SLE_UINT16,                5, SL_MAX_VERSION),
-
-	    SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleAir, state),           SLE_UINT8),
-
-	SLE_CONDVARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleAir, previous_pos),    SLE_UINT8,                 2, SL_MAX_VERSION),
-
-	/* reserve extra space in savegame here. (currently 15 bytes) */
-	SLE_CONDNULL(15,                                                                                      2, SL_MAX_VERSION),
-
-	SLE_END()
-};
-
-static const SaveLoad _special_desc[] = {
-	SLE_WRITEBYTE(Vehicle, type, VEH_EFFECT),
-
-	    SLE_VAR(Vehicle, subtype,       SLE_UINT8),
-
-	SLE_CONDVAR(Vehicle, tile,          SLE_FILE_U16 | SLE_VAR_U32, 0, 5),
-	SLE_CONDVAR(Vehicle, tile,          SLE_UINT32,                 6, SL_MAX_VERSION),
-
-	SLE_CONDVAR(Vehicle, x_pos,         SLE_FILE_I16 | SLE_VAR_I32, 0, 5),
-	SLE_CONDVAR(Vehicle, x_pos,         SLE_INT32,                  6, SL_MAX_VERSION),
-	SLE_CONDVAR(Vehicle, y_pos,         SLE_FILE_I16 | SLE_VAR_I32, 0, 5),
-	SLE_CONDVAR(Vehicle, y_pos,         SLE_INT32,                  6, SL_MAX_VERSION),
-	    SLE_VAR(Vehicle, z_pos,         SLE_UINT8),
-
-	    SLE_VAR(Vehicle, cur_image,     SLE_UINT16),
-	SLE_CONDNULL(5,                                                 0, 57),
-	    SLE_VAR(Vehicle, progress,      SLE_UINT8),
-	    SLE_VAR(Vehicle, vehstatus,     SLE_UINT8),
-
-	    SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleEffect, animation_state),    SLE_UINT16),
-	    SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleEffect, animation_substate), SLE_UINT8),
-
-	SLE_CONDVAR(Vehicle, spritenum,     SLE_UINT8, 2, SL_MAX_VERSION),
-
-	/* reserve extra space in savegame here. (currently 15 bytes) */
-	SLE_CONDNULL(15, 2, SL_MAX_VERSION),
-
-	SLE_END()
-};
-
-static const SaveLoad _disaster_desc[] = {
-	SLE_WRITEBYTE(Vehicle, type, VEH_DISASTER),
-
-	    SLE_REF(Vehicle, next,          REF_VEHICLE_OLD),
-
-	    SLE_VAR(Vehicle, subtype,       SLE_UINT8),
-	SLE_CONDVAR(Vehicle, tile,          SLE_FILE_U16 | SLE_VAR_U32,  0, 5),
-	SLE_CONDVAR(Vehicle, tile,          SLE_UINT32,                  6, SL_MAX_VERSION),
-	SLE_CONDVAR(Vehicle, dest_tile,     SLE_FILE_U16 | SLE_VAR_U32,  0, 5),
-	SLE_CONDVAR(Vehicle, dest_tile,     SLE_UINT32,                  6, SL_MAX_VERSION),
-
-	SLE_CONDVAR(Vehicle, x_pos,         SLE_FILE_I16 | SLE_VAR_I32,  0, 5),
-	SLE_CONDVAR(Vehicle, x_pos,         SLE_INT32,                   6, SL_MAX_VERSION),
-	SLE_CONDVAR(Vehicle, y_pos,         SLE_FILE_I16 | SLE_VAR_I32,  0, 5),
-	SLE_CONDVAR(Vehicle, y_pos,         SLE_INT32,                   6, SL_MAX_VERSION),
-	    SLE_VAR(Vehicle, z_pos,         SLE_UINT8),
-	    SLE_VAR(Vehicle, direction,     SLE_UINT8),
-
-	SLE_CONDNULL(5,                                                  0, 57),
-	    SLE_VAR(Vehicle, owner,         SLE_UINT8),
-	    SLE_VAR(Vehicle, vehstatus,     SLE_UINT8),
-	SLE_CONDVARX(cpp_offsetof(Vehicle, current_order) + cpp_offsetof(Order, dest), SLE_FILE_U8 | SLE_VAR_U16, 0, 4),
-	SLE_CONDVARX(cpp_offsetof(Vehicle, current_order) + cpp_offsetof(Order, dest), SLE_UINT16,                5, SL_MAX_VERSION),
-
-	    SLE_VAR(Vehicle, cur_image,     SLE_UINT16),
-	SLE_CONDVAR(Vehicle, age,           SLE_FILE_U16 | SLE_VAR_I32,  0, 30),
-	SLE_CONDVAR(Vehicle, age,           SLE_INT32,                  31, SL_MAX_VERSION),
-	    SLE_VAR(Vehicle, tick_counter,  SLE_UINT8),
-
-	   SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleDisaster, image_override),           SLE_UINT16),
-	   SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleDisaster, big_ufo_destroyer_target), SLE_UINT16),
-
-	/* reserve extra space in savegame here. (currently 16 bytes) */
-	SLE_CONDNULL(16,                                                 2, SL_MAX_VERSION),
-
-	SLE_END()
-};
-
-
-static const SaveLoad *_veh_descs[] = {
-	_train_desc,
-	_roadveh_desc,
-	_ship_desc,
-	_aircraft_desc,
-	_special_desc,
-	_disaster_desc,
-	_common_veh_desc,
-};
-
-	return _veh_descs[vt];
-}
-
-/** Will be called when the vehicles need to be saved. */
-static void Save_VEHS()
-{
-	Vehicle *v;
-	/* Write the vehicles */
-	FOR_ALL_VEHICLES(v) {
-		SlSetArrayIndex(v->index);
-		SlObject(v, GetVehicleDescription(v->type));
-	}
-}
-
-/** Will be called when vehicles need to be loaded. */
-void Load_VEHS()
-{
-	_vehicles_to_autoreplace.Reset();
-
-	int index;
-
-	_cargo_count = 0;
-
-	while ((index = SlIterateArray()) != -1) {
-		Vehicle *v;
-		VehicleType vtype = (VehicleType)SlReadByte();
-
-		switch (vtype) {
-			case VEH_TRAIN:    v = new (index) Train();           break;
-			case VEH_ROAD:     v = new (index) RoadVehicle();     break;
-			case VEH_SHIP:     v = new (index) Ship();            break;
-			case VEH_AIRCRAFT: v = new (index) Aircraft();        break;
-			case VEH_EFFECT:   v = new (index) EffectVehicle();   break;
-			case VEH_DISASTER: v = new (index) DisasterVehicle(); break;
-			case VEH_INVALID:  v = new (index) InvalidVehicle();  break;
-			default: NOT_REACHED();
-		}
-
-		SlObject(v, GetVehicleDescription(vtype));
-
-		if (_cargo_count != 0 && IsCompanyBuildableVehicleType(v)) {
-			/* Don't construct the packet with station here, because that'll fail with old savegames */
-			CargoPacket *cp = new CargoPacket();
-			cp->source          = _cargo_source;
-			cp->source_xy       = _cargo_source_xy;
-			cp->count           = _cargo_count;
-			cp->days_in_transit = _cargo_days;
-			cp->feeder_share    = _cargo_feeder_share;
-			cp->loaded_at_xy    = _cargo_loaded_at_xy;
-			v->cargo.Append(cp);
-		}
-
-		/* Old savegames used 'last_station_visited = 0xFF' */
-		if (CheckSavegameVersion(5) && v->last_station_visited == 0xFF)
-			v->last_station_visited = INVALID_STATION;
-
-		if (CheckSavegameVersion(5)) {
-			/* Convert the current_order.type (which is a mix of type and flags, because
-			 *  in those versions, they both were 4 bits big) to type and flags */
-			v->current_order.flags = GB(v->current_order.type, 4, 4);
-			v->current_order.type &= 0x0F;
-		}
-
-		/* Advanced vehicle lists got added */
-		if (CheckSavegameVersion(60)) v->group_id = DEFAULT_GROUP;
-	}
-}
-
-extern const ChunkHandler _veh_chunk_handlers[] = {
-	{ 'VEHS', Save_VEHS, Load_VEHS, CH_SPARSE_ARRAY | CH_LAST},
-};
 
 void Vehicle::BeginLoading()
 {
--- a/src/vehicle_base.h
+++ b/src/vehicle_base.h
@@ -194,7 +194,6 @@
 /* Some declarations of functions, so we can make them friendly */
 struct SaveLoad;
 extern const SaveLoad *GetVehicleDescription(VehicleType vt);
-extern void AfterLoadVehicles(bool part_of_load);
 struct LoadgameState;
 extern bool LoadOldVehicle(LoadgameState *ls, int num);
 
@@ -712,4 +711,6 @@
 
 void CheckVehicle32Day(Vehicle *v);
 
+static const int32 INVALID_COORD = 0x7fffffff;
+
 #endif /* VEHICLE_BASE_H */
--- a/src/viewport.cpp
+++ b/src/viewport.cpp
@@ -2785,33 +2785,3 @@
 {
 	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.h
+++ b/src/water.h
@@ -15,6 +15,5 @@
 void DrawShoreTile(Slope tileh);
 
 void MakeWaterKeepingClass(TileIndex tile, Owner o);
-void SetWaterClassDependingOnSurroundings(TileIndex t, bool include_invalid_water_class);
 
 #endif /* WATER_H */
--- a/src/water_cmd.cpp
+++ b/src/water_cmd.cpp
@@ -101,88 +101,6 @@
 	}
 }
 
-/**
- * Makes a tile canal or water depending on the surroundings.
- *
- * Must only be used for converting old savegames. Use WaterClass now.
- *
- * This as for example docks and shipdepots do not store
- * whether the tile used to be canal or 'normal' water.
- * @param t the tile to change.
- * @param o the owner of the new tile.
- * @param include_invalid_water_class Also consider WATER_CLASS_INVALID, i.e. industry tiles on land
- */
-void SetWaterClassDependingOnSurroundings(TileIndex t, bool include_invalid_water_class)
-{
-	/* If the slope is not flat, we always assume 'land' (if allowed). Also for one-corner-raised-shores.
-	 * Note: Wrt. autosloping under industry tiles this is the most fool-proof behaviour. */
-	if (GetTileSlope(t, NULL) != SLOPE_FLAT) {
-		if (include_invalid_water_class) {
-			SetWaterClass(t, WATER_CLASS_INVALID);
-			return;
-		} else {
-			NOT_REACHED();
-		}
-	}
-
-	/* Mark tile dirty in all cases */
-	MarkTileDirtyByTile(t);
-
-	if (TileX(t) == 0 || TileY(t) == 0 || TileX(t) == MapMaxX() - 1 || TileY(t) == MapMaxY() - 1) {
-		/* tiles at map borders are always WATER_CLASS_SEA */
-		SetWaterClass(t, WATER_CLASS_SEA);
-		return;
-	}
-
-	bool has_water = false;
-	bool has_canal = false;
-	bool has_river = false;
-
-	for (DiagDirection dir = DIAGDIR_BEGIN; dir < DIAGDIR_END; dir++) {
-		TileIndex neighbour = TileAddByDiagDir(t, dir);
-		switch (GetTileType(neighbour)) {
-			case MP_WATER:
-				/* clear water and shipdepots have already a WaterClass associated */
-				if (IsCoast(neighbour)) {
-					has_water = true;
-				} else if (!IsLock(neighbour)) {
-					switch (GetWaterClass(neighbour)) {
-						case WATER_CLASS_SEA:   has_water = true; break;
-						case WATER_CLASS_CANAL: has_canal = true; break;
-						case WATER_CLASS_RIVER: has_river = true; break;
-						default: NOT_REACHED();
-					}
-				}
-				break;
-
-			case MP_RAILWAY:
-				/* Shore or flooded halftile */
-				has_water |= (GetRailGroundType(neighbour) == RAIL_GROUND_WATER);
-				break;
-
-			case MP_TREES:
-				/* trees on shore */
-				has_water |= (GetTreeGround(neighbour) == TREE_GROUND_SHORE);
-				break;
-
-			default: break;
-		}
-	}
-
-	if (!has_water && !has_canal && !has_river && include_invalid_water_class) {
-		SetWaterClass(t, WATER_CLASS_INVALID);
-		return;
-	}
-
-	if (has_river && !has_canal) {
-		SetWaterClass(t, WATER_CLASS_RIVER);
-	} else if (has_canal || !has_water) {
-		SetWaterClass(t, WATER_CLASS_CANAL);
-	} else {
-		SetWaterClass(t, WATER_CLASS_SEA);
-	}
-}
-
 
 /** Build a ship depot.
  * @param tile tile where ship depot is built
--- a/src/waypoint.cpp
+++ b/src/waypoint.cpp
@@ -11,7 +11,6 @@
 #include "rail_map.h"
 #include "rail.h"
 #include "bridge_map.h"
-#include "saveload.h"
 #include "station_base.h"
 #include "town.h"
 #include "waypoint.h"
@@ -157,29 +156,6 @@
 	return best;
 }
 
-/**
- * Update waypoint graphics id against saved GRFID/localidx.
- * This is to ensure the chosen graphics are correct if GRF files are changed.
- */
-void AfterLoadWaypoints()
-{
-	Waypoint *wp;
-
-	FOR_ALL_WAYPOINTS(wp) {
-		uint i;
-
-		if (wp->grfid == 0) continue;
-
-		for (i = 0; i < GetNumCustomStations(STAT_CLASS_WAYP); i++) {
-			const StationSpec *statspec = GetCustomStationSpec(STAT_CLASS_WAYP, i);
-			if (statspec != NULL && statspec->grffile->grfid == wp->grfid && statspec->localidx == wp->localidx) {
-				wp->stat_id = i;
-				break;
-			}
-		}
-	}
-}
-
 /** Convert existing rail to waypoint. Eg build a waypoint station over
  * piece of rail
  * @param tile tile where waypoint will be built
@@ -463,69 +439,8 @@
 	this->xy = INVALID_TILE;
 }
 
-/**
- * Fix savegames which stored waypoints in their old format
- */
-void FixOldWaypoints()
-{
-	Waypoint *wp;
-
-	/* Convert the old 'town_or_string', to 'string' / 'town' / 'town_cn' */
-	FOR_ALL_WAYPOINTS(wp) {
-		wp->town_index = ClosestTownFromTile(wp->xy, UINT_MAX)->index;
-		wp->town_cn = 0;
-		if (wp->string & 0xC000) {
-			wp->town_cn = wp->string & 0x3F;
-			wp->string = STR_NULL;
-		}
-	}
-}
-
 void InitializeWaypoints()
 {
 	_Waypoint_pool.CleanPool();
 	_Waypoint_pool.AddBlockToPool();
 }
-
-static const SaveLoad _waypoint_desc[] = {
-	SLE_CONDVAR(Waypoint, xy,         SLE_FILE_U16 | SLE_VAR_U32,  0, 5),
-	SLE_CONDVAR(Waypoint, xy,         SLE_UINT32,                  6, SL_MAX_VERSION),
-	SLE_CONDVAR(Waypoint, town_index, SLE_UINT16,                 12, SL_MAX_VERSION),
-	SLE_CONDVAR(Waypoint, town_cn,    SLE_FILE_U8 | SLE_VAR_U16,  12, 88),
-	SLE_CONDVAR(Waypoint, town_cn,    SLE_UINT16,                 89, SL_MAX_VERSION),
-	SLE_CONDVAR(Waypoint, string,     SLE_STRINGID,                0, 83),
-	SLE_CONDSTR(Waypoint, name,       SLE_STR, 0,                 84, SL_MAX_VERSION),
-	    SLE_VAR(Waypoint, deleted,    SLE_UINT8),
-
-	SLE_CONDVAR(Waypoint, build_date, SLE_FILE_U16 | SLE_VAR_I32,  3, 30),
-	SLE_CONDVAR(Waypoint, build_date, SLE_INT32,                  31, SL_MAX_VERSION),
-	SLE_CONDVAR(Waypoint, localidx,   SLE_UINT8,                   3, SL_MAX_VERSION),
-	SLE_CONDVAR(Waypoint, grfid,      SLE_UINT32,                 17, SL_MAX_VERSION),
-	SLE_CONDVAR(Waypoint, owner,      SLE_UINT8,                 101, SL_MAX_VERSION),
-
-	SLE_END()
-};
-
-static void Save_WAYP()
-{
-	Waypoint *wp;
-
-	FOR_ALL_WAYPOINTS(wp) {
-		SlSetArrayIndex(wp->index);
-		SlObject(wp, _waypoint_desc);
-	}
-}
-
-static void Load_WAYP()
-{
-	int index;
-
-	while ((index = SlIterateArray()) != -1) {
-		Waypoint *wp = new (index) Waypoint();
-		SlObject(wp, _waypoint_desc);
-	}
-}
-
-extern const ChunkHandler _waypoint_chunk_handlers[] = {
-	{ 'CHKP', Save_WAYP, Load_WAYP, CH_ARRAY | CH_LAST},
-};
--- a/src/waypoint.h
+++ b/src/waypoint.h
@@ -12,6 +12,7 @@
 #include "station_type.h"
 #include "town_type.h"
 #include "viewport_type.h"
+#include "date_type.h"
 
 DECLARE_OLD_POOL(Waypoint, Waypoint, 3, 8000)
 
@@ -63,8 +64,6 @@
 Station *ComposeWaypointStation(TileIndex tile);
 void ShowWaypointWindow(const Waypoint *wp);
 void DrawWaypointSprite(int x, int y, int stat_id, RailType railtype);
-void FixOldWaypoints();
 void UpdateAllWaypointSigns();
-void AfterLoadWaypoints();
 
 #endif /* WAYPOINT_H */
--- a/src/win32.cpp
+++ b/src/win32.cpp
@@ -5,7 +5,7 @@
 #include "stdafx.h"
 #include "openttd.h"
 #include "debug.h"
-#include "saveload.h"
+#include "saveload/saveload.h"
 #include "gfx_func.h"
 #include "textbuf_gui.h"
 #include "fileio_func.h"