From a3ab74e16b99094dd71f5286e987d916d52185b0 Mon Sep 17 00:00:00 2001 From: Charles Pigott Date: Fri, 26 Apr 2019 19:09:55 +0100 Subject: [PATCH 1/4] Fix: Crash when attempting to load old save game with GRFs set GroupStatistics pool was not initialised before trying to delete vehicles (specifically, trams with no tram track) --- src/saveload/afterload.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/saveload/afterload.cpp b/src/saveload/afterload.cpp index 8d9b0ffa6c955..f3c35b647dae8 100644 --- a/src/saveload/afterload.cpp +++ b/src/saveload/afterload.cpp @@ -1900,6 +1900,7 @@ bool AfterLoadGame() } if (IsSavegameVersionBefore(SLV_62)) { + GroupStatistics::UpdateAfterLoad(); // Ensure statistics pool is initialised before trying to delete vehicles /* Remove all trams from savegames without tram support. * There would be trams without tram track under causing crashes sooner or later. */ RoadVehicle *v; From 13defee4d05c1a9610c2ea5889d798a9cbd0f113 Mon Sep 17 00:00:00 2001 From: Charles Pigott Date: Fri, 26 Apr 2019 20:22:06 +0100 Subject: [PATCH 2/4] Cleanup: Delete GetSavegameType function since it's been commented out since 2005 --- src/saveload/saveload.cpp | 33 --------------------------------- 1 file changed, 33 deletions(-) diff --git a/src/saveload/saveload.cpp b/src/saveload/saveload.cpp index d7ec59d6fe78c..83685b46b66f6 100644 --- a/src/saveload/saveload.cpp +++ b/src/saveload/saveload.cpp @@ -2887,36 +2887,3 @@ void FileToSaveLoad::SetTitle(const char *title) { strecpy(this->title, title, lastof(this->title)); } - -#if 0 -/** - * Function to get the type of the savegame by looking at the file header. - * NOTICE: Not used right now, but could be used if extensions of savegames are garbled - * @param file Savegame to be checked - * @return SL_OLD_LOAD or SL_LOAD of the file - */ -int GetSavegameType(char *file) -{ - const SaveLoadFormat *fmt; - uint32 hdr; - FILE *f; - int mode = SL_OLD_LOAD; - - f = fopen(file, "rb"); - if (fread(&hdr, sizeof(hdr), 1, f) != 1) { - DEBUG(sl, 0, "Savegame is obsolete or invalid format"); - mode = SL_LOAD; // don't try to get filename, just show name as it is written - } else { - /* see if we have any loader for this type. */ - for (fmt = _saveload_formats; fmt != endof(_saveload_formats); fmt++) { - if (fmt->tag == hdr) { - mode = SL_LOAD; // new type of savegame - break; - } - } - } - - fclose(f); - return mode; -} -#endif From 87aa139610db4bfc23b6c4d91a09b34902ced197 Mon Sep 17 00:00:00 2001 From: Charles Pigott Date: Sat, 27 Apr 2019 09:59:45 +0100 Subject: [PATCH 3/4] Fix #6507: Don't try to load invalid depots from older savegames --- src/saveload/afterload.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/saveload/afterload.cpp b/src/saveload/afterload.cpp index f3c35b647dae8..26551ac481b96 100644 --- a/src/saveload/afterload.cpp +++ b/src/saveload/afterload.cpp @@ -2312,6 +2312,14 @@ bool AfterLoadGame() if (IsSavegameVersionBefore(SLV_128)) { const Depot *d; FOR_ALL_DEPOTS(d) { + /* At some point, invalid depots were saved into the game (possibly those removed in the past?) + * Remove them here, so they don't cause issues further down the line */ + if (!IsDepotTile(d->xy)) { + DEBUG(sl, 0, "Removing invalid depot %d at %d, %d", d->index, TileX(d->xy), TileY(d->xy)); + delete d; + d = nullptr; + continue; + } _m[d->xy].m2 = d->index; if (IsTileType(d->xy, MP_WATER)) _m[GetOtherShipDepotTile(d->xy)].m2 = d->index; } From e345f90ee4f95188ae3e917c4d94e200b98f67db Mon Sep 17 00:00:00 2001 From: Charles Pigott Date: Sat, 27 Apr 2019 14:30:06 +0100 Subject: [PATCH 4/4] Fix 5db883f: Railtype bits were moved too late, leading to rails under bridges losing their type --- src/saveload/afterload.cpp | 64 +++++++++++++++++++------------------- 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/src/saveload/afterload.cpp b/src/saveload/afterload.cpp index 26551ac481b96..8a8e580b10600 100644 --- a/src/saveload/afterload.cpp +++ b/src/saveload/afterload.cpp @@ -1139,6 +1139,38 @@ bool AfterLoadGame() } } + /* Railtype moved from m3 to m8 in version SLV_EXTEND_RAILTYPES. */ + if (IsSavegameVersionBefore(SLV_EXTEND_RAILTYPES)) { + for (TileIndex t = 0; t < map_size; t++) { + switch (GetTileType(t)) { + case MP_RAILWAY: + SetRailType(t, (RailType)GB(_m[t].m3, 0, 4)); + break; + + case MP_ROAD: + if (IsLevelCrossing(t)) { + SetRailType(t, (RailType)GB(_m[t].m3, 0, 4)); + } + break; + + case MP_STATION: + if (HasStationRail(t)) { + SetRailType(t, (RailType)GB(_m[t].m3, 0, 4)); + } + break; + + case MP_TUNNELBRIDGE: + if (GetTunnelBridgeTransportType(t) == TRANSPORT_RAIL) { + SetRailType(t, (RailType)GB(_m[t].m3, 0, 4)); + } + break; + + default: + break; + } + } + } + if (IsSavegameVersionBefore(SLV_42)) { Vehicle *v; @@ -1220,38 +1252,6 @@ bool AfterLoadGame() } } - /* Railtype moved from m3 to m8 in version SLV_EXTEND_RAILTYPES. */ - if (IsSavegameVersionBefore(SLV_EXTEND_RAILTYPES)) { - for (TileIndex t = 0; t < map_size; t++) { - switch (GetTileType(t)) { - case MP_RAILWAY: - SetRailType(t, (RailType)GB(_m[t].m3, 0, 4)); - break; - - case MP_ROAD: - if (IsLevelCrossing(t)) { - SetRailType(t, (RailType)GB(_m[t].m3, 0, 4)); - } - break; - - case MP_STATION: - if (HasStationRail(t)) { - SetRailType(t, (RailType)GB(_m[t].m3, 0, 4)); - } - break; - - case MP_TUNNELBRIDGE: - if (GetTunnelBridgeTransportType(t) == TRANSPORT_RAIL) { - SetRailType(t, (RailType)GB(_m[t].m3, 0, 4)); - } - break; - - default: - break; - } - } - } - /* Elrails got added in rev 24 */ if (IsSavegameVersionBefore(SLV_24)) { RailType min_rail = RAILTYPE_ELECTRIC;