summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsmatz <smatz@openttd.org>2009-01-04 15:32:25 +0000
committersmatz <smatz@openttd.org>2009-01-04 15:32:25 +0000
commit7368c740a646c958797b5dff90d6c5b51236e2a4 (patch)
tree56e0ff1f4048e467cf123e92ca788c3c4bbc0f94
parentc9e8fd307e36b3d35f5bf7d01cffe64b1e75b846 (diff)
downloadopenttd-7368c740a646c958797b5dff90d6c5b51236e2a4.tar.xz
(svn r14828) -Codechange: move most of save/load-specific code to separate files
-rw-r--r--projects/openttd_vs80.vcproj132
-rw-r--r--projects/openttd_vs90.vcproj132
-rw-r--r--source.list34
-rw-r--r--src/ai/default/default.cpp72
-rw-r--r--src/ai/default/default.h1
-rw-r--r--src/ai/trolly/trolly.h1
-rw-r--r--src/aircraft.h5
-rw-r--r--src/aircraft_cmd.cpp45
-rw-r--r--src/animated_tile.cpp46
-rw-r--r--src/autoreplace.cpp41
-rw-r--r--src/cargopacket.cpp38
-rw-r--r--src/cheat.cpp31
-rw-r--r--src/cheat_gui.cpp2
-rw-r--r--src/company_cmd.cpp225
-rw-r--r--src/company_manager_face.h3
-rw-r--r--src/console_cmds.cpp2
-rw-r--r--src/date.cpp2
-rw-r--r--src/depot.cpp34
-rw-r--r--src/economy.cpp85
-rw-r--r--src/economy_func.h1
-rw-r--r--src/effectvehicle.cpp1
-rw-r--r--src/engine.cpp111
-rw-r--r--src/gamelog.cpp232
-rw-r--r--src/gamelog_internal.h82
-rw-r--r--src/genworld.cpp2
-rw-r--r--src/group_cmd.cpp38
-rw-r--r--src/heightmap.cpp2
-rw-r--r--src/industry_cmd.cpp144
-rw-r--r--src/misc.cpp288
-rw-r--r--src/misc_gui.cpp2
-rw-r--r--src/network/network_client.cpp2
-rw-r--r--src/network/network_server.cpp2
-rw-r--r--src/newgrf.h2
-rw-r--r--src/newgrf_config.cpp46
-rw-r--r--src/newgrf_house.cpp47
-rw-r--r--src/newgrf_house.h3
-rw-r--r--src/newgrf_station.h1
-rw-r--r--src/openttd.cpp1566
-rw-r--r--src/order_base.h3
-rw-r--r--src/order_cmd.cpp192
-rw-r--r--src/saveload/afterload.cpp1704
-rw-r--r--src/saveload/ai_sl.cpp79
-rw-r--r--src/saveload/animated_tile_sl.cpp56
-rw-r--r--src/saveload/autoreplace_sl.cpp51
-rw-r--r--src/saveload/cargopacket_sl.cpp45
-rw-r--r--src/saveload/cheat_sl.cpp37
-rw-r--r--src/saveload/company_sl.cpp240
-rw-r--r--src/saveload/depot_sl.cpp39
-rw-r--r--src/saveload/economy_sl.cpp58
-rw-r--r--src/saveload/engine_sl.cpp118
-rw-r--r--src/saveload/gamelog_sl.cpp161
-rw-r--r--src/saveload/group_sl.cpp43
-rw-r--r--src/saveload/industry_sl.cpp155
-rw-r--r--src/saveload/map_sl.cpp249
-rw-r--r--src/saveload/misc_sl.cpp105
-rw-r--r--src/saveload/newgrf_sl.cpp52
-rw-r--r--src/saveload/oldloader.cpp (renamed from src/oldloader.cpp)52
-rw-r--r--src/saveload/order_sl.cpp203
-rw-r--r--src/saveload/saveload.cpp (renamed from src/saveload.cpp)60
-rw-r--r--src/saveload/saveload.h (renamed from src/saveload.h)2
-rw-r--r--src/saveload/saveload_internal.h40
-rw-r--r--src/saveload/signs_sl.cpp49
-rw-r--r--src/saveload/station_sl.cpp227
-rw-r--r--src/saveload/strings_sl.cpp126
-rw-r--r--src/saveload/subsidy_sl.cpp43
-rw-r--r--src/saveload/town_sl.cpp210
-rw-r--r--src/saveload/vehicle_sl.cpp670
-rw-r--r--src/saveload/waypoint_sl.cpp96
-rw-r--r--src/screenshot.cpp2
-rw-r--r--src/settings.cpp1
-rw-r--r--src/settings_internal.h2
-rw-r--r--src/signs.cpp53
-rw-r--r--src/signs_base.h1
-rw-r--r--src/station.cpp1
-rw-r--r--src/station_cmd.cpp216
-rw-r--r--src/station_func.h1
-rw-r--r--src/strings.cpp112
-rw-r--r--src/strings_func.h3
-rw-r--r--src/town.h1
-rw-r--r--src/town_cmd.cpp150
-rw-r--r--src/train.h3
-rw-r--r--src/train_cmd.cpp143
-rw-r--r--src/variables.h4
-rw-r--r--src/vehicle.cpp495
-rw-r--r--src/vehicle_base.h3
-rw-r--r--src/viewport.cpp30
-rw-r--r--src/water.h1
-rw-r--r--src/water_cmd.cpp82
-rw-r--r--src/waypoint.cpp85
-rw-r--r--src/waypoint.h3
-rw-r--r--src/win32.cpp2
91 files changed, 5320 insertions, 4742 deletions
diff --git a/projects/openttd_vs80.vcproj b/projects/openttd_vs80.vcproj
index 5a5d75014..6dc649a8c 100644
--- 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
diff --git a/projects/openttd_vs90.vcproj b/projects/openttd_vs90.vcproj
index 91e051306..898410e4b 100644
--- 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
diff --git a/source.list b/source.list
index 5c153f69f..487d3fe09 100644
--- a/source.list
+++ b/source.list
@@ -50,7 +50,6 @@ network/network_gamelist.cpp
network/network_server.cpp
network/network_udp.cpp
npf.cpp
-oldloader.cpp
oldpool.cpp
openttd.cpp
os_timer.cpp
@@ -66,7 +65,6 @@ queue.cpp
rail.cpp
rev.cpp
road.cpp
-saveload.cpp
screenshot.cpp
#if SDL
sdl.cpp
@@ -193,6 +191,7 @@ fios.h
fontcache.h
functions.h
gamelog.h
+gamelog_internal.h
genworld.h
gfx_func.h
gfx_type.h
@@ -272,7 +271,6 @@ road_gui.h
road_internal.h
road_type.h
roadveh.h
-saveload.h
screenshot.h
sdl.h
sound/sdl_s.h
@@ -452,6 +450,36 @@ tunnelbridge_cmd.cpp
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
diff --git a/src/ai/default/default.cpp b/src/ai/default/default.cpp
index 8cbbafdaa..ab20b5952 100644
--- 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 @@ void AiDoGameLoop(Company *c)
_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);
- }
-}
diff --git a/src/ai/default/default.h b/src/ai/default/default.h
index 69d65a396..843cf0f17 100644
--- 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;
diff --git a/src/ai/trolly/trolly.h b/src/ai/trolly/trolly.h
index a1d8e0cd9..60180694c 100644
--- 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
diff --git a/src/aircraft.h b/src/aircraft.h
index 2a143db91..b5a231e25 100644
--- a/src/aircraft.h
+++ b/src/aircraft.h
@@ -99,6 +99,11 @@ void UpdateAirplanesOnNewStation(const Station *st);
*/
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
diff --git a/src/aircraft_cmd.cpp b/src/aircraft_cmd.cpp
index 5cd7f7bb4..41bc1663f 100644
--- a/src/aircraft_cmd.cpp
+++ b/src/aircraft_cmd.cpp
@@ -82,9 +82,6 @@ static bool AirportFindFreeTerminal(Vehicle *v, const AirportFTAClass *apc);
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 @@ static void HelicopterTickHandler(Vehicle *v)
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 @@ static int UpdateAircraftSpeed(Vehicle *v, uint speed_limit = SPEED_LIMIT_NONE,
* @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 @@ void AircraftNextAirportPos_and_Order(Vehicle *v)
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 @@ Station *GetTargetAirportIfValid(const Vehicle *v)
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
diff --git a/src/animated_tile.cpp b/src/animated_tile.cpp
index a66225ae6..fd3fc12f8 100644
--- 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 @@ TileIndex *_animated_tile_list = NULL;
/** 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 @@ void InitializeAnimatedTiles()
_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},
-};
diff --git a/src/autoreplace.cpp b/src/autoreplace.cpp
index a2da94776..830236019 100644
--- 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 @@ CommandCost RemoveEngineReplacement(EngineRenewList *erl, EngineID engine, Group
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 */
diff --git a/src/cargopacket.cpp b/src/cargopacket.cpp
index 971db12ef..3c043829a 100644
--- 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 @@ bool CargoPacket::SameSource(const CargoPacket *cp) const
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
diff --git a/src/cheat.cpp b/src/cheat.cpp
index 8a7d2e04c..8f18e5bc1 100644
--- 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 @@ void InitializeCheats()
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 @@ bool CheatHasBeenUsed()
return false;
}
-
-
-extern const ChunkHandler _cheat_chunk_handlers[] = {
- { 'CHTS', Save_CHTS, Load_CHTS, CH_RIFF | CH_LAST}
-};
diff --git a/src/cheat_gui.cpp b/src/cheat_gui.cpp
index 19b07e460..1ddb1c662 100644
--- 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"
diff --git a/src/company_cmd.cpp b/src/company_cmd.cpp
index 087e490dc..338abc88b 100644
--- 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 @@ void DrawCompanyIcon(CompanyID c, int x, int y)
}
/**
- * 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 @@ CommandCost CmdCompanyCtrl(TileIndex tile, uint32 flags, uint32 p1, uint32 p2, c
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},
-};
diff --git a/src/company_manager_face.h b/src/company_manager_face.h
index 6f2a96ff9..184f7d87c 100644
--- 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 @@ static inline SpriteID GetCompanyManagerFaceSprite(CompanyManagerFace cmf, Compa
}
void DrawCompanyManagerFace(CompanyManagerFace face, int color, int x, int y);
-CompanyManagerFace ConvertFromOldCompanyManagerFace(uint32 face);
bool IsValidCompanyManagerFace(CompanyManagerFace cmf);
#endif /* COMPANY_MANAGER_FACE_H */
diff --git a/src/console_cmds.cpp b/src/console_cmds.cpp
index 92f6a7934..e98997d66 100644
--- 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"
diff --git a/src/date.cpp b/src/date.cpp
index d20665f86..9d2f8e29f 100644
--- 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)
diff --git a/src/depot.cpp b/src/depot.cpp
index 005f067b1..cf6ec603a 100644
--- 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 @@ void InitializeDepots()
_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},
-};
diff --git a/src/economy.cpp b/src/economy.cpp
index 3c220d329..f8d0205b0 100644
--- 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 @@ void SetPriceBaseMultiplier(uint price, byte factor)
* 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 @@ no_add:;
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 @@ CommandCost CmdBuyCompany(TileIndex tile, uint32 flags, uint32 p1, uint32 p2, co
}
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},
-};
diff --git a/src/economy_func.h b/src/economy_func.h
index e9c569832..8bbb4a7cc 100644
--- a/src/economy_func.h
+++ b/src/economy_func.h
@@ -34,6 +34,7 @@ Pair SetupSubsidyDecodeParam(const Subsidy *s, bool mode);
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);
diff --git a/src/effectvehicle.cpp b/src/effectvehicle.cpp
index 5caae25da..6d97b49c2 100644
--- 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"
diff --git a/src/engine.cpp b/src/engine.cpp
index 564ff33f5..c8a256f10 100644
--- 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 @@ CargoID GetEngineCargoType(EngineID engine)
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 },
-};
diff --git a/src/gamelog.cpp b/src/gamelog.cpp
index b57f7a47a..a9d9d4bd4 100644
--- 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 uint32 _ttdp_version; ///< version of TTDP savegame (if applicable)
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 @@ void GamelogGRFUpdate(const GRFConfig *oldc, const GRFConfig *newc)
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 }
-};
diff --git a/src/gamelog_internal.h b/src/gamelog_internal.h
new file mode 100644
index 000000000..db5affd03
--- /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 */
diff --git a/src/genworld.cpp b/src/genworld.cpp
index 23a978272..ef6c87151 100644
--- 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"
diff --git a/src/group_cmd.cpp b/src/group_cmd.cpp
index 3a80c3d49..44e3b6bb3 100644
--- 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 @@ void RemoveAllGroupsForCompany(const CompanyID company)
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},
-};
diff --git a/src/heightmap.cpp b/src/heightmap.cpp
index 1add9853c..2ca58b14c 100644
--- 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"
diff --git a/src/industry_cmd.cpp b/src/industry_cmd.cpp
index e9e4e68d4..3c9262458 100644
--- 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 @@ extern const TileTypeProcs _tile_type_industry_procs = {
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},
-};
diff --git a/src/misc.cpp b/src/misc.cpp
index 3d51bf2b2..bccaf2c62 100644
--- 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 @@ void InitializeLandscapeVariables(bool only_constants)
_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},
-};
diff --git a/src/misc_gui.cpp b/src/misc_gui.cpp
index bd27e065b..b0dd24d00 100644
--- 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"
diff --git a/src/network/network_client.cpp b/src/network/network_client.cpp
index 145d61dd6..2d7256beb 100644
--- 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"
diff --git a/src/network/network_server.cpp b/src/network/network_server.cpp
index 5f5d5692c..2fc06f4a1 100644
--- 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"
diff --git a/src/newgrf.h b/src/newgrf.h
index 253d8f334..83690e003 100644
--- a/src/newgrf.h
+++ b/src/newgrf.h
@@ -121,7 +121,7 @@ extern GRFLoadedFeatures _loaded_newgrf_features;
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, ...);
diff --git a/src/newgrf_config.cpp b/src/newgrf_config.cpp
index 389aeb408..b579e5e98 100644
--- 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 @@ bool GRFConfig::IsOpenTTDBaseGRF() const
{
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 }
-};
-
-
-
diff --git a/src/newgrf_house.cpp b/src/newgrf_house.cpp
index ce7558f97..c02e0e42b 100644
--- a/src/newgrf_house.cpp
+++ b/src/newgrf_house.cpp
@@ -34,53 +34,6 @@ static HouseClassMapping _class_mapping[HOUSE_CLASS_MAX];
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. */
diff --git a/src/newgrf_house.h b/src/newgrf_house.h
index 9a6f32d01..ce08e1213 100644
--- 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 @@ struct HouseClassMapping {
uint8 class_id; ////< The class id within the grf file
};
-void UpdateHousesAndTowns();
-
HouseClassID AllocateHouseClassID(byte grf_class_id, uint32 grfid);
void InitializeBuildingCounts();
diff --git a/src/newgrf_station.h b/src/newgrf_station.h
index 5d42cde72..13844268b 100644
--- 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
diff --git a/src/openttd.cpp b/src/openttd.cpp
index 613d63151..fd478955d 100644
--- 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 IncreaseDate();
void DoPaletteAnimations();
void MusicLoop();
void ResetMusic();
-void ResetOldNames();
void ProcessAsyncSaveFinish();
void CallWindowTickEvent();
@@ -1182,1566 +1181,3 @@ void GameLoop()
_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();
-}
diff --git a/src/order_base.h b/src/order_base.h
index b7c01282d..44e8d9c15 100644
--- a/src/order_base.h
+++ b/src/order_base.h
@@ -431,7 +431,4 @@ static inline bool IsValidOrderListID(uint index)
#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 */
diff --git a/src/order_cmd.cpp b/src/order_cmd.cpp
index d0678c457..4686a564d 100644
--- 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 @@ Order::Order(uint32 packed)
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 @@ void InitializeOrders()
_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},
-};
diff --git a/src/saveload/afterload.cpp b/src/saveload/afterload.cpp
new file mode 100644
index 000000000..c4ecb664a
--- /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();
+}
diff --git a/src/saveload/ai_sl.cpp b/src/saveload/ai_sl.cpp
new file mode 100644
index 000000000..b4d16a6b5
--- /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);
+ }
+}
diff --git a/src/saveload/animated_tile_sl.cpp b/src/saveload/animated_tile_sl.cpp
new file mode 100644
index 000000000..ba3f519db
--- /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},
+};
diff --git a/src/saveload/autoreplace_sl.cpp b/src/saveload/autoreplace_sl.cpp
new file mode 100644
index 000000000..d24c290a8
--- /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},
+};
diff --git a/src/saveload/cargopacket_sl.cpp b/src/saveload/cargopacket_sl.cpp
new file mode 100644
index 000000000..d38e4e22e
--- /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},
+};
diff --git a/src/saveload/cheat_sl.cpp b/src/saveload/cheat_sl.cpp
new file mode 100644
index 000000000..a8c939fed
--- /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}
+};
diff --git a/src/saveload/company_sl.cpp b/src/saveload/company_sl.cpp
new file mode 100644
index 000000000..933cc0bde
--- /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},
+};
diff --git a/src/saveload/depot_sl.cpp b/src/saveload/depot_sl.cpp
new file mode 100644
index 000000000..fb546ef73
--- /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},
+};
diff --git a/src/saveload/economy_sl.cpp b/src/saveload/economy_sl.cpp
new file mode 100644
index 000000000..99f306f52
--- /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},
+};
diff --git a/src/saveload/engine_sl.cpp b/src/saveload/engine_sl.cpp
new file mode 100644
index 000000000..6dc47c56a
--- /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 },
+};
diff --git a/src/saveload/gamelog_sl.cpp b/src/saveload/gamelog_sl.cpp
new file mode 100644
index 000000000..7364602bb
--- /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 }
+};
diff --git a/src/saveload/group_sl.cpp b/src/saveload/group_sl.cpp
new file mode 100644
index 000000000..66e3585b4
--- /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},
+};
diff --git a/src/saveload/industry_sl.cpp b/src/saveload/industry_sl.cpp
new file mode 100644
index 000000000..2b8aea788
--- /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},
+};
diff --git a/src/saveload/map_sl.cpp b/src/saveload/map_sl.cpp
new file mode 100644
index 000000000..6025f0fca
--- /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 },
+};
diff --git a/src/saveload/misc_sl.cpp b/src/saveload/misc_sl.cpp
new file mode 100644
index 000000000..4b8e8b2c7
--- /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},
+};
diff --git a/src/saveload/newgrf_sl.cpp b/src/saveload/newgrf_sl.cpp
new file mode 100644
index 000000000..5269f235d
--- /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 }
+};
diff --git a/src/oldloader.cpp b/src/saveload/oldloader.cpp
index 2a02f069e..532d58f8c 100644
--- a/src/oldloader.cpp
+++ b/src/saveload/oldloader.cpp
@@ -2,34 +2,36 @@
/** @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 "../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,
diff --git a/src/saveload/order_sl.cpp b/src/saveload/order_sl.cpp
new file mode 100644
index 000000000..ef11056ed
--- /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},
+};
diff --git a/src/saveload.cpp b/src/saveload/saveload.cpp
index eb46fe094..0a6585ce8 100644
--- a/src/saveload.cpp
+++ b/src/saveload/saveload.cpp
@@ -13,32 +13,35 @@
* <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 "../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
@@ -1069,7 +1072,7 @@ static void SlLoadChunks()
*******************************************/
#define LZO_SIZE 8192
-#include "minilzo.h"
+#include "../minilzo.h"
static size_t ReadLZO()
{
@@ -1157,8 +1160,8 @@ static void UninitNoComp()
********** START OF MEMORY CODE (in ram)****
********************************************/
-#include "table/sprites.h"
-#include "gui.h"
+#include "../table/sprites.h"
+#include "../gui.h"
struct ThreadedSave {
uint count;
@@ -1298,6 +1301,7 @@ static void UninitWriteZlib()
/* 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[] ;
@@ -1313,6 +1317,7 @@ 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[];
@@ -1321,6 +1326,7 @@ 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,
@@ -1331,6 +1337,7 @@ static const ChunkHandler * const _chunk_handlers[] = {
_order_chunk_handlers,
_industry_chunk_handlers,
_economy_chunk_handlers,
+ _subsidy_chunk_handlers,
_engine_chunk_handlers,
_town_chunk_handlers,
_sign_chunk_handlers,
@@ -1501,7 +1508,6 @@ static const SaveLoadFormat *GetSavegameFormat(const char *s)
/* 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 */
diff --git a/src/saveload.h b/src/saveload/saveload.h
index 6585230a9..f71b0dec4 100644
--- a/src/saveload.h
+++ b/src/saveload/saveload.h
@@ -5,7 +5,7 @@
#ifndef SAVELOAD_H
#define SAVELOAD_H
-#include "fileio_type.h"
+#include "../fileio_type.h"
#ifdef SIZE_MAX
#undef SIZE_MAX
diff --git a/src/saveload/saveload_internal.h b/src/saveload/saveload_internal.h
new file mode 100644
index 000000000..7bb865d81
--- /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 */
diff --git a/src/saveload/signs_sl.cpp b/src/saveload/signs_sl.cpp
new file mode 100644
index 000000000..ef4530dcd
--- /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},
+};
diff --git a/src/saveload/station_sl.cpp b/src/saveload/station_sl.cpp
new file mode 100644
index 000000000..b03e59c7d
--- /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},
+};
diff --git a/src/saveload/strings_sl.cpp b/src/saveload/strings_sl.cpp
new file mode 100644
index 000000000..f436bdedf
--- /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},
+};
diff --git a/src/saveload/subsidy_sl.cpp b/src/saveload/subsidy_sl.cpp
new file mode 100644
index 000000000..95fac25c7
--- /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},
+};
diff --git a/src/saveload/town_sl.cpp b/src/saveload/town_sl.cpp
new file mode 100644
index 000000000..eaa3edaa3
--- /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},
+};
diff --git a/src/saveload/vehicle_sl.cpp b/src/saveload/vehicle_sl.cpp
new file mode 100644
index 000000000..33f043b45
--- /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},
+};
diff --git a/src/saveload/waypoint_sl.cpp b/src/saveload/waypoint_sl.cpp
new file mode 100644
index 000000000..e8a8bf949
--- /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},
+};
diff --git a/src/screenshot.cpp b/src/screenshot.cpp
index ced474d91..4fd62c4dd 100644
--- 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"
diff --git a/src/settings.cpp b/src/settings.cpp
index 53fafaf9b..a7bea9cf0 100644
--- 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"
diff --git a/src/settings_internal.h b/src/settings_internal.h
index 73357451c..20cd4eca5 100644
--- 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
diff --git a/src/signs.cpp b/src/signs.cpp
index 1c2d846cd..7866783c7 100644
--- 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 @@ static void UpdateSignVirtCoords(Sign *si)
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 @@ void InitializeSigns()
_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},
-};
diff --git a/src/signs_base.h b/src/signs_base.h
index 1c25656e2..52737a833 100644
--- 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)
diff --git a/src/station.cpp b/src/station.cpp
index 672c3d320..df256adb3 100644
--- 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"
diff --git a/src/station_cmd.cpp b/src/station_cmd.cpp
index 1923ebd61..7abdd0d2d 100644
--- 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 @@ void InitializeStations()
_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 @@ extern const TileTypeProcs _tile_type_station_procs = {
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},
-};
diff --git a/src/station_func.h b/src/station_func.h
index ebb41a40d..9f47cfb38 100644
--- a/src/station_func.h
+++ b/src/station_func.h
@@ -25,7 +25,6 @@ StationSet FindStationsAroundTiles(TileIndex tile, int w_prod, int h_prod);
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);
diff --git a/src/strings.cpp b/src/strings.cpp
index a03354ae5..5aa15fe0f 100644
--- 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 @@ void CheckForMissingGlyphsInLoadedLanguagePack()
/* --- 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},
-};
diff --git a/src/strings_func.h b/src/strings_func.h
index 2c53bac8c..a1b090195 100644
--- a/src/strings_func.h
+++ b/src/strings_func.h
@@ -68,7 +68,4 @@ struct StringIDCompare
void CheckForMissingGlyphsInLoadedLanguagePack();
-StringID RemapOldStringID(StringID s);
-char *CopyFromOldName(StringID id);
-
#endif /* STRINGS_TYPE_H */
diff --git a/src/town.h b/src/town.h
index 0e2b2221b..1d9fb3380 100644
--- a/src/town.h
+++ b/src/town.h
@@ -362,7 +362,6 @@ extern int _cleared_town_rating;
void ResetHouses();
void ClearTownHouse(Town *t, TileIndex tile);
-void AfterLoadTown();
void UpdateTownMaxPass(Town *t);
void UpdateTownRadius(Town *t);
bool CheckIfAuthorityAllows(TileIndex tile);
diff --git a/src/town_cmd.cpp b/src/town_cmd.cpp
index 218f4d9c7..c666442c7 100644
--- 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 @@ extern const TileTypeProcs _tile_type_town_procs = {
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));
diff --git a/src/train.h b/src/train.h
index 5e57bdb2d..0adcc69cc 100644
--- a/src/train.h
+++ b/src/train.h
@@ -287,9 +287,6 @@ static inline Vehicle *GetPrevUnit(const Vehicle *v)
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);
diff --git a/src/train_cmd.cpp b/src/train_cmd.cpp
index 432ef9e8e..9960b1be7 100644
--- a/src/train_cmd.cpp
+++ b/src/train_cmd.cpp
@@ -4500,146 +4500,3 @@ void InitializeTrains()
{
_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;
- }
- }
- }
- }
- }
-}
diff --git a/src/variables.h b/src/variables.h
index c69d400fa..cd8c16e33 100644
--- a/src/variables.h
+++ b/src/variables.h
@@ -33,10 +33,6 @@ VARDEF uint _next_competitor_start;
/* 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;
diff --git a/src/vehicle.cpp b/src/vehicle.cpp
index 4f620e5f0..108ccb8d7 100644
--- 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 @@ void VehiclePositionChanged(Vehicle *v)
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 @@ void ResetVehicleColorMap()
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 @@ Vehicle::~Vehicle()
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 @@ SpriteID GetVehiclePalette(const Vehicle *v)
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()
{
diff --git a/src/vehicle_base.h b/src/vehicle_base.h
index 42fd3d44d..7d6a9985d 100644
--- a/src/vehicle_base.h
+++ b/src/vehicle_base.h
@@ -194,7 +194,6 @@ DECLARE_OLD_POOL(Vehicle, Vehicle, 9, 125)
/* 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 @@ Trackdir GetVehicleTrackdir(const Vehicle* v);
void CheckVehicle32Day(Vehicle *v);
+static const int32 INVALID_COORD = 0x7fffffff;
+
#endif /* VEHICLE_BASE_H */
diff --git a/src/viewport.cpp b/src/viewport.cpp
index 0622f85a3..0d97d8cd0 100644
--- a/src/viewport.cpp
+++ b/src/viewport.cpp
@@ -2785,33 +2785,3 @@ void ResetObjectToPlace()
{
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();
-}
diff --git a/src/water.h b/src/water.h
index e54d2e1ea..2fa063b3c 100644
--- a/src/water.h
+++ b/src/water.h
@@ -15,6 +15,5 @@ void DrawWaterClassGround(const struct TileInfo *ti);
void DrawShoreTile(Slope tileh);
void MakeWaterKeepingClass(TileIndex tile, Owner o);
-void SetWaterClassDependingOnSurroundings(TileIndex t, bool include_invalid_water_class);
#endif /* WATER_H */
diff --git a/src/water_cmd.cpp b/src/water_cmd.cpp
index 0c7907f20..6735d2231 100644
--- a/src/water_cmd.cpp
+++ b/src/water_cmd.cpp
@@ -101,88 +101,6 @@ static void MarkCanalsAndRiversAroundDirty(TileIndex tile)
}
}
-/**
- * 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
diff --git a/src/waypoint.cpp b/src/waypoint.cpp
index 81d7d9563..888d2d795 100644
--- 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 @@ static Waypoint *FindDeletedWaypointCloseTo(TileIndex tile)
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 @@ Waypoint::~Waypoint()
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},
-};
diff --git a/src/waypoint.h b/src/waypoint.h
index 8b07bdbac..e4af9c1a1 100644
--- 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 @@ CommandCost RemoveTrainWaypoint(TileIndex tile, uint32 flags, bool justremove);
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 */
diff --git a/src/win32.cpp b/src/win32.cpp
index 98d626094..338253194 100644
--- 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"