Add support for loading trunk savegames versions 293 - 299 (12.0)

Use modified upstream saveload implementation for these versions
Re-arrange headers to support multiple saveload implementations
pull/332/head
Jonathan G Rennison 3 years ago
parent c6f0559ad4
commit d1f1a6942a

@ -18,7 +18,7 @@
#include "vehicle_type.h"
#include "company_type.h"
#include "core/multimap.hpp"
#include "saveload/saveload.h"
#include "saveload/saveload_common.h"
#include <deque>
/** Unique identifier for a single cargo packet. */
@ -36,6 +36,12 @@ template <class Tinst, class Tcont> class CargoList;
class StationCargoList; // forward-declare, so we can use it in VehicleCargoList.
extern SaveLoadTable GetCargoPacketDesc();
namespace upstream_sl {
extern upstream_sl::SaveLoadTable GetCargoPacketDesc();
class SlVehicleCommon;
class SlStationGoods;
}
typedef uint32 TileOrStationID;
void ClearCargoPacketDeferredPayments();
@ -70,6 +76,7 @@ private:
friend class StationCargoList;
/** We want this to be saved, right? */
friend SaveLoadTable GetCargoPacketDesc();
friend upstream_sl::SaveLoadTable upstream_sl::GetCargoPacketDesc();
friend void Load_CPDP();
public:
/** Maximum number of items in a single cargo packet. */
@ -340,6 +347,7 @@ protected:
public:
/** The station cargo list needs to control the unloading. */
friend class StationCargoList;
friend upstream_sl::SlVehicleCommon;
/** The super class ought to know what it's doing. */
friend class CargoList<VehicleCargoList, CargoPacketList>;
/** The vehicles have a cargo list (and we want that saved). */
@ -495,6 +503,7 @@ public:
friend class CargoList<StationCargoList, StationCargoPacketMap>;
/** The stations, via GoodsEntry, have a CargoList. */
friend SaveLoadTable GetGoodsDesc();
friend upstream_sl::SlStationGoods;
friend class CargoLoad;
friend class CargoTransfer;

@ -103,28 +103,30 @@ struct CompanyProperties {
CompanyEconomyEntry old_economy[MAX_HISTORY_QUARTERS]; ///< Economic data of the company of the last #MAX_HISTORY_QUARTERS quarters.
byte num_valid_stat_ent; ///< Number of valid statistical entries in #old_economy.
Livery livery[LS_END];
EngineRenewList engine_renew_list; ///< Engine renewals of this company.
CompanySettings settings; ///< settings specific for each company
// TODO: Change some of these member variables to use relevant INVALID_xxx constants
CompanyProperties()
: name_2(0), name_1(0), president_name_1(0), president_name_2(0),
face(0), money(0), money_fraction(0), current_loan(0), colour(0), block_preview(0),
location_of_HQ(0), last_build_coordinate(0), share_owners(), inaugurated_year(0),
months_of_bankruptcy(0), bankrupt_last_asked(INVALID_COMPANY), bankrupt_asked(0), bankrupt_timeout(0), bankrupt_value(0),
terraform_limit(0), clear_limit(0), tree_limit(0), purchase_land_limit(0), build_object_limit(0), is_ai(false) {}
terraform_limit(0), clear_limit(0), tree_limit(0), purchase_land_limit(0), build_object_limit(0), is_ai(false), engine_renew_list(nullptr) {}
};
struct Company : CompanyPool::PoolItem<&_company_pool>, CompanyProperties {
Company(uint16 name_1 = 0, bool is_ai = false);
~Company();
Livery livery[LS_END];
RailTypes avail_railtypes; ///< Rail types available to this company.
RoadTypes avail_roadtypes; ///< Road types available to this company.
class AIInstance *ai_instance;
class AIInfo *ai_info;
EngineRenewList engine_renew_list; ///< Engine renewals of this company.
CompanySettings settings; ///< settings specific for each company
GroupStatistics group_all[VEH_COMPANY_END]; ///< NOSAVE: Statistics for the ALL_GROUP group.
GroupStatistics group_default[VEH_COMPANY_END]; ///< NOSAVE: Statistics for the DEFAULT_GROUP group.

@ -73,6 +73,8 @@ public:
typedef size_t size_type;
typedef std::ptrdiff_t difference_type;
constexpr span() noexcept : first(nullptr), last(nullptr) {}
constexpr span(pointer data_in, size_t size_in) : first(data_in), last(data_in + size_in) {}
template<class Container, typename std::enable_if<(is_compatible_container<Container, element_type>::value), int>::type = 0>

@ -13,7 +13,7 @@
#include "newgrf_config.h"
/** The actions we log. */
enum GamelogActionType {
enum GamelogActionType : uint8 {
GLAT_START, ///< Game created
GLAT_LOAD, ///< Game loaded
GLAT_GRF, ///< GRF changed

@ -17,7 +17,7 @@
#include "../station_base.h"
#include "../cargotype.h"
#include "../date_func.h"
#include "../saveload/saveload.h"
#include "../saveload/saveload_common.h"
#include "linkgraph_type.h"
#include <utility>
@ -31,6 +31,13 @@ typedef Pool<LinkGraph, LinkGraphID, 32, 0xFFFF> LinkGraphPool;
/** The actual pool with link graphs. */
extern LinkGraphPool _link_graph_pool;
namespace upstream_sl {
SaveLoadTable GetLinkGraphDesc();
SaveLoadTable GetLinkGraphJobDesc();
class SlLinkgraphNode;
class SlLinkgraphEdge;
}
/**
* A connected component of a link graph. Contains a complete set of stations
* connected by links as nodes and edges. Each component also holds a copy of
@ -536,6 +543,11 @@ protected:
friend void Save_LinkGraph(LinkGraph &lg);
friend void Load_LinkGraph(LinkGraph &lg);
friend upstream_sl::SaveLoadTable upstream_sl::GetLinkGraphDesc();
friend upstream_sl::SaveLoadTable upstream_sl::GetLinkGraphJobDesc();
friend upstream_sl::SlLinkgraphNode;
friend upstream_sl::SlLinkgraphEdge;
CargoID cargo; ///< Cargo of this component's link graph.
Date last_compression; ///< Last time the capacities and supplies were compressed.
NodeVector nodes; ///< Nodes in the component.

@ -27,6 +27,10 @@ typedef Pool<LinkGraphJob, LinkGraphJobID, 32, 0xFFFF> LinkGraphJobPool;
/** The actual pool with link graph jobs. */
extern LinkGraphJobPool _link_graph_job_pool;
namespace upstream_sl {
SaveLoadTable GetLinkGraphJobDesc();
}
/**
* Class for calculation jobs to be run on link graphs.
*/
@ -57,6 +61,7 @@ private:
typedef SmallMatrix<EdgeAnnotation> EdgeAnnotationMatrix;
friend SaveLoadTable GetLinkGraphJobDesc();
friend upstream_sl::SaveLoadTable upstream_sl::GetLinkGraphJobDesc();
friend void GetLinkGraphJobDayLengthScaleAfterLoad(LinkGraphJob *lgj);
friend class LinkGraphSchedule;
friend class LinkGraphJobGroup;

@ -16,6 +16,10 @@
class LinkGraphJob;
namespace upstream_sl {
SaveLoadTable GetLinkGraphScheduleDesc();
}
/**
* A handler doing "something" on a link graph component. It must not keep any
* state as it is called concurrently from different threads.
@ -42,6 +46,7 @@ private:
typedef std::list<LinkGraph *> GraphList;
typedef std::list<std::unique_ptr<LinkGraphJob>> JobList;
friend SaveLoadTable GetLinkGraphScheduleDesc();
friend upstream_sl::SaveLoadTable upstream_sl::GetLinkGraphScheduleDesc();
protected:
std::unique_ptr<ComponentHandler> handlers[6]; ///< Handlers to be run for each job.

@ -15,7 +15,7 @@
#include "tile_type.h"
#include "vehicle_type.h"
#include "base_consist.h"
#include "saveload/saveload.h"
#include "saveload/saveload_common.h"
/** Unique identifier for an order backup. */
typedef uint8 OrderBackupID;
@ -29,6 +29,11 @@ extern OrderBackupPool _order_backup_pool;
/** Flag to pass to the vehicle construction command when an order should be preserved. */
static const uint32 MAKE_ORDER_BACKUP_FLAG = 1U << 31;
namespace upstream_sl {
SaveLoadTable GetOrderBackupDescription();
struct BKORChunkHandler;
}
/**
* Data for backing up an order of a vehicle so it can be
* restored after a vehicle is rebuilt in the same depot.
@ -36,7 +41,9 @@ static const uint32 MAKE_ORDER_BACKUP_FLAG = 1U << 31;
struct OrderBackup : OrderBackupPool::PoolItem<&_order_backup_pool>, BaseConsist {
private:
friend SaveLoadTable GetOrderBackupDescription(); ///< Saving and loading of order backups.
friend upstream_sl::SaveLoadTable upstream_sl::GetOrderBackupDescription(); ///< Saving and loading of order backups.
friend void Load_BKOR(); ///< Creating empty orders upon savegame loading.
friend upstream_sl::BKORChunkHandler;
uint32 user; ///< The user that requested the backup.
TileIndex tile; ///< Tile of the depot where the order was changed.
GroupID group; ///< The group the vehicle was part of.

@ -19,7 +19,7 @@
#include "vehicle_type.h"
#include "date_type.h"
#include "schdispatch.h"
#include "saveload/saveload.h"
#include "saveload/saveload_common.h"
#include <memory>
#include <vector>
@ -56,6 +56,13 @@ struct OrderExtraInfo {
uint8 xflags = 0; ///< Extra flags
};
namespace upstream_sl {
SaveLoadTable GetOrderDescription();
SaveLoadTable GetOrderListDescription();
class SlVehicleCommon;
class SlVehicleDisaster;
}
/* If you change this, keep in mind that it is saved on 3 places:
* - Load_ORDR, all the global orders
* - Vehicle -> current_order
@ -66,6 +73,9 @@ private:
friend SaveLoadTable GetVehicleDescription(VehicleType vt); ///< Saving and loading the current order of vehicles.
friend void Load_VEHS(); ///< Loading of ancient vehicles.
friend SaveLoadTable GetOrderDescription(); ///< Saving and loading of orders.
friend upstream_sl::SaveLoadTable upstream_sl::GetOrderDescription(); ///< Saving and loading of orders.
friend upstream_sl::SlVehicleCommon;
friend upstream_sl::SlVehicleDisaster;
friend void Load_ORDX(); ///< Saving and loading of orders.
friend void Save_ORDX(); ///< Saving and loading of orders.
friend void Load_VEOX(); ///< Saving and loading of orders.
@ -588,6 +598,7 @@ struct OrderList : OrderListPool::PoolItem<&_orderlist_pool> {
private:
friend void AfterLoadVehicles(bool part_of_load); ///< For instantiating the shared vehicle chain
friend SaveLoadTable GetOrderListDescription(); ///< Saving and loading of order lists.
friend upstream_sl::SaveLoadTable upstream_sl::GetOrderListDescription(); ///< Saving and loading of order lists.
friend void Ptrs_ORDL(); ///< Saving and loading of order lists.
StationID GetBestLoadableNext(const Vehicle *v, const Order *o1, const Order *o2) const;

@ -1,3 +1,5 @@
add_subdirectory(upstream)
add_files(
afterload.cpp
ai_sl.cpp
@ -35,8 +37,10 @@ add_files(
saveload.cpp
saveload.h
saveload_buffer.h
saveload_common.h
saveload_filter.h
saveload_internal.h
saveload_types.h
signal_sl.cpp
signs_sl.cpp
station_sl.cpp

@ -56,6 +56,7 @@ bool _sl_is_ext_version; ///< is this an exte
bool _sl_is_faked_ext; ///< is this a faked extended savegame version, with no SLXI chunk? See: SlXvCheckSpecialSavegameVersions.
bool _sl_maybe_springpp; ///< is this possibly a SpringPP savegame?
bool _sl_maybe_chillpp; ///< is this possibly a ChillPP v8 savegame?
bool _sl_upstream_mode; ///< load game using upstream loader
std::vector<uint32> _sl_xv_discardable_chunk_ids; ///< list of chunks IDs which we can discard if no chunk loader exists
std::string _sl_xv_version_label; ///< optional SLXI version label
@ -224,6 +225,7 @@ void SlXvResetState()
_sl_is_faked_ext = false;
_sl_maybe_springpp = false;
_sl_maybe_chillpp = false;
_sl_upstream_mode = false;
_sl_xv_discardable_chunk_ids.clear();
memset(_sl_xv_feature_versions, 0, sizeof(_sl_xv_feature_versions));
_sl_xv_version_label.clear();

@ -11,6 +11,7 @@
#define EXTENDED_VER_SL_H
#include "../core/bitmath_func.hpp"
#include "../core/enum_type.hpp"
#include <vector>

@ -16,7 +16,7 @@
#include "../safeguards.h"
static std::vector<RailTypeLabel> _railtype_list;
std::vector<RailTypeLabel> _railtype_list;
/**
* Test if any saved rail type labels are different to the currently loaded

@ -241,6 +241,7 @@ static void Load_LGRJ()
LinkGraphJob *lgj = new (index) LinkGraphJob();
SlObjectLoadFiltered(lgj, _filtered_job_desc);
if (SlXvIsFeatureMissing(XSLFI_LINKGRAPH_DAY_SCALE)) {
extern void GetLinkGraphJobDayLengthScaleAfterLoad(LinkGraphJob *lgj);
GetLinkGraphJobDayLengthScaleAfterLoad(lgj);
}
LinkGraph &lg = const_cast<LinkGraph &>(lgj->Graph());

@ -74,7 +74,7 @@
#include "../safeguards.h"
extern const SaveLoadVersion SAVEGAME_VERSION = SLV_CUSTOM_SUBSIDY_DURATION; ///< Current savegame version of OpenTTD.
extern const SaveLoadVersion MAX_LOAD_SAVEGAME_VERSION = SLV_CUSTOM_SUBSIDY_DURATION; ///< Max loadable savegame version of OpenTTD.
extern const SaveLoadVersion MAX_LOAD_SAVEGAME_VERSION = (SaveLoadVersion)(SL_MAX_VERSION - 1); ///< Max loadable savegame version of OpenTTD.
const SaveLoadVersion SAVEGAME_VERSION_EXT = (SaveLoadVersion)(0x8000); ///< Savegame extension indicator mask
@ -90,6 +90,14 @@ bool _do_autosave; ///< are we doing an autosave at the moment?
extern bool _sl_is_ext_version;
extern bool _sl_maybe_springpp;
extern bool _sl_maybe_chillpp;
extern bool _sl_upstream_mode;
namespace upstream_sl {
void SlNullPointers();
void SlLoadChunks();
void SlLoadCheckChunks();
void SlFixPointers();
}
/** What are we currently doing? */
enum SaveLoadAction {
@ -357,6 +365,11 @@ static const std::vector<ChunkHandler> &ChunkHandlers()
/** Null all pointers (convert index -> nullptr) */
static void SlNullPointers()
{
if (_sl_upstream_mode) {
upstream_sl::SlNullPointers();
return;
}
_sl.action = SLA_NULL;
/* We don't want any savegame conversion code to run
@ -2277,6 +2290,11 @@ static const ChunkHandler *SlFindChunkHandler(uint32 id)
/** Load all chunks */
static void SlLoadChunks()
{
if (_sl_upstream_mode) {
upstream_sl::SlLoadChunks();
return;
}
for (uint32 id = SlReadUint32(); id != 0; id = SlReadUint32()) {
DEBUG(sl, 2, "Loading chunk %c%c%c%c", id >> 24, id >> 16, id >> 8, id);
size_t read = 0;
@ -2300,6 +2318,11 @@ static void SlLoadChunks()
/** Load all chunks for savegame checking */
static void SlLoadCheckChunks()
{
if (_sl_upstream_mode) {
upstream_sl::SlLoadCheckChunks();
return;
}
uint32 id;
const ChunkHandler *ch;
@ -2322,6 +2345,11 @@ static void SlLoadCheckChunks()
/** Fix all pointers (convert index -> pointer) */
static void SlFixPointers()
{
if (_sl_upstream_mode) {
upstream_sl::SlFixPointers();
return;
}
_sl.action = SLA_PTRS;
for (auto &ch : ChunkHandlers()) {
@ -3388,8 +3416,17 @@ static SaveOrLoadResult DoLoad(LoadFilter *reader, bool load_check)
special_version = SlXvCheckSpecialSavegameVersions();
}
DEBUG(sl, 1, "Loading savegame version %d%s%s%s", _sl_version, _sl_is_ext_version ? " (extended)" : "",
_sl_maybe_springpp ? " which might be SpringPP" : "", _sl_maybe_chillpp ? " which might be ChillPP" : "");
if (_sl_version >= SLV_SAVELOAD_LIST_LENGTH) {
if (_sl_is_ext_version) {
DEBUG(sl, 0, "Got an extended savegame version with a base version in the upstream mode range, giving up");
SlError(STR_GAME_SAVELOAD_ERROR_TOO_NEW_SAVEGAME);
} else {
_sl_upstream_mode = true;
}
}
DEBUG(sl, 1, "Loading savegame version %d%s%s%s%s", _sl_version, _sl_is_ext_version ? " (extended)" : "",
_sl_maybe_springpp ? " which might be SpringPP" : "", _sl_maybe_chillpp ? " which might be ChillPP" : "", _sl_upstream_mode ? " (upstream mode)" : "");
/* Is the version higher than the current? */
if (_sl_version > MAX_LOAD_SAVEGAME_VERSION && !special_version) SlError(STR_GAME_SAVELOAD_ERROR_TOO_NEW_SAVEGAME);
@ -3684,3 +3721,8 @@ void FileToSaveLoad::SetTitle(const char *title)
{
strecpy(this->title, title, lastof(this->title));
}
bool SaveLoadFileTypeIsScenario()
{
return _file_to_saveload.abstract_ftype == FT_SCENARIO;
}

@ -10,368 +10,15 @@
#ifndef SAVELOAD_H
#define SAVELOAD_H
#include "saveload_types.h"
#include "../fileio_type.h"
#include "../strings_type.h"
#include "../core/span_type.hpp"
#include "extended_ver_sl.h"
#include <stdarg.h>
#include <vector>
#include <string>
#include <vector>
/** SaveLoad versions
* Previous savegame versions, the trunk revision where they were
* introduced and the released version that had that particular
* savegame version.
* Up to savegame version 18 there is a minor version as well.
*
* Older entries keep their original numbering.
*
* Newer entries should use a descriptive labels, numeric version
* and PR can be added to comment.
*
* Note that this list must not be reordered.
*/
enum SaveLoadVersion : uint16 {
SL_MIN_VERSION, ///< First savegame version
SLV_1, ///< 1.0 0.1.x, 0.2.x
SLV_2, /**< 2.0 0.3.0
* 2.1 0.3.1, 0.3.2 */
SLV_3, ///< 3.x lost
SLV_4, /**< 4.0 1
* 4.1 122 0.3.3, 0.3.4
* 4.2 1222 0.3.5
* 4.3 1417
* 4.4 1426 */
SLV_5, /**< 5.0 1429
* 5.1 1440
* 5.2 1525 0.3.6 */
SLV_6, /**< 6.0 1721
* 6.1 1768 */
SLV_7, ///< 7.0 1770
SLV_8, ///< 8.0 1786
SLV_9, ///< 9.0 1909
SLV_10, ///< 10.0 2030
SLV_11, /**< 11.0 2033
* 11.1 2041 */
SLV_12, ///< 12.1 2046
SLV_13, ///< 13.1 2080 0.4.0, 0.4.0.1
SLV_14, ///< 14.0 2441
SLV_15, ///< 15.0 2499
SLV_16, /**< 16.0 2817
* 16.1 3155 */
SLV_17, /**< 17.0 3212
* 17.1 3218 */
SLV_18, ///< 18 3227
SLV_19, ///< 19 3396
SLV_20, ///< 20 3403
SLV_21, ///< 21 3472 0.4.x
SLV_22, ///< 22 3726
SLV_23, ///< 23 3915
SLV_24, ///< 24 4150
SLV_25, ///< 25 4259
SLV_26, ///< 26 4466
SLV_27, ///< 27 4757
SLV_28, ///< 28 4987
SLV_29, ///< 29 5070
SLV_30, ///< 30 5946
SLV_31, ///< 31 5999
SLV_32, ///< 32 6001
SLV_33, ///< 33 6440
SLV_34, ///< 34 6455
SLV_35, ///< 35 6602
SLV_36, ///< 36 6624
SLV_37, ///< 37 7182
SLV_38, ///< 38 7195
SLV_39, ///< 39 7269
SLV_40, ///< 40 7326
SLV_41, ///< 41 7348 0.5.x
SLV_42, ///< 42 7573
SLV_43, ///< 43 7642
SLV_44, ///< 44 8144
SLV_45, ///< 45 8501
SLV_46, ///< 46 8705
SLV_47, ///< 47 8735
SLV_48, ///< 48 8935
SLV_49, ///< 49 8969
SLV_50, ///< 50 8973
SLV_51, ///< 51 8978
SLV_52, ///< 52 9066
SLV_53, ///< 53 9316
SLV_54, ///< 54 9613
SLV_55, ///< 55 9638
SLV_56, ///< 56 9667
SLV_57, ///< 57 9691
SLV_58, ///< 58 9762
SLV_59, ///< 59 9779
SLV_60, ///< 60 9874
SLV_61, ///< 61 9892
SLV_62, ///< 62 9905
SLV_63, ///< 63 9956
SLV_64, ///< 64 10006
SLV_65, ///< 65 10210
SLV_66, ///< 66 10211
SLV_67, ///< 67 10236
SLV_68, ///< 68 10266
SLV_69, ///< 69 10319
SLV_70, ///< 70 10541
SLV_71, ///< 71 10567
SLV_72, ///< 72 10601
SLV_73, ///< 73 10903
SLV_74, ///< 74 11030
SLV_75, ///< 75 11107
SLV_76, ///< 76 11139
SLV_77, ///< 77 11172
SLV_78, ///< 78 11176
SLV_79, ///< 79 11188
SLV_80, ///< 80 11228
SLV_81, ///< 81 11244
SLV_82, ///< 82 11410
SLV_83, ///< 83 11589
SLV_84, ///< 84 11822
SLV_85, ///< 85 11874
SLV_86, ///< 86 12042
SLV_87, ///< 87 12129
SLV_88, ///< 88 12134
SLV_89, ///< 89 12160
SLV_90, ///< 90 12293
SLV_91, ///< 91 12347
SLV_92, ///< 92 12381 0.6.x
SLV_93, ///< 93 12648
SLV_94, ///< 94 12816
SLV_95, ///< 95 12924
SLV_96, ///< 96 13226
SLV_97, ///< 97 13256
SLV_98, ///< 98 13375
SLV_99, ///< 99 13838
SLV_100, ///< 100 13952
SLV_101, ///< 101 14233
SLV_102, ///< 102 14332
SLV_103, ///< 103 14598
SLV_104, ///< 104 14735
SLV_105, ///< 105 14803
SLV_106, ///< 106 14919
SLV_107, ///< 107 15027
SLV_108, ///< 108 15045
SLV_109, ///< 109 15075
SLV_110, ///< 110 15148
SLV_111, ///< 111 15190
SLV_112, ///< 112 15290
SLV_113, ///< 113 15340
SLV_114, ///< 114 15601
SLV_115, ///< 115 15695
SLV_116, ///< 116 15893 0.7.x
SLV_117, ///< 117 16037
SLV_118, ///< 118 16129
SLV_119, ///< 119 16242
SLV_120, ///< 120 16439
SLV_121, ///< 121 16694
SLV_122, ///< 122 16855
SLV_123, ///< 123 16909
SLV_124, ///< 124 16993
SLV_125, ///< 125 17113
SLV_126, ///< 126 17433
SLV_127, ///< 127 17439
SLV_128, ///< 128 18281
SLV_129, ///< 129 18292
SLV_130, ///< 130 18404
SLV_131, ///< 131 18481
SLV_132, ///< 132 18522
SLV_133, ///< 133 18674
SLV_134, ///< 134 18703
SLV_135, ///< 135 18719
SLV_136, ///< 136 18764
SLV_137, ///< 137 18912
SLV_138, ///< 138 18942 1.0.x
SLV_139, ///< 139 19346
SLV_140, ///< 140 19382
SLV_141, ///< 141 19799
SLV_142, ///< 142 20003
SLV_143, ///< 143 20048
SLV_144, ///< 144 20334
SLV_145, ///< 145 20376
SLV_146, ///< 146 20446
SLV_147, ///< 147 20621
SLV_148, ///< 148 20659
SLV_149, ///< 149 20832
SLV_150, ///< 150 20857
SLV_151, ///< 151 20918
SLV_152, ///< 152 21171
SLV_153, ///< 153 21263
SLV_154, ///< 154 21426
SLV_155, ///< 155 21453
SLV_156, ///< 156 21728
SLV_157, ///< 157 21862
SLV_158, ///< 158 21933
SLV_159, ///< 159 21962
SLV_160, ///< 160 21974 1.1.x
SLV_161, ///< 161 22567
SLV_162, ///< 162 22713
SLV_163, ///< 163 22767
SLV_164, ///< 164 23290
SLV_165, ///< 165 23304
SLV_166, ///< 166 23415
SLV_167, ///< 167 23504
SLV_168, ///< 168 23637
SLV_169, ///< 169 23816
SLV_170, ///< 170 23826
SLV_171, ///< 171 23835
SLV_172, ///< 172 23947
SLV_173, ///< 173 23967 1.2.0-RC1
SLV_174, ///< 174 23973 1.2.x
SLV_175, ///< 175 24136
SLV_176, ///< 176 24446
SLV_177, ///< 177 24619
SLV_178, ///< 178 24789
SLV_179, ///< 179 24810
SLV_180, ///< 180 24998 1.3.x
SLV_181, ///< 181 25012
SLV_182, ///< 182 25115 FS#5492, r25259, r25296 Goal status
SLV_183, ///< 183 25363 Cargodist
SLV_184, ///< 184 25508 Unit localisation split
SLV_185, ///< 185 25620 Storybooks
SLV_186, ///< 186 25833 Objects storage
SLV_187, ///< 187 25899 Linkgraph - restricted flows
SLV_188, ///< 188 26169 v1.4 FS#5831 Unify RV travel time
SLV_189, ///< 189 26450 Hierarchical vehicle subgroups
SLV_190, ///< 190 26547 Separate order travel and wait times
SLV_191, ///< 191 26636 FS#6026 Fix disaster vehicle storage (No bump)
///< 191 26646 FS#6041 Linkgraph - store locations
SLV_192, ///< 192 26700 FS#6066 Fix saving of order backups
SLV_193, ///< 193 26802
SLV_194, ///< 194 26881 v1.5
SLV_195, ///< 195 27572 v1.6.1
SLV_196, ///< 196 27778 v1.7
SLV_197, ///< 197 27978 v1.8
SLV_198, ///< 198 PR#6763 Switch town growth rate and counter to actual game ticks
SLV_EXTEND_CARGOTYPES, ///< 199 PR#6802 Extend cargotypes to 64
SLV_EXTEND_RAILTYPES, ///< 200 PR#6805 Extend railtypes to 64, adding uint16 to map array.
SLV_EXTEND_PERSISTENT_STORAGE, ///< 201 PR#6885 Extend NewGRF persistent storages.
SLV_EXTEND_INDUSTRY_CARGO_SLOTS, ///< 202 PR#6867 Increase industry cargo slots to 16 in, 16 out
SLV_SHIP_PATH_CACHE, ///< 203 PR#7072 Add path cache for ships
SLV_SHIP_ROTATION, ///< 204 PR#7065 Add extra rotation stages for ships.
SLV_GROUP_LIVERIES, ///< 205 PR#7108 Livery storage change and group liveries.
SLV_SHIPS_STOP_IN_LOCKS, ///< 206 PR#7150 Ship/lock movement changes.
SLV_FIX_CARGO_MONITOR, ///< 207 PR#7175 v1.9 Cargo monitor data packing fix to support 64 cargotypes.
SLV_TOWN_CARGOGEN, ///< 208 PR#6965 New algorithms for town building cargo generation.
SLV_SHIP_CURVE_PENALTY, ///< 209 PR#7289 Configurable ship curve penalties.
SLV_SERVE_NEUTRAL_INDUSTRIES, ///< 210 PR#7234 Company stations can serve industries with attached neutral stations.
SLV_ROADVEH_PATH_CACHE, ///< 211 PR#7261 Add path cache for road vehicles.
SLV_REMOVE_OPF, ///< 212 PR#7245 Remove OPF.
SLV_TREES_WATER_CLASS, ///< 213 PR#7405 WaterClass update for tree tiles.
SLV_ROAD_TYPES, ///< 214 PR#6811 NewGRF road types.
SLV_SCRIPT_MEMLIMIT, ///< 215 PR#7516 Limit on AI/GS memory consumption.
SLV_MULTITILE_DOCKS, ///< 216 PR#7380 Multiple docks per station.
SLV_TRADING_AGE, ///< 217 PR#7780 Configurable company trading age.
SLV_ENDING_YEAR, ///< 218 PR#7747 v1.10 Configurable ending year.
SLV_REMOVE_TOWN_CARGO_CACHE, ///< 219 PR#8258 Remove town cargo acceptance and production caches.
/* Patchpacks for a while considered it a good idea to jump a few versions
* above our version for their savegames. But as time continued, this gap
* has been closing, up to the point we would start to reuse versions from
* their patchpacks. This is not a problem from our perspective: the
* savegame will simply fail to load because they all contain chunks we
* cannot digest. But, this gives for ugly errors. As we have plenty of
* versions anyway, we simply skip the versions we know belong to
* patchpacks. This way we can present the user with a clean error
* indicate they are loading a savegame from a patchpack.
* For future patchpack creators: please follow a system like JGRPP, where
* the version is masked with 0x8000, and the true version is stored in
* its own chunk with feature toggles.
*/
SLV_START_PATCHPACKS, ///< 220 First known patchpack to use a version just above ours.
SLV_END_PATCHPACKS = 286, ///< 286 Last known patchpack to use a version just above ours.
SLV_GS_INDUSTRY_CONTROL, ///< 287 PR#7912 and PR#8115 GS industry control.
SLV_VEH_MOTION_COUNTER, ///< 288 PR#8591 Desync safe motion counter
SLV_INDUSTRY_TEXT, ///< 289 PR#8576 v1.11.0-RC1 Additional GS text for industries.
SLV_MAPGEN_SETTINGS_REVAMP, ///< 290 PR#8891 v1.11 Revamp of some mapgen settings (snow coverage, desert coverage, heightmap height, custom terrain type).
SLV_GROUP_REPLACE_WAGON_REMOVAL, ///< 291 PR#7441 Per-group wagon removal flag.
SLV_CUSTOM_SUBSIDY_DURATION, ///< 292 PR#9081 Configurable subsidy duration.
/* upstream savegame versions follow */
SLV_SAVELOAD_LIST_LENGTH, ///< 293 PR#9374 Consistency in list length with SL_STRUCT / SL_STRUCTLIST / SL_DEQUE / SL_REFLIST.
SLV_RIFF_TO_ARRAY, ///< 294 PR#9375 Changed many CH_RIFF chunks to CH_ARRAY chunks.
SLV_TABLE_CHUNKS, ///< 295 PR#9322 Introduction of CH_TABLE and CH_SPARSE_TABLE.
SLV_SCRIPT_INT64, ///< 296 PR#9415 SQInteger is 64bit but was saved as 32bit.
SLV_LINKGRAPH_TRAVEL_TIME, ///< 297 PR#9457 v12.0-RC1 Store travel time in the linkgraph.
SLV_DOCK_DOCKINGTILES, ///< 298 PR#9578 All tiles around docks may be docking tiles.
SLV_REPAIR_OBJECT_DOCKING_TILES, ///< 299 PR#9594 v12.0 Fixing issue with docking tiles overlapping objects.
SL_MAX_VERSION, ///< Highest possible saveload version
SL_SPRING_2013_v2_0_102 = 220,
SL_SPRING_2013_v2_1_108 = 221,
SL_SPRING_2013_v2_1_147 = 222,
SL_SPRING_2013_v2_3_XXX = 223,
SL_SPRING_2013_v2_3_b3 = 224,
SL_SPRING_2013_v2_3_b4 = 225,
SL_SPRING_2013_v2_3_b5 = 226,
SL_SPRING_2013_v2_4 = 227,
SL_TRACE_RESTRICT_2000 = 2000,
SL_TRACE_RESTRICT_2001 = 2001,
SL_TRACE_RESTRICT_2002 = 2002,
SL_JOKER_1_19 = 278,
SL_JOKER_1_20 = 279,
SL_JOKER_1_21 = 280,
SL_JOKER_1_22 = 281,
SL_JOKER_1_23 = 282,
SL_JOKER_1_24 = 283,
SL_JOKER_1_25 = 284,
SL_JOKER_1_26 = 285,
SL_JOKER_1_27 = 286,
SL_CHILLPP_201 = 201,
SL_CHILLPP_232 = 232,
SL_CHILLPP_233 = 233,
};
/** Save or load result codes. */
enum SaveOrLoadResult {
SL_OK = 0, ///< completed successfully
@ -475,128 +122,6 @@ enum SaveLoadChunkExtHeaderFlags {
};
DECLARE_ENUM_AS_BIT_SET(SaveLoadChunkExtHeaderFlags)
/**
* VarTypes is the general bitmasked magic type that tells us
* certain characteristics about the variable it refers to. For example
* SLE_FILE_* gives the size(type) as it would be in the savegame and
* SLE_VAR_* the size(type) as it is in memory during runtime. These are
* the first 8 bits (0-3 SLE_FILE, 4-7 SLE_VAR).
* Bits 8-15 are reserved for various flags as explained below
*/
enum VarTypes {
/* 4 bits allocated a maximum of 16 types for NumberType */
SLE_FILE_I8 = 0,
SLE_FILE_U8 = 1,
SLE_FILE_I16 = 2,
SLE_FILE_U16 = 3,
SLE_FILE_I32 = 4,
SLE_FILE_U32 = 5,
SLE_FILE_I64 = 6,
SLE_FILE_U64 = 7,
SLE_FILE_STRINGID = 8, ///< StringID offset into strings-array
SLE_FILE_STRING = 9,
SLE_FILE_VEHORDERID = 10,
/* 5 more possible file-primitives */
/* 4 bits allocated a maximum of 16 types for NumberType */
SLE_VAR_BL = 0 << 4,
SLE_VAR_I8 = 1 << 4,
SLE_VAR_U8 = 2 << 4,
SLE_VAR_I16 = 3 << 4,
SLE_VAR_U16 = 4 << 4,
SLE_VAR_I32 = 5 << 4,
SLE_VAR_U32 = 6 << 4,
SLE_VAR_I64 = 7 << 4,
SLE_VAR_U64 = 8 << 4,
SLE_VAR_NULL = 9 << 4, ///< useful to write zeros in savegame.
SLE_VAR_STRB = 10 << 4, ///< string (with pre-allocated buffer)
SLE_VAR_STR = 12 << 4, ///< string pointer
SLE_VAR_STRQ = 13 << 4, ///< string pointer enclosed in quotes
SLE_VAR_NAME = 14 << 4, ///< old custom name to be converted to a std::string
SLE_VAR_CNAME = 15 << 4, ///< old custom name to be converted to a char pointer
/* 0 more possible memory-primitives */
/* Shortcut values */
SLE_VAR_CHAR = SLE_VAR_I8,
/* Default combinations of variables. As savegames change, so can variables
* and thus it is possible that the saved value and internal size do not
* match and you need to specify custom combo. The defaults are listed here */
SLE_BOOL = SLE_FILE_I8 | SLE_VAR_BL,
SLE_INT8 = SLE_FILE_I8 | SLE_VAR_I8,
SLE_UINT8 = SLE_FILE_U8 | SLE_VAR_U8,
SLE_INT16 = SLE_FILE_I16 | SLE_VAR_I16,
SLE_UINT16 = SLE_FILE_U16 | SLE_VAR_U16,
SLE_INT32 = SLE_FILE_I32 | SLE_VAR_I32,
SLE_UINT32 = SLE_FILE_U32 | SLE_VAR_U32,
SLE_INT64 = SLE_FILE_I64 | SLE_VAR_I64,
SLE_UINT64 = SLE_FILE_U64 | SLE_VAR_U64,
SLE_CHAR = SLE_FILE_I8 | SLE_VAR_CHAR,
SLE_STRINGID = SLE_FILE_STRINGID | SLE_VAR_U32,
SLE_STRINGBUF = SLE_FILE_STRING | SLE_VAR_STRB,
SLE_STRING = SLE_FILE_STRING | SLE_VAR_STR,
SLE_STRINGQUOTE = SLE_FILE_STRING | SLE_VAR_STRQ,
SLE_NAME = SLE_FILE_STRINGID | SLE_VAR_NAME,
SLE_CNAME = SLE_FILE_STRINGID | SLE_VAR_CNAME,
SLE_VEHORDERID = SLE_FILE_VEHORDERID | SLE_VAR_U16,
/* Shortcut values */
SLE_UINT = SLE_UINT32,
SLE_INT = SLE_INT32,
SLE_STRB = SLE_STRINGBUF,
SLE_STR = SLE_STRING,
SLE_STRQ = SLE_STRINGQUOTE,
/* 8 bits allocated for a maximum of 8 flags
* Flags directing saving/loading of a variable */
SLF_ALLOW_CONTROL = 1 << 8, ///< Allow control codes in the strings.
SLF_ALLOW_NEWLINE = 1 << 9, ///< Allow new lines in the strings.
};
typedef uint32 VarType;
/** Type of data saved. */
enum SaveLoadTypes {
SL_VAR = 0, ///< Save/load a variable.
SL_REF = 1, ///< Save/load a reference.
SL_ARR = 2, ///< Save/load a fixed-size array of #SL_VAR elements.
SL_STR = 3, ///< Save/load a string.
SL_REFLIST = 4, ///< Save/load a list of #SL_REF elements.
SL_DEQUE = 5, ///< Save/load a deque of #SL_VAR elements.
SL_VEC = 6, ///< Save/load a vector of #SL_REF elements.
SL_STDSTR = 7, ///< Save/load a std::string.
/* non-normal save-load types */
SL_WRITEBYTE = 8,
SL_VEH_INCLUDE = 9,
SL_ST_INCLUDE = 10,
SL_PTRDEQ = 13, ///< Save/load a deque of #SL_REF elements.
SL_VARVEC = 14, ///< Save/load a primitive type vector.
};
typedef byte SaveLoadType; ///< Save/load type. @see SaveLoadTypes
/** SaveLoad type struct. Do NOT use this directly but use the SLE_ macros defined just below! */
struct SaveLoad {
bool global; ///< should we load a global variable or a non-global one
SaveLoadType cmd; ///< the action to take with the saved/loaded type, All types need different action
VarType conv; ///< type of the variable to be saved, int
uint16 length; ///< (conditional) length of the variable (eg. arrays) (max array size is 65536 elements)
SaveLoadVersion version_from; ///< save/load the variable starting from this savegame version
SaveLoadVersion version_to; ///< save/load the variable until this savegame version
/* NOTE: This element either denotes the address of the variable for a global
* variable, or the offset within a struct which is then bound to a variable
* during runtime. Decision on which one to use is controlled by the function
* that is called to save it. address: global=true, offset: global=false */
void *address; ///< address of variable OR offset of variable in the struct (max offset is 65536)
size_t size; ///< the sizeof size.
SlXvFeatureTest ext_feature_test; ///< extended feature test
};
/** A table of SaveLoad entries. */
using SaveLoadTable = span<const SaveLoad>;
/**
* Storage of simple variables, references (pointers), and arrays.
* @param cmd Load/save type. @see SaveLoadType
@ -1097,22 +622,6 @@ void SlSetLength(size_t length);
size_t SlCalcObjMemberLength(const void *object, const SaveLoad &sld);
size_t SlCalcObjLength(const void *object, const SaveLoadTable &slt);
byte SlReadByte();
void SlWriteByte(byte b);
int SlReadUint16();
uint32 SlReadUint32();
uint64 SlReadUint64();
void SlWriteUint16(uint16 v);
void SlWriteUint32(uint32 v);
void SlWriteUint64(uint64 v);
void SlSkipBytes(size_t length);
size_t SlGetBytesRead();
size_t SlGetBytesWritten();
void SlGlobList(const SaveLoadTable &slt);
void SlArray(void *array, size_t length, VarType conv);
void SlObject(void *object, const SaveLoadTable &slt);
@ -1123,10 +632,7 @@ void SlObjectSaveFiltered(void *object, const SaveLoadTable &slt);
void SlObjectLoadFiltered(void *object, const SaveLoadTable &slt);
void SlObjectPtrOrNullFiltered(void *object, const SaveLoadTable &slt);
void NORETURN SlError(StringID string, const char *extra_msg = nullptr, bool already_malloced = false);
void NORETURN SlErrorCorrupt(const char *msg, bool already_malloced = false);
void NORETURN CDECL SlErrorFmt(StringID string, const char *msg, ...) WARN_FORMAT(2, 3);
void NORETURN CDECL SlErrorCorruptFmt(const char *format, ...) WARN_FORMAT(1, 2);
bool SaveloadCrashWithMissingNewGRFs();

@ -0,0 +1,402 @@
/*
* This file is part of OpenTTD.
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file saveload_common.h Common functions/types for saving and loading games. */
#ifndef SAVELOAD_COMMON_H
#define SAVELOAD_COMMON_H
#include "../strings_type.h"
#include "../core/span_type.hpp"
struct SaveLoad;
/** A table of SaveLoad entries. */
using SaveLoadTable = span<const SaveLoad>;
namespace upstream_sl {
struct SaveLoad;
/** A table of SaveLoad entries. */
using SaveLoadTable = span<const SaveLoad>;
}
/** SaveLoad versions
* Previous savegame versions, the trunk revision where they were
* introduced and the released version that had that particular
* savegame version.
* Up to savegame version 18 there is a minor version as well.
*
* Older entries keep their original numbering.
*
* Newer entries should use a descriptive labels, numeric version
* and PR can be added to comment.
*
* Note that this list must not be reordered.
*/
enum SaveLoadVersion : uint16 {
SL_MIN_VERSION, ///< First savegame version
SLV_1, ///< 1.0 0.1.x, 0.2.x
SLV_2, /**< 2.0 0.3.0
* 2.1 0.3.1, 0.3.2 */
SLV_3, ///< 3.x lost
SLV_4, /**< 4.0 1
* 4.1 122 0.3.3, 0.3.4
* 4.2 1222 0.3.5
* 4.3 1417
* 4.4 1426 */
SLV_5, /**< 5.0 1429
* 5.1 1440
* 5.2 1525 0.3.6 */
SLV_6, /**< 6.0 1721
* 6.1 1768 */
SLV_7, ///< 7.0 1770
SLV_8, ///< 8.0 1786
SLV_9, ///< 9.0 1909
SLV_10, ///< 10.0 2030
SLV_11, /**< 11.0 2033
* 11.1 2041 */
SLV_12, ///< 12.1 2046
SLV_13, ///< 13.1 2080 0.4.0, 0.4.0.1
SLV_14, ///< 14.0 2441
SLV_15, ///< 15.0 2499
SLV_16, /**< 16.0 2817
* 16.1 3155 */
SLV_17, /**< 17.0 3212
* 17.1 3218 */
SLV_18, ///< 18 3227
SLV_19, ///< 19 3396
SLV_20, ///< 20 3403
SLV_21, ///< 21 3472 0.4.x
SLV_22, ///< 22 3726
SLV_23, ///< 23 3915
SLV_24, ///< 24 4150
SLV_25, ///< 25 4259
SLV_26, ///< 26 4466
SLV_27, ///< 27 4757
SLV_28, ///< 28 4987
SLV_29, ///< 29 5070
SLV_30, ///< 30 5946
SLV_31, ///< 31 5999
SLV_32, ///< 32 6001
SLV_33, ///< 33 6440
SLV_34, ///< 34 6455
SLV_35, ///< 35 6602
SLV_36, ///< 36 6624
SLV_37, ///< 37 7182
SLV_38, ///< 38 7195
SLV_39, ///< 39 7269
SLV_40, ///< 40 7326
SLV_41, ///< 41 7348 0.5.x
SLV_42, ///< 42 7573
SLV_43, ///< 43 7642
SLV_44, ///< 44 8144
SLV_45, ///< 45 8501
SLV_46, ///< 46 8705
SLV_47, ///< 47 8735
SLV_48, ///< 48 8935
SLV_49, ///< 49 8969
SLV_50, ///< 50 8973
SLV_51, ///< 51 8978
SLV_52, ///< 52 9066
SLV_53, ///< 53 9316
SLV_54, ///< 54 9613
SLV_55, ///< 55 9638
SLV_56, ///< 56 9667
SLV_57, ///< 57 9691
SLV_58, ///< 58 9762
SLV_59, ///< 59 9779
SLV_60, ///< 60 9874
SLV_61, ///< 61 9892
SLV_62, ///< 62 9905
SLV_63, ///< 63 9956
SLV_64, ///< 64 10006
SLV_65, ///< 65 10210
SLV_66, ///< 66 10211
SLV_67, ///< 67 10236
SLV_68, ///< 68 10266
SLV_69, ///< 69 10319
SLV_70, ///< 70 10541
SLV_71, ///< 71 10567
SLV_72, ///< 72 10601
SLV_73, ///< 73 10903
SLV_74, ///< 74 11030
SLV_75, ///< 75 11107
SLV_76, ///< 76 11139
SLV_77, ///< 77 11172
SLV_78, ///< 78 11176
SLV_79, ///< 79 11188
SLV_80, ///< 80 11228
SLV_81, ///< 81 11244
SLV_82, ///< 82 11410
SLV_83, ///< 83 11589
SLV_84, ///< 84 11822
SLV_85, ///< 85 11874
SLV_86, ///< 86 12042
SLV_87, ///< 87 12129
SLV_88, ///< 88 12134
SLV_89, ///< 89 12160
SLV_90, ///< 90 12293
SLV_91, ///< 91 12347
SLV_92, ///< 92 12381 0.6.x
SLV_93, ///< 93 12648
SLV_94, ///< 94 12816
SLV_95, ///< 95 12924
SLV_96, ///< 96 13226
SLV_97, ///< 97 13256
SLV_98, ///< 98 13375
SLV_99, ///< 99 13838
SLV_100, ///< 100 13952
SLV_101, ///< 101 14233
SLV_102, ///< 102 14332
SLV_103, ///< 103 14598
SLV_104, ///< 104 14735
SLV_105, ///< 105 14803
SLV_106, ///< 106 14919
SLV_107, ///< 107 15027
SLV_108, ///< 108 15045
SLV_109, ///< 109 15075
SLV_110, ///< 110 15148
SLV_111, ///< 111 15190
SLV_112, ///< 112 15290
SLV_113, ///< 113 15340
SLV_114, ///< 114 15601
SLV_115, ///< 115 15695
SLV_116, ///< 116 15893 0.7.x
SLV_117, ///< 117 16037
SLV_118, ///< 118 16129
SLV_119, ///< 119 16242
SLV_120, ///< 120 16439
SLV_121, ///< 121 16694
SLV_122, ///< 122 16855
SLV_123, ///< 123 16909
SLV_124, ///< 124 16993
SLV_125, ///< 125 17113
SLV_126, ///< 126 17433
SLV_127, ///< 127 17439
SLV_128, ///< 128 18281
SLV_129, ///< 129 18292
SLV_130, ///< 130 18404
SLV_131, ///< 131 18481
SLV_132, ///< 132 18522
SLV_133, ///< 133 18674
SLV_134, ///< 134 18703
SLV_135, ///< 135 18719
SLV_136, ///< 136 18764
SLV_137, ///< 137 18912
SLV_138, ///< 138 18942 1.0.x
SLV_139, ///< 139 19346
SLV_140, ///< 140 19382
SLV_141, ///< 141 19799
SLV_142, ///< 142 20003
SLV_143, ///< 143 20048
SLV_144, ///< 144 20334
SLV_145, ///< 145 20376
SLV_146, ///< 146 20446
SLV_147, ///< 147 20621
SLV_148, ///< 148 20659
SLV_149, ///< 149 20832
SLV_150, ///< 150 20857
SLV_151, ///< 151 20918
SLV_152, ///< 152 21171
SLV_153, ///< 153 21263
SLV_154, ///< 154 21426
SLV_155, ///< 155 21453
SLV_156, ///< 156 21728
SLV_157, ///< 157 21862
SLV_158, ///< 158 21933
SLV_159, ///< 159 21962
SLV_160, ///< 160 21974 1.1.x
SLV_161, ///< 161 22567
SLV_162, ///< 162 22713
SLV_163, ///< 163 22767
SLV_164, ///< 164 23290
SLV_165, ///< 165 23304
SLV_166, ///< 166 23415
SLV_167, ///< 167 23504
SLV_168, ///< 168 23637
SLV_169, ///< 169 23816
SLV_170, ///< 170 23826
SLV_171, ///< 171 23835
SLV_172, ///< 172 23947
SLV_173, ///< 173 23967 1.2.0-RC1
SLV_174, ///< 174 23973 1.2.x
SLV_175, ///< 175 24136
SLV_176, ///< 176 24446
SLV_177, ///< 177 24619
SLV_178, ///< 178 24789
SLV_179, ///< 179 24810
SLV_180, ///< 180 24998 1.3.x
SLV_181, ///< 181 25012
SLV_182, ///< 182 25115 FS#5492, r25259, r25296 Goal status
SLV_183, ///< 183 25363 Cargodist
SLV_184, ///< 184 25508 Unit localisation split
SLV_185, ///< 185 25620 Storybooks
SLV_186, ///< 186 25833 Objects storage
SLV_187, ///< 187 25899 Linkgraph - restricted flows
SLV_188, ///< 188 26169 v1.4 FS#5831 Unify RV travel time
SLV_189, ///< 189 26450 Hierarchical vehicle subgroups
SLV_190, ///< 190 26547 Separate order travel and wait times
SLV_191, ///< 191 26636 FS#6026 Fix disaster vehicle storage (No bump)
///< 191 26646 FS#6041 Linkgraph - store locations
SLV_192, ///< 192 26700 FS#6066 Fix saving of order backups
SLV_193, ///< 193 26802
SLV_194, ///< 194 26881 v1.5
SLV_195, ///< 195 27572 v1.6.1
SLV_196, ///< 196 27778 v1.7
SLV_197, ///< 197 27978 v1.8
SLV_198, ///< 198 PR#6763 Switch town growth rate and counter to actual game ticks
SLV_EXTEND_CARGOTYPES, ///< 199 PR#6802 Extend cargotypes to 64
SLV_EXTEND_RAILTYPES, ///< 200 PR#6805 Extend railtypes to 64, adding uint16 to map array.
SLV_EXTEND_PERSISTENT_STORAGE, ///< 201 PR#6885 Extend NewGRF persistent storages.
SLV_EXTEND_INDUSTRY_CARGO_SLOTS, ///< 202 PR#6867 Increase industry cargo slots to 16 in, 16 out
SLV_SHIP_PATH_CACHE, ///< 203 PR#7072 Add path cache for ships
SLV_SHIP_ROTATION, ///< 204 PR#7065 Add extra rotation stages for ships.
SLV_GROUP_LIVERIES, ///< 205 PR#7108 Livery storage change and group liveries.
SLV_SHIPS_STOP_IN_LOCKS, ///< 206 PR#7150 Ship/lock movement changes.
SLV_FIX_CARGO_MONITOR, ///< 207 PR#7175 v1.9 Cargo monitor data packing fix to support 64 cargotypes.
SLV_TOWN_CARGOGEN, ///< 208 PR#6965 New algorithms for town building cargo generation.
SLV_SHIP_CURVE_PENALTY, ///< 209 PR#7289 Configurable ship curve penalties.
SLV_SERVE_NEUTRAL_INDUSTRIES, ///< 210 PR#7234 Company stations can serve industries with attached neutral stations.
SLV_ROADVEH_PATH_CACHE, ///< 211 PR#7261 Add path cache for road vehicles.
SLV_REMOVE_OPF, ///< 212 PR#7245 Remove OPF.
SLV_TREES_WATER_CLASS, ///< 213 PR#7405 WaterClass update for tree tiles.
SLV_ROAD_TYPES, ///< 214 PR#6811 NewGRF road types.
SLV_SCRIPT_MEMLIMIT, ///< 215 PR#7516 Limit on AI/GS memory consumption.
SLV_MULTITILE_DOCKS, ///< 216 PR#7380 Multiple docks per station.
SLV_TRADING_AGE, ///< 217 PR#7780 Configurable company trading age.
SLV_ENDING_YEAR, ///< 218 PR#7747 v1.10 Configurable ending year.
SLV_REMOVE_TOWN_CARGO_CACHE, ///< 219 PR#8258 Remove town cargo acceptance and production caches.
/* Patchpacks for a while considered it a good idea to jump a few versions
* above our version for their savegames. But as time continued, this gap
* has been closing, up to the point we would start to reuse versions from
* their patchpacks. This is not a problem from our perspective: the
* savegame will simply fail to load because they all contain chunks we
* cannot digest. But, this gives for ugly errors. As we have plenty of
* versions anyway, we simply skip the versions we know belong to
* patchpacks. This way we can present the user with a clean error
* indicate they are loading a savegame from a patchpack.
* For future patchpack creators: please follow a system like JGRPP, where
* the version is masked with 0x8000, and the true version is stored in
* its own chunk with feature toggles.
*/
SLV_START_PATCHPACKS, ///< 220 First known patchpack to use a version just above ours.
SLV_END_PATCHPACKS = 286, ///< 286 Last known patchpack to use a version just above ours.
SLV_GS_INDUSTRY_CONTROL, ///< 287 PR#7912 and PR#8115 GS industry control.
SLV_VEH_MOTION_COUNTER, ///< 288 PR#8591 Desync safe motion counter
SLV_INDUSTRY_TEXT, ///< 289 PR#8576 v1.11.0-RC1 Additional GS text for industries.
SLV_MAPGEN_SETTINGS_REVAMP, ///< 290 PR#8891 v1.11 Revamp of some mapgen settings (snow coverage, desert coverage, heightmap height, custom terrain type).
SLV_GROUP_REPLACE_WAGON_REMOVAL, ///< 291 PR#7441 Per-group wagon removal flag.
SLV_CUSTOM_SUBSIDY_DURATION, ///< 292 PR#9081 Configurable subsidy duration.
/* upstream savegame versions follow */
SLV_SAVELOAD_LIST_LENGTH, ///< 293 PR#9374 Consistency in list length with SL_STRUCT / SL_STRUCTLIST / SL_DEQUE / SL_REFLIST.
SLV_RIFF_TO_ARRAY, ///< 294 PR#9375 Changed many CH_RIFF chunks to CH_ARRAY chunks.
SLV_TABLE_CHUNKS, ///< 295 PR#9322 Introduction of CH_TABLE and CH_SPARSE_TABLE.
SLV_SCRIPT_INT64, ///< 296 PR#9415 SQInteger is 64bit but was saved as 32bit.
SLV_LINKGRAPH_TRAVEL_TIME, ///< 297 PR#9457 v12.0-RC1 Store travel time in the linkgraph.
SLV_DOCK_DOCKINGTILES, ///< 298 PR#9578 All tiles around docks may be docking tiles.
SLV_REPAIR_OBJECT_DOCKING_TILES, ///< 299 PR#9594 v12.0 Fixing issue with docking tiles overlapping objects.
SL_MAX_VERSION, ///< Highest possible saveload version
SL_SPRING_2013_v2_0_102 = 220,
SL_SPRING_2013_v2_1_108 = 221,
SL_SPRING_2013_v2_1_147 = 222,
SL_SPRING_2013_v2_3_XXX = 223,
SL_SPRING_2013_v2_3_b3 = 224,
SL_SPRING_2013_v2_3_b4 = 225,
SL_SPRING_2013_v2_3_b5 = 226,
SL_SPRING_2013_v2_4 = 227,
SL_TRACE_RESTRICT_2000 = 2000,
SL_TRACE_RESTRICT_2001 = 2001,
SL_TRACE_RESTRICT_2002 = 2002,
SL_JOKER_1_19 = 278,
SL_JOKER_1_20 = 279,
SL_JOKER_1_21 = 280,
SL_JOKER_1_22 = 281,
SL_JOKER_1_23 = 282,
SL_JOKER_1_24 = 283,
SL_JOKER_1_25 = 284,
SL_JOKER_1_26 = 285,
SL_JOKER_1_27 = 286,
SL_CHILLPP_201 = 201,
SL_CHILLPP_232 = 232,
SL_CHILLPP_233 = 233,
};
byte SlReadByte();
void SlWriteByte(byte b);
int SlReadUint16();
uint32 SlReadUint32();
uint64 SlReadUint64();
void SlWriteUint16(uint16 v);
void SlWriteUint32(uint32 v);
void SlWriteUint64(uint64 v);
void SlSkipBytes(size_t length);
size_t SlGetBytesRead();
size_t SlGetBytesWritten();
void NORETURN SlError(StringID string, const char *extra_msg = nullptr, bool already_malloced = false);
void NORETURN SlErrorCorrupt(const char *msg, bool already_malloced = false);
void NORETURN CDECL SlErrorCorruptFmt(const char *format, ...) WARN_FORMAT(1, 2);
bool SaveLoadFileTypeIsScenario();
#endif

@ -0,0 +1,135 @@
/*
* This file is part of OpenTTD.
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file saveload_common.h Common functions/types for saving and loading games. */
#ifndef SAVELOAD_TYPES_H
#define SAVELOAD_TYPES_H
#include "saveload_common.h"
#include "extended_ver_sl.h"
/**
* VarTypes is the general bitmasked magic type that tells us
* certain characteristics about the variable it refers to. For example
* SLE_FILE_* gives the size(type) as it would be in the savegame and
* SLE_VAR_* the size(type) as it is in memory during runtime. These are
* the first 8 bits (0-3 SLE_FILE, 4-7 SLE_VAR).
* Bits 8-15 are reserved for various flags as explained below
*/
enum VarTypes {
/* 4 bits allocated a maximum of 16 types for NumberType */
SLE_FILE_I8 = 0,
SLE_FILE_U8 = 1,
SLE_FILE_I16 = 2,
SLE_FILE_U16 = 3,
SLE_FILE_I32 = 4,
SLE_FILE_U32 = 5,
SLE_FILE_I64 = 6,
SLE_FILE_U64 = 7,
SLE_FILE_STRINGID = 8, ///< StringID offset into strings-array
SLE_FILE_STRING = 9,
SLE_FILE_VEHORDERID = 10,
/* 5 more possible file-primitives */
/* 4 bits allocated a maximum of 16 types for NumberType */
SLE_VAR_BL = 0 << 4,
SLE_VAR_I8 = 1 << 4,
SLE_VAR_U8 = 2 << 4,
SLE_VAR_I16 = 3 << 4,
SLE_VAR_U16 = 4 << 4,
SLE_VAR_I32 = 5 << 4,
SLE_VAR_U32 = 6 << 4,
SLE_VAR_I64 = 7 << 4,
SLE_VAR_U64 = 8 << 4,
SLE_VAR_NULL = 9 << 4, ///< useful to write zeros in savegame.
SLE_VAR_STRB = 10 << 4, ///< string (with pre-allocated buffer)
SLE_VAR_STR = 12 << 4, ///< string pointer
SLE_VAR_STRQ = 13 << 4, ///< string pointer enclosed in quotes
SLE_VAR_NAME = 14 << 4, ///< old custom name to be converted to a std::string
SLE_VAR_CNAME = 15 << 4, ///< old custom name to be converted to a char pointer
/* 0 more possible memory-primitives */
/* Shortcut values */
SLE_VAR_CHAR = SLE_VAR_I8,
/* Default combinations of variables. As savegames change, so can variables
* and thus it is possible that the saved value and internal size do not
* match and you need to specify custom combo. The defaults are listed here */
SLE_BOOL = SLE_FILE_I8 | SLE_VAR_BL,
SLE_INT8 = SLE_FILE_I8 | SLE_VAR_I8,
SLE_UINT8 = SLE_FILE_U8 | SLE_VAR_U8,
SLE_INT16 = SLE_FILE_I16 | SLE_VAR_I16,
SLE_UINT16 = SLE_FILE_U16 | SLE_VAR_U16,
SLE_INT32 = SLE_FILE_I32 | SLE_VAR_I32,
SLE_UINT32 = SLE_FILE_U32 | SLE_VAR_U32,
SLE_INT64 = SLE_FILE_I64 | SLE_VAR_I64,
SLE_UINT64 = SLE_FILE_U64 | SLE_VAR_U64,
SLE_CHAR = SLE_FILE_I8 | SLE_VAR_CHAR,
SLE_STRINGID = SLE_FILE_STRINGID | SLE_VAR_U32,
SLE_STRINGBUF = SLE_FILE_STRING | SLE_VAR_STRB,
SLE_STRING = SLE_FILE_STRING | SLE_VAR_STR,
SLE_STRINGQUOTE = SLE_FILE_STRING | SLE_VAR_STRQ,
SLE_NAME = SLE_FILE_STRINGID | SLE_VAR_NAME,
SLE_CNAME = SLE_FILE_STRINGID | SLE_VAR_CNAME,
SLE_VEHORDERID = SLE_FILE_VEHORDERID | SLE_VAR_U16,
/* Shortcut values */
SLE_UINT = SLE_UINT32,
SLE_INT = SLE_INT32,
SLE_STRB = SLE_STRINGBUF,
SLE_STR = SLE_STRING,
SLE_STRQ = SLE_STRINGQUOTE,
/* 8 bits allocated for a maximum of 8 flags
* Flags directing saving/loading of a variable */
SLF_ALLOW_CONTROL = 1 << 8, ///< Allow control codes in the strings.
SLF_ALLOW_NEWLINE = 1 << 9, ///< Allow new lines in the strings.
};
typedef uint32 VarType;
/** Type of data saved. */
enum SaveLoadTypes {
SL_VAR = 0, ///< Save/load a variable.
SL_REF = 1, ///< Save/load a reference.
SL_ARR = 2, ///< Save/load a fixed-size array of #SL_VAR elements.
SL_STR = 3, ///< Save/load a string.
SL_REFLIST = 4, ///< Save/load a list of #SL_REF elements.
SL_DEQUE = 5, ///< Save/load a deque of #SL_VAR elements.
SL_VEC = 6, ///< Save/load a vector of #SL_REF elements.
SL_STDSTR = 7, ///< Save/load a std::string.
/* non-normal save-load types */
SL_WRITEBYTE = 8,
SL_VEH_INCLUDE = 9,
SL_ST_INCLUDE = 10,
SL_PTRDEQ = 13, ///< Save/load a deque of #SL_REF elements.
SL_VARVEC = 14, ///< Save/load a primitive type vector.
};
typedef byte SaveLoadType; ///< Save/load type. @see SaveLoadTypes
/** SaveLoad type struct. Do NOT use this directly but use the SLE_ macros defined just below! */
struct SaveLoad {
bool global; ///< should we load a global variable or a non-global one
SaveLoadType cmd; ///< the action to take with the saved/loaded type, All types need different action
VarType conv; ///< type of the variable to be saved, int
uint16 length; ///< (conditional) length of the variable (eg. arrays) (max array size is 65536 elements)
SaveLoadVersion version_from; ///< save/load the variable starting from this savegame version
SaveLoadVersion version_to; ///< save/load the variable until this savegame version
/* NOTE: This element either denotes the address of the variable for a global
* variable, or the offset within a struct which is then bound to a variable
* during runtime. Decision on which one to use is controlled by the function
* that is called to save it. address: global=true, offset: global=false */
void *address; ///< address of variable OR offset of variable in the struct (max offset is 65536)
size_t size; ///< the sizeof size.
SlXvFeatureTest ext_feature_test; ///< extended feature test
};
#endif

@ -0,0 +1,38 @@
add_subdirectory(compat)
add_files(
ai_sl.cpp
airport_sl.cpp
animated_tile_sl.cpp
autoreplace_sl.cpp
cargomonitor_sl.cpp
cargopacket_sl.cpp
cheat_sl.cpp
company_sl.cpp
depot_sl.cpp
economy_sl.cpp
engine_sl.cpp
game_sl.cpp
gamelog_sl.cpp
goal_sl.cpp
group_sl.cpp
industry_sl.cpp
labelmaps_sl.cpp
linkgraph_sl.cpp
map_sl.cpp
misc_sl.cpp
newgrf_sl.cpp
newgrf_sl.h
object_sl.cpp
order_sl.cpp
saveload.cpp
saveload.h
settings_sl.cpp
signs_sl.cpp
station_sl.cpp
storage_sl.cpp
story_sl.cpp
subsidy_sl.cpp
town_sl.cpp
vehicle_sl.cpp
)

@ -0,0 +1,143 @@
/*
* This file is part of OpenTTD.
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file ai_sl.cpp Handles the saveload part of the AIs */
#include "../../stdafx.h"
#include "../../debug.h"
#include "saveload.h"
#include "compat/ai_sl_compat.h"
#include "../../company_base.h"
#include "../../string_func.h"
#include "../../ai/ai.hpp"
#include "../../ai/ai_config.hpp"
#include "../../network/network.h"
#include "../../ai/ai_instance.hpp"
#include "../../safeguards.h"
namespace upstream_sl {
static std::string _ai_saveload_name;
static int _ai_saveload_version;
static std::string _ai_saveload_settings;
static bool _ai_saveload_is_random;
static const SaveLoad _ai_company_desc[] = {
SLEG_SSTR("name", _ai_saveload_name, SLE_STR),
SLEG_SSTR("settings", _ai_saveload_settings, SLE_STR),
SLEG_CONDVAR("version", _ai_saveload_version, SLE_UINT32, SLV_108, SL_MAX_VERSION),
SLEG_CONDVAR("is_random", _ai_saveload_is_random, SLE_BOOL, SLV_136, SL_MAX_VERSION),
};
static void SaveReal_AIPL(int *index_ptr)
{
CompanyID index = (CompanyID)*index_ptr;
AIConfig *config = AIConfig::GetConfig(index);
if (config->HasScript()) {
_ai_saveload_name = config->GetName();
_ai_saveload_version = config->GetVersion();
} else {
/* No AI is configured for this so store an empty string as name. */
_ai_saveload_name.clear();
_ai_saveload_version = -1;
}
_ai_saveload_is_random = config->IsRandom();
_ai_saveload_settings = config->SettingsToString();
SlObject(nullptr, _ai_company_desc);
/* If the AI was active, store its data too */
if (Company::IsValidAiID(index)) AI::Save(index);
}
struct AIPLChunkHandler : ChunkHandler {
AIPLChunkHandler() : ChunkHandler('AIPL', CH_TABLE) {}
void Load() const override
{
const std::vector<SaveLoad> slt = SlCompatTableHeader(_ai_company_desc, _ai_company_sl_compat);
/* Free all current data */
for (CompanyID c = COMPANY_FIRST; c < MAX_COMPANIES; c++) {
AIConfig::GetConfig(c, AIConfig::SSS_FORCE_GAME)->Change(nullptr);
}
CompanyID index;
while ((index = (CompanyID)SlIterateArray()) != (CompanyID)-1) {
if (index >= MAX_COMPANIES) SlErrorCorrupt("Too many AI configs");
_ai_saveload_is_random = false;
_ai_saveload_version = -1;
SlObject(nullptr, slt);
if (_networking && !_network_server) {
if (Company::IsValidAiID(index)) AIInstance::LoadEmpty();
continue;
}
AIConfig *config = AIConfig::GetConfig(index, AIConfig::SSS_FORCE_GAME);
if (_ai_saveload_name.empty()) {
/* A random AI. */
config->Change(nullptr, -1, false, true);
} else {
config->Change(_ai_saveload_name.c_str(), _ai_saveload_version, false, _ai_saveload_is_random);
if (!config->HasScript()) {
/* No version of the AI available that can load the data. Try to load the
* latest version of the AI instead. */
config->Change(_ai_saveload_name.c_str(), -1, false, _ai_saveload_is_random);
if (!config->HasScript()) {
if (_ai_saveload_name.compare("%_dummy") != 0) {
DEBUG(script, 0, "The savegame has an AI by the name '%s', version %u which is no longer available.", _ai_saveload_name.c_str(), _ai_saveload_version);
DEBUG(script, 0, "A random other AI will be loaded in its place.");
} else {
DEBUG(script, 0, "The savegame had no AIs available at the time of saving.");
DEBUG(script, 0, "A random available AI will be loaded now.");
}
} else {
DEBUG(script, 0, "The savegame has an AI by the name '%s', version %u which is no longer available.", _ai_saveload_name.c_str(), _ai_saveload_version);
DEBUG(script, 0, "The latest version of that AI has been loaded instead, but it'll not get the savegame data as it's incompatible.");
}
/* Make sure the AI doesn't get the saveload data, as it was not the
* writer of the saveload data in the first place */
_ai_saveload_version = -1;
}
}
config->StringToSettings(_ai_saveload_settings);
/* Start the AI directly if it was active in the savegame */
if (Company::IsValidAiID(index)) {
AI::StartNew(index, false);
AI::Load(index, _ai_saveload_version);
}
}
}
void Save() const override
{
SlTableHeader(_ai_company_desc);
for (int i = COMPANY_FIRST; i < MAX_COMPANIES; i++) {
SlSetArrayIndex(i);
SlAutolength((AutolengthProc *)SaveReal_AIPL, &i);
}
}
};
static const AIPLChunkHandler AIPL;
static const ChunkHandlerRef ai_chunk_handlers[] = {
AIPL,
};
extern const ChunkHandlerTable _ai_chunk_handlers(ai_chunk_handlers);
}

@ -0,0 +1,36 @@
/*
* This file is part of OpenTTD.
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file airport_sl.cpp Code handling saving and loading airport ids */
#include "../../stdafx.h"
#include "saveload.h"
#include "newgrf_sl.h"
#include "../../safeguards.h"
namespace upstream_sl {
struct APIDChunkHandler : NewGRFMappingChunkHandler {
APIDChunkHandler() : NewGRFMappingChunkHandler('APID', _airport_mngr) {}
};
struct ATIDChunkHandler : NewGRFMappingChunkHandler {
ATIDChunkHandler() : NewGRFMappingChunkHandler('ATID', _airporttile_mngr) {}
};
static const ATIDChunkHandler ATID;
static const APIDChunkHandler APID;
static const ChunkHandlerRef airport_chunk_handlers[] = {
ATID,
APID,
};
extern const ChunkHandlerTable _airport_chunk_handlers(airport_chunk_handlers);
}

@ -0,0 +1,84 @@
/*
* This file is part of OpenTTD.
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file animated_tile_sl.cpp Code handling saving and loading of animated tiles */
#include "../../stdafx.h"
#include "saveload.h"
#include "compat/animated_tile_sl_compat.h"
#include "../../tile_type.h"
#include "../../animated_tile.h"
#include "../../core/alloc_func.hpp"
#include "../../core/smallvec_type.hpp"
#include "../../safeguards.h"
namespace upstream_sl {
static std::vector <TileIndex> _tmp_animated_tiles;
static const SaveLoad _animated_tile_desc[] = {
SLEG_VECTOR("tiles", _tmp_animated_tiles, SLE_UINT32),
};
struct ANITChunkHandler : ChunkHandler {
ANITChunkHandler() : ChunkHandler('ANIT', CH_TABLE) {}
void Save() const override
{
// removed
NOT_REACHED();
}
void Load() const override
{
/* Before version 80 we did NOT have a variable length animated tile table */
if (IsSavegameVersionBefore(SLV_80)) {
/* In pre version 6, we has 16bit per tile, now we have 32bit per tile, convert it ;) */
TileIndex anim_list[256];
SlCopy(anim_list, 256, IsSavegameVersionBefore(SLV_6) ? (SLE_FILE_U16 | SLE_VAR_U32) : SLE_UINT32);
for (int i = 0; i < 256; i++) {
if (anim_list[i] == 0) break;
_animated_tiles[anim_list[i]] = {};
}
return;
}
if (IsSavegameVersionBefore(SLV_RIFF_TO_ARRAY)) {
size_t count = SlGetFieldLength() / sizeof(uint32);
_animated_tiles.clear();
for (uint i = 0; i < count; i++) {
_animated_tiles[SlReadUint32()] = {};
}
return;
}
const std::vector<SaveLoad> slt = SlCompatTableHeader(_animated_tile_desc, _animated_tile_sl_compat);
if (SlIterateArray() == -1) return;
SlGlobList(slt);
if (SlIterateArray() != -1) SlErrorCorrupt("Too many ANIT entries");
for (TileIndex t : _tmp_animated_tiles) {
_animated_tiles[t] = {};
}
_tmp_animated_tiles.clear();
}
};
static const ANITChunkHandler ANIT;
static const ChunkHandlerRef animated_tile_chunk_handlers[] = {
ANIT,
};
extern const ChunkHandlerTable _animated_tile_chunk_handlers(animated_tile_chunk_handlers);
}

@ -0,0 +1,77 @@
/*
* This file is part of OpenTTD.
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file autoreplace_sl.cpp Code handling saving and loading of autoreplace rules */
#include "../../stdafx.h"
#include "saveload.h"
#include "compat/autoreplace_sl_compat.h"
#include "../../autoreplace_base.h"
#include "../../safeguards.h"
namespace upstream_sl {
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, SLV_60, SL_MAX_VERSION),
SLE_CONDVAR(EngineRenew, replace_when_old, SLE_BOOL, SLV_175, SL_MAX_VERSION),
};
struct ERNWChunkHandler : ChunkHandler {
ERNWChunkHandler() : ChunkHandler('ERNW', CH_TABLE) {}
void Save() const override
{
SlTableHeader(_engine_renew_desc);
for (EngineRenew *er : EngineRenew::Iterate()) {
SlSetArrayIndex(er->index);
SlObject(er, _engine_renew_desc);
}
}
void Load() const override
{
const std::vector<SaveLoad> slt = SlCompatTableHeader(_engine_renew_desc, _engine_renew_sl_compat);
int index;
while ((index = SlIterateArray()) != -1) {
EngineRenew *er = new (index) EngineRenew();
SlObject(er, slt);
/* Advanced vehicle lists, ungrouped vehicles got added */
if (IsSavegameVersionBefore(SLV_60)) {
er->group_id = ALL_GROUP;
} else if (IsSavegameVersionBefore(SLV_71)) {
if (er->group_id == DEFAULT_GROUP) er->group_id = ALL_GROUP;
}
}
}
void FixPointers() const override
{
for (EngineRenew *er : EngineRenew::Iterate()) {
SlObject(er, _engine_renew_desc);
}
}
};
static const ERNWChunkHandler ERNW;
static const ChunkHandlerRef autoreplace_chunk_handlers[] = {
ERNW,
};
extern const ChunkHandlerTable _autoreplace_chunk_handlers(autoreplace_chunk_handlers);
}

@ -0,0 +1,146 @@
/*
* This file is part of OpenTTD.
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file cargomonitor_sl.cpp Code handling saving and loading of Cargo monitoring. */
#include "../../stdafx.h"
#include "saveload.h"
#include "compat/cargomonitor_sl_compat.h"
#include "../../cargomonitor.h"
#include "../../safeguards.h"
namespace upstream_sl {
/** Temporary storage of cargo monitoring data for loading or saving it. */
struct TempStorage {
CargoMonitorID number;
uint32 amount;
};
/** Description of the #TempStorage structure for the purpose of load and save. */
static const SaveLoad _cargomonitor_pair_desc[] = {
SLE_VAR(TempStorage, number, SLE_UINT32),
SLE_VAR(TempStorage, amount, SLE_UINT32),
};
static CargoMonitorID FixupCargoMonitor(CargoMonitorID number)
{
/* Between SLV_EXTEND_CARGOTYPES and SLV_FIX_CARGO_MONITOR, the
* CargoMonitorID structure had insufficient packing for more
* than 32 cargo types. Here we have to shuffle bits to account
* for the change.
* Company moved from bits 24-31 to 25-28.
* Cargo type increased from bits 19-23 to 19-24.
*/
SB(number, 25, 4, GB(number, 24, 4));
SB(number, 29, 3, 0);
ClrBit(number, 24);
return number;
}
/** #_cargo_deliveries monitoring map. */
struct CMDLChunkHandler : ChunkHandler {
CMDLChunkHandler() : ChunkHandler('CMDL', CH_TABLE) {}
void Save() const override
{
SlTableHeader(_cargomonitor_pair_desc);
TempStorage storage;
int i = 0;
CargoMonitorMap::const_iterator iter = _cargo_deliveries.begin();
while (iter != _cargo_deliveries.end()) {
storage.number = iter->first;
storage.amount = iter->second;
SlSetArrayIndex(i);
SlObject(&storage, _cargomonitor_pair_desc);
i++;
iter++;
}
}
void Load() const override
{
const std::vector<SaveLoad> slt = SlCompatTableHeader(_cargomonitor_pair_desc, _cargomonitor_pair_sl_compat);
TempStorage storage;
bool fix = IsSavegameVersionBefore(SLV_FIX_CARGO_MONITOR);
ClearCargoDeliveryMonitoring();
for (;;) {
if (SlIterateArray() < 0) break;
SlObject(&storage, slt);
if (fix) storage.number = FixupCargoMonitor(storage.number);
std::pair<CargoMonitorID, uint32> p(storage.number, storage.amount);
_cargo_deliveries.insert(p);
}
}
};
/** #_cargo_pickups monitoring map. */
struct CMPUChunkHandler : ChunkHandler {
CMPUChunkHandler() : ChunkHandler('CMPU', CH_TABLE) {}
void Save() const override
{
SlTableHeader(_cargomonitor_pair_desc);
TempStorage storage;
int i = 0;
CargoMonitorMap::const_iterator iter = _cargo_pickups.begin();
while (iter != _cargo_pickups.end()) {
storage.number = iter->first;
storage.amount = iter->second;
SlSetArrayIndex(i);
SlObject(&storage, _cargomonitor_pair_desc);
i++;
iter++;
}
}
void Load() const override
{
const std::vector<SaveLoad> slt = SlCompatTableHeader(_cargomonitor_pair_desc, _cargomonitor_pair_sl_compat);
TempStorage storage;
bool fix = IsSavegameVersionBefore(SLV_FIX_CARGO_MONITOR);
ClearCargoPickupMonitoring();
for (;;) {
if (SlIterateArray() < 0) break;
SlObject(&storage, slt);
if (fix) storage.number = FixupCargoMonitor(storage.number);
std::pair<CargoMonitorID, uint32> p(storage.number, storage.amount);
_cargo_pickups.insert(p);
}
}
};
/** Chunk definition of the cargomonitoring maps. */
static const CMDLChunkHandler CMDL;
static const CMPUChunkHandler CMPU;
static const ChunkHandlerRef cargomonitor_chunk_handlers[] = {
CMDL,
CMPU,
};
extern const ChunkHandlerTable _cargomonitor_chunk_handlers(cargomonitor_chunk_handlers);
}

@ -0,0 +1,75 @@
/*
* This file is part of OpenTTD.
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file cargopacket_sl.cpp Code handling saving and loading of cargo packets */
#include "../../stdafx.h"
#include "saveload.h"
#include "compat/cargopacket_sl_compat.h"
#include "../../vehicle_base.h"
#include "../../station_base.h"
#include "../../safeguards.h"
namespace upstream_sl {
/**
* Wrapper function to get the CargoPacket's internal structure while
* some of the variables itself are private.
* @return the saveload description for CargoPackets.
*/
SaveLoadTable GetCargoPacketDesc()
{
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_CONDVAR(CargoPacket, source_type, SLE_UINT8, SLV_125, SL_MAX_VERSION),
SLE_CONDVAR(CargoPacket, source_id, SLE_UINT16, SLV_125, SL_MAX_VERSION),
};
return _cargopacket_desc;
}
struct CAPAChunkHandler : ChunkHandler {
CAPAChunkHandler() : ChunkHandler('CAPA', CH_TABLE) {}
void Save() const override
{
SlTableHeader(GetCargoPacketDesc());
for (CargoPacket *cp : CargoPacket::Iterate()) {
SlSetArrayIndex(cp->index);
SlObject(cp, GetCargoPacketDesc());
}
}
void Load() const override
{
const std::vector<SaveLoad> slt = SlCompatTableHeader(GetCargoPacketDesc(), _cargopacket_sl_compat);
int index;
while ((index = SlIterateArray()) != -1) {
CargoPacket *cp = new (index) CargoPacket();
SlObject(cp, slt);
}
}
};
static const CAPAChunkHandler CAPA;
static const ChunkHandlerRef cargopacket_chunk_handlers[] = {
CAPA,
};
extern const ChunkHandlerTable _cargopacket_chunk_handlers(cargopacket_chunk_handlers);
}

@ -0,0 +1,86 @@
/*
* This file is part of OpenTTD.
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file cheat_sl.cpp Code handling saving and loading of cheats */
#include "../../stdafx.h"
#include "saveload.h"
#include "compat/cheat_sl_compat.h"
#include "../../cheat_type.h"
#include "../../safeguards.h"
namespace upstream_sl {
static const SaveLoad _cheats_desc[] = {
SLE_VAR(Cheats, magic_bulldozer.been_used, SLE_BOOL),
SLE_VAR(Cheats, magic_bulldozer.value, SLE_BOOL),
SLE_VAR(Cheats, switch_company.been_used, SLE_BOOL),
SLE_VAR(Cheats, switch_company.value, SLE_BOOL),
SLE_VAR(Cheats, money.been_used, SLE_BOOL),
SLE_VAR(Cheats, money.value, SLE_BOOL),
SLE_VAR(Cheats, crossing_tunnels.been_used, SLE_BOOL),
SLE_VAR(Cheats, crossing_tunnels.value, SLE_BOOL),
SLE_VAR(Cheats, no_jetcrash.been_used, SLE_BOOL),
SLE_VAR(Cheats, no_jetcrash.value, SLE_BOOL),
SLE_VAR(Cheats, change_date.been_used, SLE_BOOL),
SLE_VAR(Cheats, change_date.value, SLE_BOOL),
SLE_VAR(Cheats, setup_prod.been_used, SLE_BOOL),
SLE_VAR(Cheats, setup_prod.value, SLE_BOOL),
SLE_VAR(Cheats, edit_max_hl.been_used, SLE_BOOL),
SLE_VAR(Cheats, edit_max_hl.value, SLE_BOOL),
};
struct CHTSChunkHandler : ChunkHandler {
CHTSChunkHandler() : ChunkHandler('CHTS', CH_TABLE) {}
void Save() const override
{
SlTableHeader(_cheats_desc);
SlSetArrayIndex(0);
SlObject(&_cheats, _cheats_desc);
}
void Load() const override
{
std::vector<SaveLoad> slt = SlCompatTableHeader(_cheats_desc, _cheats_sl_compat);
if (IsSavegameVersionBefore(SLV_TABLE_CHUNKS)) {
size_t count = SlGetFieldLength();
std::vector<SaveLoad> oslt;
/* Cheats were added over the years without a savegame bump. They are
* stored as 2 SLE_BOOLs per entry. "count" indicates how many SLE_BOOLs
* are stored for this savegame. So read only "count" SLE_BOOLs (and in
* result "count / 2" cheats). */
for (auto &sld : slt) {
count--;
oslt.push_back(sld);
if (count == 0) break;
}
slt = oslt;
}
if (!IsSavegameVersionBefore(SLV_RIFF_TO_ARRAY) && SlIterateArray() == -1) return;
SlObject(&_cheats, slt);
if (!IsSavegameVersionBefore(SLV_RIFF_TO_ARRAY) && SlIterateArray() != -1) SlErrorCorrupt("Too many CHTS entries");
}
};
static const CHTSChunkHandler CHTS;
static const ChunkHandlerRef cheat_chunk_handlers[] = {
CHTS,
};
extern const ChunkHandlerTable _cheat_chunk_handlers(cheat_chunk_handlers);
}

@ -0,0 +1,363 @@
/*
* This file is part of OpenTTD.
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file company_sl.cpp Code handling saving and loading of company data */
#include "../../stdafx.h"
#include "saveload.h"
#include "compat/company_sl_compat.h"
#include "../../company_func.h"
#include "../../company_manager_face.h"
#include "../../fios.h"
#include "../../tunnelbridge_map.h"
#include "../../tunnelbridge.h"
#include "../../station_base.h"
#include "../../strings_func.h"
#include "table/strings.h"
#include "../../safeguards.h"
void SetDefaultCompanySettings(CompanyID cid);
namespace upstream_sl {
/* We do need to read this single value, as the bigger it gets, the more data is stored */
struct CompanyOldAI {
uint8 num_build_rec;
};
class SlCompanyOldAIBuildRec : public DefaultSaveLoadHandler<SlCompanyOldAIBuildRec, CompanyOldAI> {
public:
inline static const SaveLoad description[] = {{}}; // Needed to keep DefaultSaveLoadHandler happy.
inline const static SaveLoadCompatTable compat_description = _company_old_ai_buildrec_compat;
SaveLoadTable GetDescription() const override { return {}; }
void Load(CompanyOldAI *old_ai) const override
{
for (int i = 0; i != old_ai->num_build_rec; i++) {
SlObject(nullptr, this->GetLoadDescription());
}
}
void LoadCheck(CompanyOldAI *old_ai) const override { this->Load(old_ai); }
};
class SlCompanyOldAI : public DefaultSaveLoadHandler<SlCompanyOldAI, CompanyProperties> {
public:
inline static const SaveLoad description[] = {
SLE_CONDVAR(CompanyOldAI, num_build_rec, SLE_UINT8, SL_MIN_VERSION, SLV_107),
SLEG_STRUCTLIST("buildrec", SlCompanyOldAIBuildRec),
};
inline const static SaveLoadCompatTable compat_description = _company_old_ai_compat;
void Load(CompanyProperties *c) const override
{
if (!c->is_ai) return;
CompanyOldAI old_ai;
SlObject(&old_ai, this->GetLoadDescription());
}
void LoadCheck(CompanyProperties *c) const override { this->Load(c); }
};
class SlCompanySettings : public DefaultSaveLoadHandler<SlCompanySettings, CompanyProperties> {
public:
inline static const SaveLoad description[] = {
/* Engine renewal settings */
SLE_CONDREF(CompanyProperties, engine_renew_list, REF_ENGINE_RENEWS, SLV_19, SL_MAX_VERSION),
SLE_CONDVAR(CompanyProperties, settings.engine_renew, SLE_BOOL, SLV_16, SL_MAX_VERSION),
SLE_CONDVAR(CompanyProperties, settings.engine_renew_months, SLE_INT16, SLV_16, SL_MAX_VERSION),
SLE_CONDVAR(CompanyProperties, settings.engine_renew_money, SLE_UINT32, SLV_16, SL_MAX_VERSION),
SLE_CONDVAR(CompanyProperties, settings.renew_keep_length, SLE_BOOL, SLV_2, SL_MAX_VERSION),
/* Default vehicle settings */
SLE_CONDVAR(CompanyProperties, settings.vehicle.servint_ispercent, SLE_BOOL, SLV_120, SL_MAX_VERSION),
SLE_CONDVAR(CompanyProperties, settings.vehicle.servint_trains, SLE_UINT16, SLV_120, SL_MAX_VERSION),
SLE_CONDVAR(CompanyProperties, settings.vehicle.servint_roadveh, SLE_UINT16, SLV_120, SL_MAX_VERSION),
SLE_CONDVAR(CompanyProperties, settings.vehicle.servint_aircraft, SLE_UINT16, SLV_120, SL_MAX_VERSION),
SLE_CONDVAR(CompanyProperties, settings.vehicle.servint_ships, SLE_UINT16, SLV_120, SL_MAX_VERSION),
};
inline const static SaveLoadCompatTable compat_description = _company_settings_compat;
void Save(CompanyProperties *c) const override
{
SlObject(c, this->GetDescription());
}
void Load(CompanyProperties *c) const override
{
SlObject(c, this->GetLoadDescription());
}
void FixPointers(CompanyProperties *c) const override
{
SlObject(c, this->GetDescription());
}
void LoadCheck(CompanyProperties *c) const override { this->Load(c); }
};
class SlCompanyEconomy : public DefaultSaveLoadHandler<SlCompanyEconomy, CompanyProperties> {
public:
inline static const SaveLoad description[] = {
SLE_CONDVAR(CompanyEconomyEntry, income, SLE_FILE_I32 | SLE_VAR_I64, SL_MIN_VERSION, SLV_2),
SLE_CONDVAR(CompanyEconomyEntry, income, SLE_INT64, SLV_2, SL_MAX_VERSION),
SLE_CONDVAR(CompanyEconomyEntry, expenses, SLE_FILE_I32 | SLE_VAR_I64, SL_MIN_VERSION, SLV_2),
SLE_CONDVAR(CompanyEconomyEntry, expenses, SLE_INT64, SLV_2, SL_MAX_VERSION),
SLE_CONDVAR(CompanyEconomyEntry, company_value, SLE_FILE_I32 | SLE_VAR_I64, SL_MIN_VERSION, SLV_2),
SLE_CONDVAR(CompanyEconomyEntry, company_value, SLE_INT64, SLV_2, SL_MAX_VERSION),
SLE_CONDVAR(CompanyEconomyEntry, delivered_cargo[NUM_CARGO - 1], SLE_INT32, SL_MIN_VERSION, SLV_170),
SLE_CONDARR(CompanyEconomyEntry, delivered_cargo, SLE_UINT32, 32, SLV_170, SLV_EXTEND_CARGOTYPES),
SLE_CONDARR(CompanyEconomyEntry, delivered_cargo, SLE_UINT32, NUM_CARGO, SLV_EXTEND_CARGOTYPES, SL_MAX_VERSION),
SLE_VAR(CompanyEconomyEntry, performance_history, SLE_INT32),
};
inline const static SaveLoadCompatTable compat_description = _company_economy_compat;
void Save(CompanyProperties *c) const override
{
SlObject(&c->cur_economy, this->GetDescription());
}
void Load(CompanyProperties *c) const override
{
SlObject(&c->cur_economy, this->GetLoadDescription());
}
void FixPointers(CompanyProperties *c) const override
{
SlObject(&c->cur_economy, this->GetDescription());
}
void LoadCheck(CompanyProperties *c) const override { this->Load(c); }
};
class SlCompanyOldEconomy : public SlCompanyEconomy {
public:
void Save(CompanyProperties *c) const override
{
SlSetStructListLength(c->num_valid_stat_ent);
for (int i = 0; i < c->num_valid_stat_ent; i++) {
SlObject(&c->old_economy[i], this->GetDescription());
}
}
void Load(CompanyProperties *c) const override
{
if (!IsSavegameVersionBefore(SLV_SAVELOAD_LIST_LENGTH)) {
c->num_valid_stat_ent = (uint8)SlGetStructListLength(UINT8_MAX);
}
if (c->num_valid_stat_ent > lengthof(c->old_economy)) SlErrorCorrupt("Too many old economy entries");
for (int i = 0; i < c->num_valid_stat_ent; i++) {
SlObject(&c->old_economy[i], this->GetLoadDescription());
}
}
void LoadCheck(CompanyProperties *c) const override { this->Load(c); }
};
class SlCompanyLiveries : public DefaultSaveLoadHandler<SlCompanyLiveries, CompanyProperties> {
public:
inline static const SaveLoad description[] = {
SLE_CONDVAR(Livery, in_use, SLE_UINT8, SLV_34, SL_MAX_VERSION),
SLE_CONDVAR(Livery, colour1, SLE_UINT8, SLV_34, SL_MAX_VERSION),
SLE_CONDVAR(Livery, colour2, SLE_UINT8, SLV_34, SL_MAX_VERSION),
};
inline const static SaveLoadCompatTable compat_description = _company_liveries_compat;
/**
* Get the number of liveries used by this savegame version.
* @return The number of liveries used by this savegame version.
*/
size_t GetNumLiveries() const
{
if (IsSavegameVersionBefore(SLV_63)) return LS_END - 4;
if (IsSavegameVersionBefore(SLV_85)) return LS_END - 2;
if (IsSavegameVersionBefore(SLV_SAVELOAD_LIST_LENGTH)) return LS_END;
/* Read from the savegame how long the list is. */
return SlGetStructListLength(LS_END);
}
void Save(CompanyProperties *c) const override
{
SlSetStructListLength(LS_END);
for (int i = 0; i < LS_END; i++) {
SlObject(&c->livery[i], this->GetDescription());
}
}
void Load(CompanyProperties *c) const override
{
size_t num_liveries = this->GetNumLiveries();
bool update_in_use = IsSavegameVersionBefore(SLV_GROUP_LIVERIES);
for (size_t i = 0; i < num_liveries; i++) {
SlObject(&c->livery[i], this->GetLoadDescription());
if (update_in_use && i != LS_DEFAULT) {
if (c->livery[i].in_use == 0) {
c->livery[i].colour1 = c->livery[LS_DEFAULT].colour1;
c->livery[i].colour2 = c->livery[LS_DEFAULT].colour2;
} else {
c->livery[i].in_use = 3;
}
}
}
if (IsSavegameVersionBefore(SLV_85)) {
/* 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 (IsSavegameVersionBefore(SLV_63)) {
/* 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];
}
}
void LoadCheck(CompanyProperties *c) const override { this->Load(c); }
};
/* Save/load of companies */
static const SaveLoad _company_desc[] = {
SLE_VAR(CompanyProperties, name_2, SLE_UINT32),
SLE_VAR(CompanyProperties, name_1, SLE_STRINGID),
SLE_CONDSSTR(CompanyProperties, name, SLE_STR | SLF_ALLOW_CONTROL, SLV_84, SL_MAX_VERSION),
SLE_VAR(CompanyProperties, president_name_1, SLE_STRINGID),
SLE_VAR(CompanyProperties, president_name_2, SLE_UINT32),
SLE_CONDSSTR(CompanyProperties, president_name, SLE_STR | SLF_ALLOW_CONTROL, SLV_84, SL_MAX_VERSION),
SLE_VAR(CompanyProperties, face, SLE_UINT32),
/* money was changed to a 64 bit field in savegame version 1. */
SLE_CONDVAR(CompanyProperties, money, SLE_VAR_I64 | SLE_FILE_I32, SL_MIN_VERSION, SLV_1),
SLE_CONDVAR(CompanyProperties, money, SLE_INT64, SLV_1, SL_MAX_VERSION),
SLE_CONDVAR(CompanyProperties, current_loan, SLE_VAR_I64 | SLE_FILE_I32, SL_MIN_VERSION, SLV_65),
SLE_CONDVAR(CompanyProperties, current_loan, SLE_INT64, SLV_65, SL_MAX_VERSION),
SLE_VAR(CompanyProperties, colour, SLE_UINT8),
SLE_VAR(CompanyProperties, money_fraction, SLE_UINT8),
SLE_VAR(CompanyProperties, block_preview, SLE_UINT8),
SLE_CONDVAR(CompanyProperties, location_of_HQ, SLE_FILE_U16 | SLE_VAR_U32, SL_MIN_VERSION, SLV_6),
SLE_CONDVAR(CompanyProperties, location_of_HQ, SLE_UINT32, SLV_6, SL_MAX_VERSION),
SLE_CONDVAR(CompanyProperties, last_build_coordinate, SLE_FILE_U16 | SLE_VAR_U32, SL_MIN_VERSION, SLV_6),
SLE_CONDVAR(CompanyProperties, last_build_coordinate, SLE_UINT32, SLV_6, SL_MAX_VERSION),
SLE_CONDVAR(CompanyProperties, inaugurated_year, SLE_FILE_U8 | SLE_VAR_I32, SL_MIN_VERSION, SLV_31),
SLE_CONDVAR(CompanyProperties, inaugurated_year, SLE_INT32, SLV_31, SL_MAX_VERSION),
SLE_ARR(CompanyProperties, share_owners, SLE_UINT8, 4),
SLE_CONDVAR(CompanyProperties, num_valid_stat_ent, SLE_UINT8, SL_MIN_VERSION, SLV_SAVELOAD_LIST_LENGTH),
SLE_VAR(CompanyProperties, months_of_bankruptcy, SLE_UINT8),
SLE_CONDVAR(CompanyProperties, bankrupt_asked, SLE_FILE_U8 | SLE_VAR_U16, SL_MIN_VERSION, SLV_104),
SLE_CONDVAR(CompanyProperties, bankrupt_asked, SLE_UINT16, SLV_104, SL_MAX_VERSION),
SLE_VAR(CompanyProperties, bankrupt_timeout, SLE_INT16),
SLE_CONDVAR(CompanyProperties, bankrupt_value, SLE_VAR_I64 | SLE_FILE_I32, SL_MIN_VERSION, SLV_65),
SLE_CONDVAR(CompanyProperties, bankrupt_value, SLE_INT64, SLV_65, SL_MAX_VERSION),
/* yearly expenses was changed to 64-bit in savegame version 2. */
SLE_CONDARR(CompanyProperties, yearly_expenses, SLE_FILE_I32 | SLE_VAR_I64, 3 * 13, SL_MIN_VERSION, SLV_2),
SLE_CONDARR(CompanyProperties, yearly_expenses, SLE_INT64, 3 * 13, SLV_2, SL_MAX_VERSION),
SLE_CONDVAR(CompanyProperties, is_ai, SLE_BOOL, SLV_2, SL_MAX_VERSION),
SLE_CONDVAR(CompanyProperties, terraform_limit, SLE_UINT32, SLV_156, SL_MAX_VERSION),
SLE_CONDVAR(CompanyProperties, clear_limit, SLE_UINT32, SLV_156, SL_MAX_VERSION),
SLE_CONDVAR(CompanyProperties, tree_limit, SLE_UINT32, SLV_175, SL_MAX_VERSION),
SLEG_STRUCT("settings", SlCompanySettings),
SLEG_CONDSTRUCT("old_ai", SlCompanyOldAI, SL_MIN_VERSION, SLV_107),
SLEG_STRUCT("cur_economy", SlCompanyEconomy),
SLEG_STRUCTLIST("old_economy", SlCompanyOldEconomy),
SLEG_CONDSTRUCTLIST("liveries", SlCompanyLiveries, SLV_34, SL_MAX_VERSION),
};
struct PLYRChunkHandler : ChunkHandler {
PLYRChunkHandler() : ChunkHandler('PLYR', CH_TABLE) {}
void Save() const override
{
SlTableHeader(_company_desc);
for (Company *c : Company::Iterate()) {
SlSetArrayIndex(c->index);
SlObject(c, _company_desc);
}
}
void Load() const override
{
const std::vector<SaveLoad> slt = SlCompatTableHeader(_company_desc, _company_sl_compat);
int index;
while ((index = SlIterateArray()) != -1) {
Company *c = new (index) Company();
SetDefaultCompanySettings(c->index);
SlObject((CompanyProperties *)c, slt);
_company_colours[index] = (Colours)c->colour;
}
}
void LoadCheck(size_t) const override
{
const std::vector<SaveLoad> slt = SlCompatTableHeader(_company_desc, _company_sl_compat);
int index;
while ((index = SlIterateArray()) != -1) {
CompanyProperties *cprops = new CompanyProperties();
SlObject(cprops, slt);
/* We do not load old custom names */
if (IsSavegameVersionBefore(SLV_84)) {
if (GetStringTab(cprops->name_1) == TEXT_TAB_OLD_CUSTOM) {
cprops->name_1 = STR_GAME_SAVELOAD_NOT_AVAILABLE;
}
if (GetStringTab(cprops->president_name_1) == TEXT_TAB_OLD_CUSTOM) {
cprops->president_name_1 = STR_GAME_SAVELOAD_NOT_AVAILABLE;
}
}
if (cprops->name.empty() && !IsInsideMM(cprops->name_1, SPECSTR_COMPANY_NAME_START, SPECSTR_COMPANY_NAME_LAST + 1) &&
cprops->name_1 != STR_GAME_SAVELOAD_NOT_AVAILABLE && cprops->name_1 != STR_SV_UNNAMED &&
cprops->name_1 != SPECSTR_ANDCO_NAME && cprops->name_1 != SPECSTR_PRESIDENT_NAME &&
cprops->name_1 != SPECSTR_SILLY_NAME) {
cprops->name_1 = STR_GAME_SAVELOAD_NOT_AVAILABLE;
}
if (!_load_check_data.companies.Insert(index, cprops)) delete cprops;
}
}
void FixPointers() const override
{
for (Company *c : Company::Iterate()) {
SlObject((CompanyProperties *)c, _company_desc);
}
}
};
static const PLYRChunkHandler PLYR;
static const ChunkHandlerRef company_chunk_handlers[] = {
PLYR,
};
extern const ChunkHandlerTable _company_chunk_handlers(company_chunk_handlers);
}

@ -0,0 +1,29 @@
add_files(
ai_sl_compat.h
autoreplace_sl_compat.h
cargomonitor_sl_compat.h
cargopacket_sl_compat.h
cheat_sl_compat.h
company_sl_compat.h
depot_sl_compat.h
economy_sl_compat.h
engine_sl_compat.h
game_sl_compat.h
goal_sl_compat.h
group_sl_compat.h
industry_sl_compat.h
labelmaps_sl_compat.h
map_sl_compat.h
misc_sl_compat.h
newgrf_sl_compat.h
object_sl_compat.h
order_sl_compat.h
settings_sl_compat.h
signs_sl_compat.h
station_sl_compat.h
storage_sl_compat.h
story_sl_compat.h
subsidy_sl_compat.h
town_sl_compat.h
vehicle_sl_compat.h
)

@ -0,0 +1,27 @@
/*
* This file is part of OpenTTD.
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file ai_sl_compat.h Loading for ai chunks before table headers were added. */
#ifndef SAVELOAD_COMPAT_AI_H
#define SAVELOAD_COMPAT_AI_H
#include "../saveload.h"
namespace upstream_sl {
/** Original field order for _ai_company_desc. */
const SaveLoadCompat _ai_company_sl_compat[] = {
SLC_VAR("name"),
SLC_VAR("settings"),
SLC_VAR("version"),
SLC_VAR("is_random"),
};
}
#endif /* SAVELOAD_COMPAT_AI_H */

@ -0,0 +1,24 @@
/*
* This file is part of OpenTTD.
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file animated_tile_sl_compat.h Loading for animated_tile chunks before table headers were added. */
#ifndef SAVELOAD_COMPAT_ANIMATED_TILE_H
#define SAVELOAD_COMPAT_ANIMATED_TILE_H
#include "../saveload.h"
namespace upstream_sl {
/** Original field order for _animated_tile_desc. */
const SaveLoadCompat _animated_tile_sl_compat[] = {
SLC_VAR("tiles"),
};
}
#endif /* SAVELOAD_COMPAT_ANIMATED_TILE_H */

@ -0,0 +1,28 @@
/*
* This file is part of OpenTTD.
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file autoreplace_sl_compat.h Loading for autoreplace chunks before table headers were added. */
#ifndef SAVELOAD_COMPAT_AUTOREPLACE_H
#define SAVELOAD_COMPAT_AUTOREPLACE_H
#include "../saveload.h"
namespace upstream_sl {
/** Original field order for _engine_renew_desc. */
const SaveLoadCompat _engine_renew_sl_compat[] = {
SLC_VAR("from"),
SLC_VAR("to"),
SLC_VAR("next"),
SLC_VAR("group_id"),
SLC_VAR("replace_when_old"),
};
}
#endif /* SAVELOAD_COMPAT_AUTOREPLACE_H */

@ -0,0 +1,25 @@
/*
* This file is part of OpenTTD.
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file cargomonitor_sl_compat.h Loading for cargomonitor chunks before table headers were added. */
#ifndef SAVELOAD_COMPAT_CARGOMONITOR_H
#define SAVELOAD_COMPAT_CARGOMONITOR_H
#include "../saveload.h"
namespace upstream_sl {
/** Original field order for _cargomonitor_pair_desc. */
const SaveLoadCompat _cargomonitor_pair_sl_compat[] = {
SLC_VAR("number"),
SLC_VAR("amount"),
};
}
#endif /* SAVELOAD_COMPAT_CARGOMONITOR_H */

@ -0,0 +1,32 @@
/*
* This file is part of OpenTTD.
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file cargopacket_sl_compat.h Loading for cargopacket chunks before table headers were added. */
#ifndef SAVELOAD_COMPAT_CARGOPACKET_H
#define SAVELOAD_COMPAT_CARGOPACKET_H
#include "../saveload.h"
namespace upstream_sl {
/** Original field order for _cargopacket_desc. */
const SaveLoadCompat _cargopacket_sl_compat[] = {
SLC_VAR("source"),
SLC_VAR("source_xy"),
SLC_VAR("loaded_at_xy"),
SLC_VAR("count"),
SLC_VAR("days_in_transit"),
SLC_VAR("feeder_share"),
SLC_VAR("source_type"),
SLC_VAR("source_id"),
SLC_NULL(1, SL_MIN_VERSION, SLV_121),
};
}
#endif /* SAVELOAD_COMPAT_CARGOPACKET_H */

@ -0,0 +1,45 @@
/*
* This file is part of OpenTTD.
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file cheat_sl_compat.h Loading for cheat chunks before table headers were added. */
#ifndef SAVELOAD_COMPAT_CHEAT_H
#define SAVELOAD_COMPAT_CHEAT_H
#include "../saveload.h"
namespace upstream_sl {
/** Original field order for _cheats_desc. */
const SaveLoadCompat _cheats_sl_compat[] = {
SLC_VAR("magic_bulldozer.been_used"),
SLC_VAR("magic_bulldozer.value"),
SLC_VAR("switch_company.been_used"),
SLC_VAR("switch_company.value"),
SLC_VAR("money.been_used"),
SLC_VAR("money.value"),
SLC_VAR("crossing_tunnels.been_used"),
SLC_VAR("crossing_tunnels.value"),
SLC_NULL(1, SL_MIN_VERSION, SLV_TABLE_CHUNKS),
SLC_NULL(1, SL_MIN_VERSION, SLV_TABLE_CHUNKS), // Need to be two NULL fields. See Load_CHTS().
SLC_VAR("no_jetcrash.been_used"),
SLC_VAR("no_jetcrash.value"),
SLC_NULL(1, SL_MIN_VERSION, SLV_TABLE_CHUNKS),
SLC_NULL(1, SL_MIN_VERSION, SLV_TABLE_CHUNKS), // Need to be two NULL fields. See Load_CHTS().
SLC_VAR("change_date.been_used"),
SLC_VAR("change_date.value"),
SLC_VAR("setup_prod.been_used"),
SLC_VAR("setup_prod.value"),
SLC_NULL(1, SL_MIN_VERSION, SLV_TABLE_CHUNKS),
SLC_NULL(1, SL_MIN_VERSION, SLV_TABLE_CHUNKS), // Need to be two NULL fields. See Load_CHTS().
SLC_VAR("edit_max_hl.been_used"),
SLC_VAR("edit_max_hl.value"),
};
}
#endif /* SAVELOAD_COMPAT_CHEAT_H */

@ -0,0 +1,133 @@
/*
* This file is part of OpenTTD.
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file company_sl_compat.h Loading of company chunks before table headers were added. */
#ifndef SAVELOAD_COMPAT_COMPANY_H
#define SAVELOAD_COMPAT_COMPANY_H
#include "../saveload.h"
namespace upstream_sl {
/** Original field order for SlCompanyOldAIBuildRec. */
const SaveLoadCompat _company_old_ai_buildrec_compat[] = {
SLC_NULL(2, SL_MIN_VERSION, SLV_6),
SLC_NULL(4, SLV_6, SLV_107),
SLC_NULL(2, SL_MIN_VERSION, SLV_6),
SLC_NULL(4, SLV_6, SLV_107),
SLC_NULL(8, SL_MIN_VERSION, SLV_107),
};
/** Original field order for SlCompanyOldAI. */
const SaveLoadCompat _company_old_ai_compat[] = {
SLC_NULL(2, SL_MIN_VERSION, SLV_107),
SLC_NULL(2, SL_MIN_VERSION, SLV_13),
SLC_NULL(4, SLV_13, SLV_107),
SLC_NULL(8, SL_MIN_VERSION, SLV_107),
SLC_VAR("num_build_rec"),
SLC_NULL(3, SL_MIN_VERSION, SLV_107),
SLC_NULL(2, SL_MIN_VERSION, SLV_6),
SLC_NULL(4, SLV_6, SLV_107),
SLC_NULL(2, SL_MIN_VERSION, SLV_6),
SLC_NULL(4, SLV_6, SLV_107),
SLC_NULL(2, SL_MIN_VERSION, SLV_107),
SLC_NULL(2, SL_MIN_VERSION, SLV_6),
SLC_NULL(4, SLV_6, SLV_107),
SLC_NULL(2, SL_MIN_VERSION, SLV_6),
SLC_NULL(4, SLV_6, SLV_107),
SLC_NULL(2, SL_MIN_VERSION, SLV_107),
SLC_NULL(2, SL_MIN_VERSION, SLV_69),
SLC_NULL(4, SLV_69, SLV_107),
SLC_NULL(18, SL_MIN_VERSION, SLV_107),
SLC_NULL(20, SL_MIN_VERSION, SLV_107),
SLC_NULL(32, SL_MIN_VERSION, SLV_107),
SLC_NULL(64, SLV_2, SLV_107),
SLC_VAR("buildrec"),
};
/** Original field order for SlCompanySettings. */
const SaveLoadCompat _company_settings_compat[] = {
SLC_NULL(512, SLV_16, SLV_19),
SLC_VAR("engine_renew_list"),
SLC_VAR("settings.engine_renew"),
SLC_VAR("settings.engine_renew_months"),
SLC_VAR("settings.engine_renew_money"),
SLC_VAR("settings.renew_keep_length"),
SLC_VAR("settings.vehicle.servint_ispercent"),
SLC_VAR("settings.vehicle.servint_trains"),
SLC_VAR("settings.vehicle.servint_roadveh"),
SLC_VAR("settings.vehicle.servint_aircraft"),
SLC_VAR("settings.vehicle.servint_ships"),
SLC_NULL(63, SLV_2, SLV_144),
};
/** Original field order for SlCompanyEconomy. */
const SaveLoadCompat _company_economy_compat[] = {
SLC_VAR("income"),
SLC_VAR("expenses"),
SLC_VAR("company_value"),
SLC_VAR("delivered_cargo[NUM_CARGO - 1]"),
SLC_VAR("delivered_cargo"),
SLC_VAR("performance_history"),
};
/** Original field order for SlCompanyLiveries. */
const SaveLoadCompat _company_liveries_compat[] = {
SLC_VAR("in_use"),
SLC_VAR("colour1"),
SLC_VAR("colour2"),
};
/** Original field order for company_desc. */
const SaveLoadCompat _company_sl_compat[] = {
SLC_VAR("name_2"),
SLC_VAR("name_1"),
SLC_VAR("name"),
SLC_VAR("president_name_1"),
SLC_VAR("president_name_2"),
SLC_VAR("president_name"),
SLC_VAR("face"),
SLC_VAR("money"),
SLC_VAR("current_loan"),
SLC_VAR("colour"),
SLC_VAR("money_fraction"),
SLC_NULL(1, SL_MIN_VERSION, SLV_58),
SLC_VAR("block_preview"),
SLC_NULL(2, SL_MIN_VERSION, SLV_94),
SLC_NULL(4, SLV_94, SLV_170),
SLC_VAR("location_of_HQ"),
SLC_VAR("last_build_coordinate"),
SLC_VAR("inaugurated_year"),
SLC_VAR("share_owners"),
SLC_VAR("num_valid_stat_ent"),
SLC_VAR("months_of_bankruptcy"),
SLC_VAR("bankrupt_asked"),
SLC_VAR("bankrupt_timeout"),
SLC_VAR("bankrupt_value"),
SLC_VAR("yearly_expenses"),
SLC_VAR("is_ai"),
SLC_NULL(1, SLV_107, SLV_112),
SLC_NULL(1, SLV_4, SLV_100),
SLC_VAR("terraform_limit"),
SLC_VAR("clear_limit"),
SLC_VAR("tree_limit"),
SLC_VAR("settings"),
SLC_VAR("old_ai"),
SLC_VAR("cur_economy"),
SLC_VAR("old_economy"),
SLC_VAR("liveries"),
};
}
#endif /* SAVELOAD_COMPAT_COMPANY_H */

@ -0,0 +1,29 @@
/*
* This file is part of OpenTTD.
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file depot_sl_compat.h Loading for depot chunks before table headers were added. */
#ifndef SAVELOAD_COMPAT_DEPOT_H
#define SAVELOAD_COMPAT_DEPOT_H
#include "../saveload.h"
namespace upstream_sl {
/** Original field order for _depot_desc. */
const SaveLoadCompat _depot_sl_compat[] = {
SLC_VAR("xy"),
SLC_VAR("town_index"),
SLC_VAR("town"),
SLC_VAR("town_cn"),
SLC_VAR("name"),
SLC_VAR("build_date"),
};
}
#endif /* SAVELOAD_COMPAT_DEPOT_H */

@ -0,0 +1,42 @@
/*
* This file is part of OpenTTD.
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file economy_sl_compat.h Loading for economy chunks before table headers were added. */
#ifndef SAVELOAD_COMPAT_ECONOMY_H
#define SAVELOAD_COMPAT_ECONOMY_H
#include "../saveload.h"
namespace upstream_sl {
/** Original field order for _economy_desc. */
const SaveLoadCompat _economy_sl_compat[] = {
SLC_NULL(4, SL_MIN_VERSION, SLV_65),
SLC_NULL(8, SLV_65, SLV_144),
SLC_VAR("old_max_loan_unround"),
SLC_VAR("old_max_loan_unround_fract"),
SLC_VAR("inflation_prices"),
SLC_VAR("inflation_payment"),
SLC_VAR("fluct"),
SLC_VAR("interest_rate"),
SLC_VAR("infl_amount"),
SLC_VAR("infl_amount_pr"),
SLC_VAR("industry_daily_change_counter"),
};
/** Original field order for _cargopayment_desc. */
const SaveLoadCompat _cargopayment_sl_compat[] = {
SLC_VAR("front"),
SLC_VAR("route_profit"),
SLC_VAR("visual_profit"),
SLC_VAR("visual_transfer"),
};
}
#endif /* SAVELOAD_COMPAT_ECONOMY_H */

@ -0,0 +1,52 @@
/*
* This file is part of OpenTTD.
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file engine_sl_compat.h Loading for engine chunks before table headers were added. */
#ifndef SAVELOAD_COMPAT_ENGINE_H
#define SAVELOAD_COMPAT_ENGINE_H
#include "../saveload.h"
namespace upstream_sl {
/** Original field order for _engine_desc. */
const SaveLoadCompat _engine_sl_compat[] = {
SLC_VAR("intro_date"),
SLC_VAR("age"),
SLC_VAR("reliability"),
SLC_VAR("reliability_spd_dec"),
SLC_VAR("reliability_start"),
SLC_VAR("reliability_max"),
SLC_VAR("reliability_final"),
SLC_VAR("duration_phase_1"),
SLC_VAR("duration_phase_2"),
SLC_VAR("duration_phase_3"),
SLC_NULL(1, SL_MIN_VERSION, SLV_121),
SLC_VAR("flags"),
SLC_NULL(1, SL_MIN_VERSION, SLV_179),
SLC_VAR("preview_asked"),
SLC_VAR("preview_company"),
SLC_VAR("preview_wait"),
SLC_NULL(1, SL_MIN_VERSION, SLV_45),
SLC_VAR("company_avail"),
SLC_VAR("company_hidden"),
SLC_VAR("name"),
SLC_NULL(16, SLV_2, SLV_144),
};
/** Original field order for _engine_id_mapping_desc. */
const SaveLoadCompat _engine_id_mapping_sl_compat[] = {
SLC_VAR("grfid"),
SLC_VAR("internal_id"),
SLC_VAR("type"),
SLC_VAR("substitute_id"),
};
}
#endif /* SAVELOAD_COMPAT_ENGINE_H */

@ -0,0 +1,39 @@
/*
* This file is part of OpenTTD.
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file game_sl_compat.h Loading for game chunks before table headers were added. */
#ifndef SAVELOAD_COMPAT_GAME_H
#define SAVELOAD_COMPAT_GAME_H
#include "../saveload.h"
namespace upstream_sl {
/** Original field order for _game_script_desc. */
const SaveLoadCompat _game_script_sl_compat[] = {
SLC_VAR("name"),
SLC_VAR("settings"),
SLC_VAR("version"),
SLC_VAR("is_random"),
};
/** Original field order for SlGameLanguageString. */
const SaveLoadCompat _game_language_string_sl_compat[] = {
SLC_VAR("string"),
};
/** Original field order for _game_language_desc. */
const SaveLoadCompat _game_language_sl_compat[] = {
SLC_VAR("language"),
SLC_VAR("count"),
SLC_VAR("strings"),
};
}
#endif /* SAVELOAD_COMPAT_GAME_H */

@ -0,0 +1,109 @@
/*
* This file is part of OpenTTD.
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file gamelog_sl_compat.h Loading for gamelog chunks before table headers were added. */
#ifndef SAVELOAD_COMPAT_GAMELOG_H
#define SAVELOAD_COMPAT_GAMELOG_H
#include "../saveload.h"
namespace upstream_sl {
/** Original field order for SlGamelogMode. */
const SaveLoadCompat _gamelog_mode_sl_compat[] = {
SLC_VAR("mode.mode"),
SLC_VAR("mode.landscape"),
};
/** Original field order for SlGamelogRevision. */
const SaveLoadCompat _gamelog_revision_sl_compat[] = {
SLC_VAR("revision.text"),
SLC_VAR("revision.newgrf"),
SLC_VAR("revision.slver"),
SLC_VAR("revision.modified"),
};
/** Original field order for SlGamelogOldver. */
const SaveLoadCompat _gamelog_oldver_sl_compat[] = {
SLC_VAR("oldver.type"),
SLC_VAR("oldver.version"),
};
/** Original field order for SlGamelogSetting. */
const SaveLoadCompat _gamelog_setting_sl_compat[] = {
SLC_VAR("setting.name"),
SLC_VAR("setting.oldval"),
SLC_VAR("setting.newval"),
};
/** Original field order for SlGamelogGrfadd. */
const SaveLoadCompat _gamelog_grfadd_sl_compat[] = {
SLC_VAR("grfadd.grfid"),
SLC_VAR("grfadd.md5sum"),
};
/** Original field order for SlGamelogGrfrem. */
const SaveLoadCompat _gamelog_grfrem_sl_compat[] = {
SLC_VAR("grfrem.grfid"),
};
/** Original field order for SlGamelogGrfcompat. */
const SaveLoadCompat _gamelog_grfcompat_sl_compat[] = {
SLC_VAR("grfcompat.grfid"),
SLC_VAR("grfcompat.md5sum"),
};
/** Original field order for SlGamelogGrfparam. */
const SaveLoadCompat _gamelog_grfparam_sl_compat[] = {
SLC_VAR("grfparam.grfid"),
};
/** Original field order for SlGamelogGrfmove. */
const SaveLoadCompat _gamelog_grfmove_sl_compat[] = {
SLC_VAR("grfmove.grfid"),
SLC_VAR("grfmove.offset"),
};
/** Original field order for SlGamelogGrfbug. */
const SaveLoadCompat _gamelog_grfbug_sl_compat[] = {
SLC_VAR("grfbug.data"),
SLC_VAR("grfbug.grfid"),
SLC_VAR("grfbug.bug"),
};
/** Original field order for SlGamelogEmergency. */
const SaveLoadCompat _gamelog_emergency_sl_compat[] = {
SLC_VAR("is_emergency_save"),
};
/** Original field order for SlGamelogAction. */
const SaveLoadCompat _gamelog_action_sl_compat[] = {
SLC_VAR("ct"),
SLC_VAR("mode"),
SLC_VAR("revision"),
SLC_VAR("oldver"),
SLC_VAR("setting"),
SLC_VAR("grfadd"),
SLC_VAR("grfrem"),
SLC_VAR("grfcompat"),
SLC_VAR("grfparam"),
SLC_VAR("grfmove"),
SLC_VAR("grfbug"),
SLC_VAR("emergency"),
};
/** Original field order for _gamelog_desc. */
const SaveLoadCompat _gamelog_sl_compat[] = {
SLC_VAR("at"),
SLC_VAR("tick"),
SLC_VAR("action"),
};
}
#endif /* SAVELOAD_COMPAT_GAMELOG_H */

@ -0,0 +1,29 @@
/*
* This file is part of OpenTTD.
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file goal_sl_compat.h Loading of goal chunks before table headers were added. */
#ifndef SAVELOAD_COMPAT_GOAL_H
#define SAVELOAD_COMPAT_GOAL_H
#include "../saveload.h"
namespace upstream_sl {
/** Original field order for _goals_desc. */
const SaveLoadCompat _goals_sl_compat[] = {
SLC_VAR("company"),
SLC_VAR("type"),
SLC_VAR("dst"),
SLC_VAR("text"),
SLC_VAR("progress"),
SLC_VAR("completed"),
};
}
#endif /* SAVELOAD_COMPAT_GOAL_H */

@ -0,0 +1,32 @@
/*
* This file is part of OpenTTD.
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file group_sl_compat.h Loading of group chunks before table headers were added. */
#ifndef SAVELOAD_COMPAT_GROUP_H
#define SAVELOAD_COMPAT_GROUP_H
#include "../saveload.h"
namespace upstream_sl {
/** Original field order for _group_desc. */
const SaveLoadCompat _group_sl_compat[] = {
SLC_VAR("name"),
SLC_NULL(2, SL_MIN_VERSION, SLV_164),
SLC_VAR("owner"),
SLC_VAR("vehicle_type"),
SLC_VAR("flags"),
SLC_VAR("livery.in_use"),
SLC_VAR("livery.colour1"),
SLC_VAR("livery.colour2"),
SLC_VAR("parent"),
};
}
#endif /* SAVELOAD_COMPAT_GROUP_H */

@ -0,0 +1,76 @@
/*
* This file is part of OpenTTD.
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file industry_sl_compat.h Loading of industry chunks before table headers were added. */
#ifndef SAVELOAD_COMPAT_INDUSTRY_H
#define SAVELOAD_COMPAT_INDUSTRY_H
#include "../saveload.h"
namespace upstream_sl {
/** Original field order for _industry_desc. */
const SaveLoadCompat _industry_sl_compat[] = {
SLC_VAR("location.tile"),
SLC_VAR("location.w"),
SLC_VAR("location.h"),
SLC_VAR("town"),
SLC_VAR("neutral_station"),
SLC_NULL(2, SL_MIN_VERSION, SLV_61),
SLC_VAR("produced_cargo"),
SLC_VAR("incoming_cargo_waiting"),
SLC_VAR("produced_cargo_waiting"),
SLC_VAR("production_rate"),
SLC_NULL(3, SL_MIN_VERSION, SLV_61),
SLC_VAR("accepts_cargo"),
SLC_VAR("prod_level"),
SLC_VAR("this_month_production"),
SLC_VAR("this_month_transported"),
SLC_VAR("last_month_pct_transported"),
SLC_VAR("last_month_production"),
SLC_VAR("last_month_transported"),
SLC_VAR("counter"),
SLC_VAR("type"),
SLC_VAR("owner"),
SLC_VAR("random_colour"),
SLC_VAR("last_prod_year"),
SLC_VAR("was_cargo_delivered"),
SLC_VAR("ctlflags"),
SLC_VAR("founder"),
SLC_VAR("construction_date"),
SLC_VAR("construction_type"),
SLC_VAR("last_cargo_accepted_at[0]"),
SLC_VAR("last_cargo_accepted_at"),
SLC_VAR("selected_layout"),
SLC_VAR("exclusive_supplier"),
SLC_VAR("exclusive_consumer"),
SLC_VAR("storage"),
SLC_VAR("psa"),
SLC_NULL(1, SLV_82, SLV_197),
SLC_VAR("random"),
SLC_VAR("text"),
SLC_NULL(32, SLV_2, SLV_144),
};
/** Original field order for _industry_builder_desc. */
const SaveLoadCompat _industry_builder_sl_compat[] = {
SLC_VAR("wanted_inds"),
};
/** Original field order for _industrytype_builder_desc. */
const SaveLoadCompat _industrytype_builder_sl_compat[] = {
SLC_VAR("probability"),
SLC_VAR("min_number"),
SLC_VAR("target_count"),
SLC_VAR("max_wait"),
SLC_VAR("wait_count"),
};
}
#endif /* SAVELOAD_COMPAT_INDUSTRY_H */

@ -0,0 +1,24 @@
/*
* This file is part of OpenTTD.
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file labelmaps_sl_compat.h Loading of labelmaps chunks before table headers were added. */
#ifndef SAVELOAD_COMPAT_LABELMAPS_H
#define SAVELOAD_COMPAT_LABELMAPS_H
#include "../saveload.h"
namespace upstream_sl {
/** Original field order for _label_object_desc. */
const SaveLoadCompat _label_object_sl_compat[] = {
SLC_VAR("label"),
};
}
#endif /* SAVELOAD_COMPAT_LABELMAPS_H */

@ -0,0 +1,70 @@
/*
* This file is part of OpenTTD.
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file linkgraph_sl_compat.h Loading of linkgraph chunks before table headers were added. */
#ifndef SAVELOAD_COMPAT_LINKGRAPH_H
#define SAVELOAD_COMPAT_LINKGRAPH_H
#include "../saveload.h"
namespace upstream_sl {
/** Original field order for SlLinkgraphEdge. */
const SaveLoadCompat _linkgraph_edge_sl_compat[] = {
SLC_NULL(4, SL_MIN_VERSION, SLV_191),
SLC_VAR("capacity"),
SLC_VAR("usage"),
SLC_VAR("last_unrestricted_update"),
SLC_VAR("last_restricted_update"),
SLC_VAR("next_edge"),
};
/** Original field order for SlLinkgraphNode. */
const SaveLoadCompat _linkgraph_node_sl_compat[] = {
SLC_VAR("xy"),
SLC_VAR("supply"),
SLC_VAR("demand"),
SLC_VAR("station"),
SLC_VAR("last_update"),
SLC_VAR("edges"),
};
/** Original field order for link_graph_desc. */
const SaveLoadCompat _linkgraph_sl_compat[] = {
SLC_VAR("last_compression"),
SLC_VAR("num_nodes"),
SLC_VAR("cargo"),
SLC_VAR("nodes"),
};
/** Original field order for job_desc. */
const SaveLoadCompat _linkgraph_job_sl_compat[] = {
SLC_VAR("linkgraph.recalc_interval"),
SLC_VAR("linkgraph.recalc_time"),
SLC_VAR("linkgraph.distribution_pax"),
SLC_VAR("linkgraph.distribution_mail"),
SLC_VAR("linkgraph.distribution_armoured"),
SLC_VAR("linkgraph.distribution_default"),
SLC_VAR("linkgraph.accuracy"),
SLC_VAR("linkgraph.demand_distance"),
SLC_VAR("linkgraph.demand_size"),
SLC_VAR("linkgraph.short_path_saturation"),
SLC_VAR("join_date"),
SLC_VAR("link_graph.index"),
SLC_VAR("linkgraph"),
};
/** Original field order for schedule_desc. */
const SaveLoadCompat _linkgraph_schedule_sl_compat[] = {
SLC_VAR("schedule"),
SLC_VAR("running"),
};
}
#endif /* SAVELOAD_COMPAT_LINKGRAPH_H */

@ -0,0 +1,25 @@
/*
* This file is part of OpenTTD.
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file map_sl_compat.h Loading for map chunks before table headers were added. */
#ifndef SAVELOAD_COMPAT_MAP_H
#define SAVELOAD_COMPAT_MAP_H
#include "../saveload.h"
namespace upstream_sl {
/** Original field order for _map_desc. */
const SaveLoadCompat _map_sl_compat[] = {
SLC_VAR("dim_x"),
SLC_VAR("dim_y"),
};
}
#endif /* SAVELOAD_COMPAT_MAP_H */

@ -0,0 +1,72 @@
/*
* This file is part of OpenTTD.
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file misc_sl_compat.h Loading for misc chunks before table headers were added. */
#ifndef SAVELOAD_COMPAT_MISC_H
#define SAVELOAD_COMPAT_MISC_H
#include "../saveload.h"
namespace upstream_sl {
/** Original field order for _date_desc. */
const SaveLoadCompat _date_sl_compat[] = {
SLC_VAR("date"),
SLC_VAR("date_fract"),
SLC_VAR("tick_counter"),
SLC_NULL(2, SL_MIN_VERSION, SLV_157),
SLC_VAR("age_cargo_skip_counter"),
SLC_NULL(1, SL_MIN_VERSION, SLV_46),
SLC_VAR("cur_tileloop_tile"),
SLC_VAR("next_disaster_start"),
SLC_NULL(2, SL_MIN_VERSION, SLV_120),
SLC_VAR("random_state[0]"),
SLC_VAR("random_state[1]"),
SLC_NULL(1, SL_MIN_VERSION, SLV_10),
SLC_NULL(4, SLV_10, SLV_120),
SLC_VAR("company_tick_counter"),
SLC_VAR("next_competitor_start"),
SLC_VAR("trees_tick_counter"),
SLC_VAR("pause_mode"),
SLC_NULL(4, SLV_11, SLV_120),
};
/** Original field order for _date_check_desc. */
const SaveLoadCompat _date_check_sl_compat[] = {
SLC_VAR("date"),
SLC_NULL(2, SL_MIN_VERSION, SL_MAX_VERSION), // date_fract
SLC_NULL(2, SL_MIN_VERSION, SL_MAX_VERSION), // tick_counter
SLC_NULL(2, SL_MIN_VERSION, SLV_157),
SLC_NULL(1, SL_MIN_VERSION, SLV_162), // age_cargo_skip_counter
SLC_NULL(1, SL_MIN_VERSION, SLV_46),
SLC_NULL(2, SL_MIN_VERSION, SLV_6), // cur_tileloop_tile
SLC_NULL(4, SLV_6, SL_MAX_VERSION), // cur_tileloop_tile
SLC_NULL(2, SL_MIN_VERSION, SL_MAX_VERSION), // disaster_delay
SLC_NULL(2, SL_MIN_VERSION, SLV_120),
SLC_NULL(4, SL_MIN_VERSION, SL_MAX_VERSION), // random.state[0]
SLC_NULL(4, SL_MIN_VERSION, SL_MAX_VERSION), // random.state[1]
SLC_NULL(1, SL_MIN_VERSION, SLV_10),
SLC_NULL(4, SLV_10, SLV_120),
SLC_NULL(1, SL_MIN_VERSION, SL_MAX_VERSION), // cur_company_tick_index
SLC_NULL(2, SL_MIN_VERSION, SLV_109), // next_competitor_start
SLC_NULL(4, SLV_109, SL_MAX_VERSION), // next_competitor_start
SLC_NULL(1, SL_MIN_VERSION, SL_MAX_VERSION), // trees_tick_ctr
SLC_NULL(1, SLV_4, SL_MAX_VERSION), // pause_mode
SLC_NULL(4, SLV_11, SLV_120),
};
/** Original field order for _view_desc. */
const SaveLoadCompat _view_sl_compat[] = {
SLC_VAR("x"),
SLC_VAR("y"),
SLC_VAR("zoom"),
};
}
#endif /* SAVELOAD_COMPAT_MISC_H */

@ -0,0 +1,37 @@
/*
* This file is part of OpenTTD.
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file newgrf_sl_compat.h Loading of newgrf chunks before table headers were added. */
#ifndef SAVELOAD_COMPAT_NEWGRF_H
#define SAVELOAD_COMPAT_NEWGRF_H
#include "../saveload.h"
namespace upstream_sl {
/** Original field order for _newgrf_mapping_desc. */
const SaveLoadCompat _newgrf_mapping_sl_compat[] = {
SLC_VAR("grfid"),
SLC_VAR("entity_id"),
SLC_VAR("substitute_id"),
};
/** Original field order for _newgrf_desc. */
const SaveLoadCompat _grfconfig_sl_compat[] = {
SLC_VAR("filename"),
SLC_VAR("ident.grfid"),
SLC_VAR("ident.md5sum"),
SLC_VAR("version"),
SLC_VAR("param"),
SLC_VAR("num_params"),
SLC_VAR("palette"),
};
}
#endif /* SAVELOAD_COMPAT_NEWGRF_H */

@ -0,0 +1,31 @@
/*
* This file is part of OpenTTD.
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file object_sl_compat.h Loading of object chunks before table headers were added. */
#ifndef SAVELOAD_COMPAT_OBJECT_H
#define SAVELOAD_COMPAT_OBJECT_H
#include "../saveload.h"
namespace upstream_sl {
/** Original field order for _object_desc. */
const SaveLoadCompat _object_sl_compat[] = {
SLC_VAR("location.tile"),
SLC_VAR("location.w"),
SLC_VAR("location.h"),
SLC_VAR("town"),
SLC_VAR("build_date"),
SLC_VAR("colour"),
SLC_VAR("view"),
SLC_VAR("type"),
};
}
#endif /* SAVELOAD_COMPAT_OBJECT_H */

@ -0,0 +1,56 @@
/*
* This file is part of OpenTTD.
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file order_sl_compat.h Loading of order chunks before table headers were added. */
#ifndef SAVELOAD_COMPAT_ORDER_H
#define SAVELOAD_COMPAT_ORDER_H
#include "../saveload.h"
namespace upstream_sl {
/** Original field order for _order_desc. */
const SaveLoadCompat _order_sl_compat[] = {
SLC_VAR("type"),
SLC_VAR("flags"),
SLC_VAR("dest"),
SLC_VAR("next"),
SLC_VAR("refit_cargo"),
SLC_NULL(1, SLV_36, SLV_182),
SLC_VAR("wait_time"),
SLC_VAR("travel_time"),
SLC_VAR("max_speed"),
SLC_NULL(10, SLV_5, SLV_36),
};
/** Original field order for _orderlist_desc. */
const SaveLoadCompat _orderlist_sl_compat[] = {
SLC_VAR("first"),
};
/** Original field order for _order_backup_desc. */
const SaveLoadCompat _order_backup_sl_compat[] = {
SLC_VAR("user"),
SLC_VAR("tile"),
SLC_VAR("group"),
SLC_VAR("service_interval"),
SLC_VAR("name"),
SLC_NULL(2, SL_MIN_VERSION, SLV_192),
SLC_VAR("clone"),
SLC_VAR("cur_real_order_index"),
SLC_VAR("cur_implicit_order_index"),
SLC_VAR("current_order_time"),
SLC_VAR("lateness_counter"),
SLC_VAR("timetable_start"),
SLC_VAR("vehicle_flags"),
SLC_VAR("orders"),
};
}
#endif /* SAVELOAD_COMPAT_ORDER_H */

@ -0,0 +1,270 @@
/*
* This file is part of OpenTTD.
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file settings_sl_compat.h Loading of settings chunks before table headers were added. */
#ifndef SAVELOAD_COMPAT_SETTINGS_H
#define SAVELOAD_COMPAT_SETTINGS_H
#include "../saveload.h"
namespace upstream_sl {
/** Original field order for _gameopt. */
const SaveLoadCompat _gameopt_sl_compat[] = {
SLC_VAR("diff_custom"),
SLC_VAR("diff_level"),
SLC_VAR("locale.currency"),
SLC_VAR("units"),
SLC_VAR("game_creation.town_name"),
SLC_VAR("game_creation.landscape"),
SLC_VAR("game_creation.snow_line_height"),
SLC_NULL(1, SLV_22, SLV_165),
SLC_NULL(1, SL_MIN_VERSION, SLV_23),
SLC_VAR("vehicle.road_side"),
};
/** Original field order for _settings. */
const SaveLoadCompat _settings_sl_compat[] = {
SLC_VAR("difficulty.max_no_competitors"),
SLC_NULL(1, SLV_97, SLV_110),
SLC_VAR("difficulty.number_towns"),
SLC_VAR("difficulty.industry_density"),
SLC_VAR("difficulty.max_loan"),
SLC_VAR("difficulty.initial_interest"),
SLC_VAR("difficulty.vehicle_costs"),
SLC_VAR("difficulty.competitor_speed"),
SLC_NULL(1, SLV_97, SLV_110),
SLC_VAR("difficulty.vehicle_breakdowns"),
SLC_VAR("difficulty.subsidy_multiplier"),
SLC_VAR("difficulty.subsidy_duration"),
SLC_VAR("difficulty.construction_cost"),
SLC_VAR("difficulty.terrain_type"),
SLC_VAR("difficulty.quantity_sea_lakes"),
SLC_VAR("difficulty.economy"),
SLC_VAR("difficulty.line_reverse_mode"),
SLC_VAR("difficulty.disasters"),
SLC_VAR("difficulty.town_council_tolerance"),
SLC_VAR("diff_level"),
SLC_VAR("game_creation.town_name"),
SLC_VAR("game_creation.landscape"),
SLC_NULL(1, SLV_97, SLV_164),
SLC_VAR("vehicle.road_side"),
SLC_VAR("construction.map_height_limit"),
SLC_VAR("game_creation.heightmap_height"),
SLC_VAR("construction.build_on_slopes"),
SLC_VAR("construction.command_pause_level"),
SLC_VAR("construction.terraform_per_64k_frames"),
SLC_VAR("construction.terraform_frame_burst"),
SLC_VAR("construction.clear_per_64k_frames"),
SLC_VAR("construction.clear_frame_burst"),
SLC_VAR("construction.tree_per_64k_frames"),
SLC_VAR("construction.tree_frame_burst"),
SLC_VAR("construction.autoslope"),
SLC_VAR("construction.extra_dynamite"),
SLC_VAR("construction.max_bridge_length"),
SLC_VAR("construction.max_bridge_height"),
SLC_VAR("construction.max_tunnel_length"),
SLC_NULL(1, SL_MIN_VERSION, SLV_159),
SLC_VAR("construction.train_signal_side"),
SLC_VAR("station.never_expire_airports"),
SLC_VAR("economy.town_layout"),
SLC_VAR("economy.allow_town_roads"),
SLC_VAR("economy.found_town"),
SLC_VAR("economy.allow_town_level_crossings"),
SLC_VAR("economy.town_cargogen_mode"),
SLC_VAR("linkgraph.recalc_interval"),
SLC_VAR("linkgraph.recalc_time"),
SLC_VAR("linkgraph.distribution_pax"),
SLC_VAR("linkgraph.distribution_mail"),
SLC_VAR("linkgraph.distribution_armoured"),
SLC_VAR("linkgraph.distribution_default"),
SLC_VAR("linkgraph.accuracy"),
SLC_VAR("linkgraph.demand_distance"),
SLC_VAR("linkgraph.demand_size"),
SLC_VAR("linkgraph.short_path_saturation"),
SLC_VAR("vehicle.train_acceleration_model"),
SLC_VAR("vehicle.roadveh_acceleration_model"),
SLC_VAR("vehicle.train_slope_steepness"),
SLC_VAR("vehicle.roadveh_slope_steepness"),
SLC_VAR("pf.forbid_90_deg"),
SLC_VAR("vehicle.max_train_length"),
SLC_NULL(1, SL_MIN_VERSION, SLV_159),
SLC_VAR("vehicle.smoke_amount"),
SLC_NULL(1, SL_MIN_VERSION, SLV_159),
SLC_VAR("pf.roadveh_queue"),
SLC_VAR("pf.new_pathfinding_all"),
SLC_VAR("pf.yapf.ship_use_yapf"),
SLC_VAR("pf.yapf.road_use_yapf"),
SLC_VAR("pf.yapf.rail_use_yapf"),
SLC_VAR("pf.pathfinder_for_trains"),
SLC_VAR("pf.pathfinder_for_roadvehs"),
SLC_VAR("pf.pathfinder_for_ships"),
SLC_VAR("vehicle.never_expire_vehicles"),
SLC_VAR("vehicle.max_trains"),
SLC_VAR("vehicle.max_roadveh"),
SLC_VAR("vehicle.max_aircraft"),
SLC_VAR("vehicle.max_ships"),
SLC_VAR("vehicle.servint_ispercent"),
SLC_VAR("vehicle.servint_trains"),
SLC_VAR("vehicle.servint_roadveh"),
SLC_VAR("vehicle.servint_ships"),
SLC_VAR("vehicle.servint_aircraft"),
SLC_VAR("order.no_servicing_if_no_breakdowns"),
SLC_VAR("vehicle.wagon_speed_limits"),
SLC_VAR("vehicle.disable_elrails"),
SLC_VAR("vehicle.freight_trains"),
SLC_NULL(1, SLV_67, SLV_159),
SLC_VAR("vehicle.plane_speed"),
SLC_VAR("vehicle.dynamic_engines"),
SLC_VAR("vehicle.plane_crashes"),
SLC_NULL(1, SL_MIN_VERSION, SLV_159),
SLC_VAR("gui.sg_full_load_any"),
SLC_VAR("order.improved_load"),
SLC_VAR("order.selectgoods"),
SLC_VAR("gui.sg_new_nonstop"),
SLC_NULL(1, SL_MIN_VERSION, SLV_159),
SLC_VAR("station.station_spread"),
SLC_VAR("order.serviceathelipad"),
SLC_VAR("station.modified_catchment"),
SLC_VAR("station.serve_neutral_industries"),
SLC_VAR("order.gradual_loading"),
SLC_VAR("construction.road_stop_on_town_road"),
SLC_VAR("construction.road_stop_on_competitor_road"),
SLC_VAR("station.adjacent_stations"),
SLC_VAR("economy.station_noise_level"),
SLC_VAR("station.distant_join_stations"),
SLC_VAR("economy.inflation"),
SLC_VAR("construction.raw_industry_construction"),
SLC_VAR("construction.industry_platform"),
SLC_VAR("economy.multiple_industry_per_town"),
SLC_NULL(1, SL_MIN_VERSION, SLV_141),
SLC_VAR("economy.bribe"),
SLC_VAR("economy.exclusive_rights"),
SLC_VAR("economy.fund_buildings"),
SLC_VAR("economy.fund_roads"),
SLC_VAR("economy.give_money"),
SLC_VAR("game_creation.snow_line_height"),
SLC_VAR("game_creation.snow_coverage"),
SLC_VAR("game_creation.desert_coverage"),
SLC_NULL(4, SL_MIN_VERSION, SLV_144),
SLC_VAR("game_creation.starting_year"),
SLC_NULL(4, SL_MIN_VERSION, SLV_105),
SLC_VAR("game_creation.ending_year"),
SLC_VAR("economy.type"),
SLC_VAR("economy.allow_shares"),
SLC_VAR("economy.min_years_for_shares"),
SLC_VAR("economy.feeder_payment_share"),
SLC_VAR("economy.town_growth_rate"),
SLC_VAR("economy.larger_towns"),
SLC_VAR("economy.initial_city_size"),
SLC_VAR("economy.mod_road_rebuild"),
SLC_NULL(1, SL_MIN_VERSION, SLV_107),
SLC_VAR("script.settings_profile"),
SLC_VAR("ai.ai_in_multiplayer"),
SLC_VAR("ai.ai_disable_veh_train"),
SLC_VAR("ai.ai_disable_veh_roadveh"),
SLC_VAR("ai.ai_disable_veh_aircraft"),
SLC_VAR("ai.ai_disable_veh_ship"),
SLC_VAR("script.script_max_opcode_till_suspend"),
SLC_VAR("script.script_max_memory_megabytes"),
SLC_VAR("vehicle.extend_vehicle_life"),
SLC_VAR("economy.dist_local_authority"),
SLC_VAR("pf.reverse_at_signals"),
SLC_VAR("pf.wait_oneway_signal"),
SLC_VAR("pf.wait_twoway_signal"),
SLC_VAR("economy.town_noise_population[0]"),
SLC_VAR("economy.town_noise_population[1]"),
SLC_VAR("economy.town_noise_population[2]"),
SLC_VAR("economy.infrastructure_maintenance"),
SLC_VAR("pf.wait_for_pbs_path"),
SLC_VAR("pf.reserve_paths"),
SLC_VAR("pf.path_backoff_interval"),
SLC_NULL(3, SL_MIN_VERSION, SLV_REMOVE_OPF),
SLC_VAR("pf.npf.npf_max_search_nodes"),
SLC_VAR("pf.npf.npf_rail_firstred_penalty"),
SLC_VAR("pf.npf.npf_rail_firstred_exit_penalty"),
SLC_VAR("pf.npf.npf_rail_lastred_penalty"),
SLC_VAR("pf.npf.npf_rail_station_penalty"),
SLC_VAR("pf.npf.npf_rail_slope_penalty"),
SLC_VAR("pf.npf.npf_rail_curve_penalty"),
SLC_VAR("pf.npf.npf_rail_depot_reverse_penalty"),
SLC_VAR("pf.npf.npf_rail_pbs_cross_penalty"),
SLC_VAR("pf.npf.npf_rail_pbs_signal_back_penalty"),
SLC_VAR("pf.npf.npf_buoy_penalty"),
SLC_VAR("pf.npf.npf_water_curve_penalty"),
SLC_VAR("pf.npf.npf_road_curve_penalty"),
SLC_VAR("pf.npf.npf_crossing_penalty"),
SLC_VAR("pf.npf.npf_road_drive_through_penalty"),
SLC_VAR("pf.npf.npf_road_dt_occupied_penalty"),
SLC_VAR("pf.npf.npf_road_bay_occupied_penalty"),
SLC_VAR("pf.npf.maximum_go_to_depot_penalty"),
SLC_VAR("pf.yapf.disable_node_optimization"),
SLC_VAR("pf.yapf.max_search_nodes"),
SLC_VAR("pf.yapf.rail_firstred_twoway_eol"),
SLC_VAR("pf.yapf.rail_firstred_penalty"),
SLC_VAR("pf.yapf.rail_firstred_exit_penalty"),
SLC_VAR("pf.yapf.rail_lastred_penalty"),
SLC_VAR("pf.yapf.rail_lastred_exit_penalty"),
SLC_VAR("pf.yapf.rail_station_penalty"),
SLC_VAR("pf.yapf.rail_slope_penalty"),
SLC_VAR("pf.yapf.rail_curve45_penalty"),
SLC_VAR("pf.yapf.rail_curve90_penalty"),
SLC_VAR("pf.yapf.rail_depot_reverse_penalty"),
SLC_VAR("pf.yapf.rail_crossing_penalty"),
SLC_VAR("pf.yapf.rail_look_ahead_max_signals"),
SLC_VAR("pf.yapf.rail_look_ahead_signal_p0"),
SLC_VAR("pf.yapf.rail_look_ahead_signal_p1"),
SLC_VAR("pf.yapf.rail_look_ahead_signal_p2"),
SLC_VAR("pf.yapf.rail_pbs_cross_penalty"),
SLC_VAR("pf.yapf.rail_pbs_station_penalty"),
SLC_VAR("pf.yapf.rail_pbs_signal_back_penalty"),
SLC_VAR("pf.yapf.rail_doubleslip_penalty"),
SLC_VAR("pf.yapf.rail_longer_platform_penalty"),
SLC_VAR("pf.yapf.rail_longer_platform_per_tile_penalty"),
SLC_VAR("pf.yapf.rail_shorter_platform_penalty"),
SLC_VAR("pf.yapf.rail_shorter_platform_per_tile_penalty"),
SLC_VAR("pf.yapf.road_slope_penalty"),
SLC_VAR("pf.yapf.road_curve_penalty"),
SLC_VAR("pf.yapf.road_crossing_penalty"),
SLC_VAR("pf.yapf.road_stop_penalty"),
SLC_VAR("pf.yapf.road_stop_occupied_penalty"),
SLC_VAR("pf.yapf.road_stop_bay_occupied_penalty"),
SLC_VAR("pf.yapf.maximum_go_to_depot_penalty"),
SLC_VAR("pf.yapf.ship_curve45_penalty"),
SLC_VAR("pf.yapf.ship_curve90_penalty"),
SLC_VAR("game_creation.land_generator"),
SLC_VAR("game_creation.oil_refinery_limit"),
SLC_VAR("game_creation.tgen_smoothness"),
SLC_VAR("game_creation.variety"),
SLC_VAR("game_creation.generation_seed"),
SLC_VAR("game_creation.tree_placer"),
SLC_VAR("construction.freeform_edges"),
SLC_VAR("game_creation.water_borders"),
SLC_VAR("game_creation.custom_town_number"),
SLC_VAR("construction.extra_tree_placement"),
SLC_VAR("game_creation.custom_terrain_type"),
SLC_VAR("game_creation.custom_sea_level"),
SLC_VAR("game_creation.min_river_length"),
SLC_VAR("game_creation.river_route_random"),
SLC_VAR("game_creation.amount_of_rivers"),
SLC_VAR("locale.currency"),
SLC_VAR("units"),
SLC_VAR("locale.units_velocity"),
SLC_VAR("locale.units_power"),
SLC_VAR("locale.units_weight"),
SLC_VAR("locale.units_volume"),
SLC_VAR("locale.units_force"),
SLC_VAR("locale.units_height"),
SLC_VAR("locale.digit_group_separator"),
SLC_VAR("locale.digit_group_separator_currency"),
SLC_VAR("locale.digit_decimal_separator"),
};
}
#endif /* SAVELOAD_COMPAT_SETTINGS_H */

@ -0,0 +1,28 @@
/*
* This file is part of OpenTTD.
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file signs_sl_compat.h Loading of signs chunks before table headers were added. */
#ifndef SAVELOAD_COMPAT_SIGNS_H
#define SAVELOAD_COMPAT_SIGNS_H
#include "../saveload.h"
namespace upstream_sl {
/** Original field order for _sign_desc. */
const SaveLoadCompat _sign_sl_compat[] = {
SLC_VAR("name"),
SLC_VAR("x"),
SLC_VAR("y"),
SLC_VAR("owner"),
SLC_VAR("z"),
};
}
#endif /* SAVELOAD_COMPAT_SIGNS_H */

@ -0,0 +1,185 @@
/*
* This file is part of OpenTTD.
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file station_sl_compat.h Loading of station chunks before table headers were added. */
#ifndef SAVELOAD_COMPAT_STATION_H
#define SAVELOAD_COMPAT_STATION_H
#include "../saveload.h"
namespace upstream_sl {
/** Original field order for _roadstop_desc. */
const SaveLoadCompat _roadstop_sl_compat[] = {
SLC_VAR("xy"),
SLC_NULL(1, SL_MIN_VERSION, SLV_45),
SLC_VAR("status"),
SLC_NULL(4, SL_MIN_VERSION, SLV_9),
SLC_NULL(2, SL_MIN_VERSION, SLV_45),
SLC_NULL(1, SL_MIN_VERSION, SLV_26),
SLC_VAR("next"),
SLC_NULL(2, SL_MIN_VERSION, SLV_45),
SLC_NULL(4, SL_MIN_VERSION, SLV_25),
SLC_NULL(1, SLV_25, SLV_26),
};
/** Original field order for SlStationSpecList. */
const SaveLoadCompat _station_spec_list_sl_compat[] = {
SLC_VAR("grfid"),
SLC_VAR("localidx"),
};
/** Original field order for SlStationCargo. */
const SaveLoadCompat _station_cargo_sl_compat[] = {
SLC_VAR("first"),
SLC_VAR("second"),
};
/** Original field order for SlStationFlow. */
const SaveLoadCompat _station_flow_sl_compat[] = {
SLC_VAR("source"),
SLC_VAR("via"),
SLC_VAR("share"),
SLC_VAR("restricted"),
};
/** Original field order for SlStationGoods. */
const SaveLoadCompat _station_goods_sl_compat[] = {
SLC_VAR("waiting_acceptance"),
SLC_VAR("status"),
SLC_NULL(2, SLV_51, SLV_68),
SLC_VAR("time_since_pickup"),
SLC_VAR("rating"),
SLC_VAR("cargo_source"),
SLC_VAR("cargo_source_xy"),
SLC_VAR("cargo_days"),
SLC_VAR("last_speed"),
SLC_VAR("last_age"),
SLC_VAR("cargo_feeder_share"),
SLC_VAR("amount_fract"),
SLC_VAR("packets"),
SLC_VAR("old_num_dests"),
SLC_VAR("cargo.reserved_count"),
SLC_VAR("link_graph"),
SLC_VAR("node"),
SLC_VAR("old_num_flows"),
SLC_VAR("max_waiting_cargo"),
SLC_VAR("flow"),
SLC_VAR("cargo"),
};
/** Original field order for SlStationBase. */
const SaveLoadCompat _station_base_sl_compat[] = {
SLC_VAR("xy"),
SLC_VAR("town"),
SLC_VAR("string_id"),
SLC_VAR("name"),
SLC_VAR("delete_ctr"),
SLC_VAR("owner"),
SLC_VAR("facilities"),
SLC_VAR("build_date"),
SLC_VAR("random_bits"),
SLC_VAR("waiting_triggers"),
SLC_VAR("num_specs"),
};
/** Original field order for SlStationNormal. */
const SaveLoadCompat _station_normal_sl_compat[] = {
SLC_VAR("base"),
SLC_VAR("train_station.tile"),
SLC_VAR("train_station.w"),
SLC_VAR("train_station.h"),
SLC_VAR("bus_stops"),
SLC_VAR("truck_stops"),
SLC_NULL(4, SL_MIN_VERSION, SLV_MULTITILE_DOCKS),
SLC_VAR("ship_station.tile"),
SLC_VAR("ship_station.w"),
SLC_VAR("ship_station.h"),
SLC_VAR("docking_station.tile"),
SLC_VAR("docking_station.w"),
SLC_VAR("docking_station.h"),
SLC_VAR("airport.tile"),
SLC_VAR("airport.w"),
SLC_VAR("airport.h"),
SLC_VAR("airport.type"),
SLC_VAR("airport.layout"),
SLC_VAR("airport.flags"),
SLC_VAR("airport.rotation"),
SLC_VAR("storage"),
SLC_VAR("airport.psa"),
SLC_VAR("indtype"),
SLC_VAR("time_since_load"),
SLC_VAR("time_since_unload"),
SLC_VAR("last_vehicle_type"),
SLC_VAR("had_vehicle_of_type"),
SLC_VAR("loading_vehicles"),
SLC_VAR("always_accepted"),
SLC_VAR("goods"),
};
/** Original field order for SlStationWaypoint. */
const SaveLoadCompat _station_waypoint_sl_compat[] = {
SLC_VAR("base"),
SLC_VAR("town_cn"),
SLC_VAR("train_station.tile"),
SLC_VAR("train_station.w"),
SLC_VAR("train_station.h"),
};
/** Original field order for _station_desc. */
const SaveLoadCompat _station_sl_compat[] = {
SLC_VAR("facilities"),
SLC_VAR("normal"),
SLC_VAR("waypoint"),
SLC_VAR("speclist"),
};
/** Original field order for _old_station_desc. */
const SaveLoadCompat _old_station_sl_compat[] = {
SLC_VAR("xy"),
SLC_NULL(4, SL_MIN_VERSION, SLV_6),
SLC_VAR("train_station.tile"),
SLC_VAR("airport.tile"),
SLC_NULL(2, SL_MIN_VERSION, SLV_6),
SLC_NULL(4, SLV_6, SLV_MULTITILE_DOCKS),
SLC_VAR("town"),
SLC_VAR("train_station.w"),
SLC_VAR("train_station.h"),
SLC_NULL(1, SL_MIN_VERSION, SLV_4),
SLC_VAR("string_id"),
SLC_VAR("name"),
SLC_VAR("indtype"),
SLC_VAR("had_vehicle_of_type"),
SLC_VAR("time_since_load"),
SLC_VAR("time_since_unload"),
SLC_VAR("delete_ctr"),
SLC_VAR("owner"),
SLC_VAR("facilities"),
SLC_VAR("airport.type"),
SLC_NULL(2, SL_MIN_VERSION, SLV_6),
SLC_NULL(1, SL_MIN_VERSION, SLV_5),
SLC_VAR("airport.flags"),
SLC_NULL(2, SL_MIN_VERSION, SLV_26),
SLC_VAR("last_vehicle_type"),
SLC_NULL(2, SLV_3, SLV_26),
SLC_VAR("build_date"),
SLC_VAR("bus_stops"),
SLC_VAR("truck_stops"),
SLC_VAR("random_bits"),
SLC_VAR("waiting_triggers"),
SLC_VAR("num_specs"),
SLC_VAR("loading_vehicles"),
SLC_NULL(32, SLV_2, SL_MAX_VERSION),
SLC_VAR("goods"),
SLC_VAR("speclist"),
};
}
#endif /* SAVELOAD_COMPAT_STATION_H */

@ -0,0 +1,25 @@
/*
* This file is part of OpenTTD.
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file storage_sl_compat.h Loading of storage chunks before table headers were added. */
#ifndef SAVELOAD_COMPAT_STORAGE_H
#define SAVELOAD_COMPAT_STORAGE_H
#include "../saveload.h"
namespace upstream_sl {
/** Original field order for _storage_desc. */
const SaveLoadCompat _storage_sl_compat[] = {
SLC_VAR("grfid"),
SLC_VAR("storage"),
};
}
#endif /* SAVELOAD_COMPAT_STORAGE_H */

@ -0,0 +1,36 @@
/*
* This file is part of OpenTTD.
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file story_sl_compat.h Loading for story chunks before table headers were added. */
#ifndef SAVELOAD_COMPAT_STORE_H
#define SAVELOAD_COMPAT_STORE_H
#include "../saveload.h"
namespace upstream_sl {
/** Original field order for _story_page_elements_desc. */
const SaveLoadCompat _story_page_elements_sl_compat[] = {
SLC_VAR("sort_value"),
SLC_VAR("page"),
SLC_VAR("type"),
SLC_VAR("referenced_id"),
SLC_VAR("text"),
};
/** Original field order for _story_pages_desc. */
const SaveLoadCompat _story_pages_sl_compat[] = {
SLC_VAR("sort_value"),
SLC_VAR("date"),
SLC_VAR("company"),
SLC_VAR("title"),
};
}
#endif /* SAVELOAD_COMPAT_STORE_H */

@ -0,0 +1,30 @@
/*
* This file is part of OpenTTD.
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file subsidy_sl_compat.h Loading of subsidy chunks before table headers were added. */
#ifndef SAVELOAD_COMPAT_SUBSIDY_H
#define SAVELOAD_COMPAT_SUBSIDY_H
#include "../saveload.h"
namespace upstream_sl {
/** Original field order for _subsidies_desc. */
const SaveLoadCompat _subsidies_sl_compat[] = {
SLC_VAR("cargo_type"),
SLC_VAR("remaining"),
SLC_VAR("awarded"),
SLC_VAR("src_type"),
SLC_VAR("dst_type"),
SLC_VAR("src"),
SLC_VAR("dst"),
};
}
#endif /* SAVELOAD_COMPAT_SUBSIDY_H */

@ -0,0 +1,91 @@
/*
* This file is part of OpenTTD.
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file town_sl_compat.h Loading of town chunks before table headers were added. */
#ifndef SAVELOAD_COMPAT_TOWN_H
#define SAVELOAD_COMPAT_TOWN_H
#include "../saveload.h"
namespace upstream_sl {
/** Original field order for SlTownSupplied. */
const SaveLoadCompat _town_supplied_sl_compat[] = {
SLC_VAR("old_max"),
SLC_VAR("new_max"),
SLC_VAR("old_act"),
SLC_VAR("new_act"),
};
/** Original field order for SlTownReceived. */
const SaveLoadCompat _town_received_sl_compat[] = {
SLC_VAR("old_max"),
SLC_VAR("new_max"),
SLC_VAR("old_act"),
SLC_VAR("new_act"),
};
/** Original field order for SlTownAcceptanceMatrix. */
const SaveLoadCompat _town_acceptance_matrix_sl_compat[] = {
SLC_VAR("area.tile"),
SLC_VAR("area.w"),
SLC_VAR("area.h"),
};
/** Original field order for town_desc. */
const SaveLoadCompat _town_sl_compat[] = {
SLC_VAR("xy"),
SLC_NULL(2, SL_MIN_VERSION, SLV_3),
SLC_NULL(4, SLV_3, SLV_85),
SLC_NULL(2, SL_MIN_VERSION, SLV_92),
SLC_VAR("townnamegrfid"),
SLC_VAR("townnametype"),
SLC_VAR("townnameparts"),
SLC_VAR("name"),
SLC_VAR("flags"),
SLC_VAR("statues"),
SLC_NULL(1, SL_MIN_VERSION, SLV_2),
SLC_VAR("have_ratings"),
SLC_VAR("ratings"),
SLC_VAR("unwanted"),
SLC_VAR("supplied[CT_PASSENGERS].old_max"),
SLC_VAR("supplied[CT_MAIL].old_max"),
SLC_VAR("supplied[CT_PASSENGERS].new_max"),
SLC_VAR("supplied[CT_MAIL].new_max"),
SLC_VAR("supplied[CT_PASSENGERS].old_act"),
SLC_VAR("supplied[CT_MAIL].old_act"),
SLC_VAR("supplied[CT_PASSENGERS].new_act"),
SLC_VAR("supplied[CT_MAIL].new_act"),
SLC_NULL(2, SL_MIN_VERSION, SLV_164),
SLC_VAR("received[TE_FOOD].old_act"),
SLC_VAR("received[TE_WATER].old_act"),
SLC_VAR("received[TE_FOOD].new_act"),
SLC_VAR("received[TE_WATER].new_act"),
SLC_VAR("goal"),
SLC_VAR("text"),
SLC_VAR("time_until_rebuild"),
SLC_VAR("grow_counter"),
SLC_VAR("growth_rate"),
SLC_VAR("fund_buildings_months"),
SLC_VAR("road_build_months"),
SLC_VAR("exclusivity"),
SLC_VAR("exclusive_counter"),
SLC_VAR("larger_town"),
SLC_VAR("layout"),
SLC_VAR("psa_list"),
SLC_NULL(4, SLV_166, SLV_EXTEND_CARGOTYPES),
SLC_NULL(8, SLV_EXTEND_CARGOTYPES, SLV_REMOVE_TOWN_CARGO_CACHE),
SLC_NULL(30, SLV_2, SLV_REMOVE_TOWN_CARGO_CACHE),
SLC_VAR("supplied"),
SLC_VAR("received"),
SLC_VAR("acceptance_matrix"),
};
}
#endif /* SAVELOAD_COMPAT_TOWN_H */

@ -0,0 +1,211 @@
/*
* This file is part of OpenTTD.
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file vehicle_sl_compat.h Loading of vehicle chunks before table headers were added. */
#ifndef SAVELOAD_COMPAT_VEHICLE_H
#define SAVELOAD_COMPAT_VEHICLE_H
#include "../saveload.h"
namespace upstream_sl {
/** Original field order for SlVehicleCommon. */
const SaveLoadCompat _vehicle_common_sl_compat[] = {
SLC_VAR("subtype"),
SLC_VAR("next"),
SLC_VAR("name"),
SLC_VAR("unitnumber"),
SLC_VAR("owner"),
SLC_VAR("tile"),
SLC_VAR("dest_tile"),
SLC_VAR("x_pos"),
SLC_VAR("y_pos"),
SLC_VAR("z_pos"),
SLC_VAR("direction"),
SLC_NULL(2, SL_MIN_VERSION, SLV_58),
SLC_VAR("spritenum"),
SLC_NULL(5, SL_MIN_VERSION, SLV_58),
SLC_VAR("engine_type"),
SLC_NULL(2, SL_MIN_VERSION, SLV_152),
SLC_VAR("cur_speed"),
SLC_VAR("subspeed"),
SLC_VAR("acceleration"),
SLC_VAR("motion_counter"),
SLC_VAR("progress"),
SLC_VAR("vehstatus"),
SLC_VAR("last_station_visited"),
SLC_VAR("last_loading_station"),
SLC_VAR("cargo_type"),
SLC_VAR("cargo_subtype"),
SLC_VAR("cargo_days"),
SLC_VAR("cargo_source"),
SLC_VAR("cargo_source_xy"),
SLC_VAR("cargo_cap"),
SLC_VAR("refit_cap"),
SLC_VAR("cargo_count"),
SLC_VAR("cargo.packets"),
SLC_VAR("cargo.action_counts"),
SLC_VAR("cargo_age_counter"),
SLC_VAR("day_counter"),
SLC_VAR("tick_counter"),
SLC_VAR("running_ticks"),
SLC_VAR("cur_implicit_order_index"),
SLC_VAR("cur_real_order_index"),
SLC_NULL(1, SL_MIN_VERSION, SLV_105),
SLC_VAR("current_order.type"),
SLC_VAR("current_order.flags"),
SLC_VAR("current_order.dest"),
SLC_VAR("current_order.refit_cargo"),
SLC_NULL(1, SLV_36, SLV_182),
SLC_VAR("current_order.wait_time"),
SLC_VAR("current_order.travel_time"),
SLC_VAR("current_order.max_speed"),
SLC_VAR("timetable_start"),
SLC_VAR("orders"),
SLC_VAR("age"),
SLC_VAR("max_age"),
SLC_VAR("date_of_last_service"),
SLC_VAR("service_interval"),
SLC_VAR("reliability"),
SLC_VAR("reliability_spd_dec"),
SLC_VAR("breakdown_ctr"),
SLC_VAR("breakdown_delay"),
SLC_VAR("breakdowns_since_last_service"),
SLC_VAR("breakdown_chance"),
SLC_VAR("build_year"),
SLC_VAR("load_unload_ticks"),
SLC_VAR("cargo_paid_for"),
SLC_VAR("vehicle_flags"),
SLC_VAR("profit_this_year"),
SLC_VAR("profit_last_year"),
SLC_VAR("cargo_feeder_share"),
SLC_VAR("cargo_loaded_at_xy"),
SLC_VAR("value"),
SLC_VAR("random_bits"),
SLC_VAR("waiting_triggers"),
SLC_VAR("next_shared"),
SLC_NULL(2, SLV_2, SLV_69),
SLC_NULL(4, SLV_69, SLV_101),
SLC_VAR("group_id"),
SLC_VAR("current_order_time"),
SLC_VAR("lateness_counter"),
SLC_NULL(10, SLV_2, SLV_144),
};
/** Original field order for SlVehicleTrain. */
const SaveLoadCompat _vehicle_train_sl_compat[] = {
SLC_VAR("common"),
SLC_VAR("crash_anim_pos"),
SLC_VAR("force_proceed"),
SLC_VAR("railtype"),
SLC_VAR("track"),
SLC_VAR("flags"),
SLC_NULL(2, SLV_2, SLV_60),
SLC_VAR("wait_counter"),
SLC_NULL(2, SLV_2, SLV_20),
SLC_VAR("gv_flags"),
SLC_NULL(11, SLV_2, SLV_144),
};
/** Original field order for SlVehicleRoadVeh. */
const SaveLoadCompat _vehicle_roadveh_sl_compat[] = {
SLC_VAR("common"),
SLC_VAR("state"),
SLC_VAR("frame"),
SLC_VAR("blocked_ctr"),
SLC_VAR("overtaking"),
SLC_VAR("overtaking_ctr"),
SLC_VAR("crashed_ctr"),
SLC_VAR("reverse_ctr"),
SLC_VAR("path.td"),
SLC_VAR("path.tile"),
SLC_NULL(2, SLV_6, SLV_69),
SLC_VAR("gv_flags"),
SLC_NULL(4, SLV_69, SLV_131),
SLC_NULL(2, SLV_6, SLV_131),
SLC_NULL(16, SLV_2, SLV_144),
};
/** Original field order for SlVehicleShip. */
const SaveLoadCompat _vehicle_ship_sl_compat[] = {
SLC_VAR("common"),
SLC_VAR("state"),
SLC_VAR("path"),
SLC_VAR("rotation"),
SLC_NULL(16, SLV_2, SLV_144),
};
/** Original field order for SlVehicleAircraft. */
const SaveLoadCompat _vehicle_aircraft_sl_compat[] = {
SLC_VAR("common"),
SLC_VAR("crashed_counter"),
SLC_VAR("pos"),
SLC_VAR("targetairport"),
SLC_VAR("state"),
SLC_VAR("previous_pos"),
SLC_VAR("last_direction"),
SLC_VAR("number_consecutive_turns"),
SLC_VAR("turn_counter"),
SLC_VAR("flags"),
SLC_NULL(13, SLV_2, SLV_144),
};
/** Original field order for SlVehicleEffect. */
const SaveLoadCompat _vehicle_effect_sl_compat[] = {
SLC_VAR("subtype"),
SLC_VAR("tile"),
SLC_VAR("x_pos"),
SLC_VAR("y_pos"),
SLC_VAR("z_pos"),
SLC_VAR("sprite_cache.sprite_seq.seq[0].sprite"),
SLC_NULL(5, SL_MIN_VERSION, SLV_59),
SLC_VAR("progress"),
SLC_VAR("vehstatus"),
SLC_VAR("animation_state"),
SLC_VAR("animation_substate"),
SLC_VAR("spritenum"),
SLC_NULL(15, SLV_2, SLV_144),
};
/** Original field order for SlVehicleDisaster. */
const SaveLoadCompat _vehicle_disaster_sl_compat[] = {
SLC_VAR("next"),
SLC_VAR("subtype"),
SLC_VAR("tile"),
SLC_VAR("dest_tile"),
SLC_VAR("x_pos"),
SLC_VAR("y_pos"),
SLC_VAR("z_pos"),
SLC_VAR("direction"),
SLC_NULL(5, SL_MIN_VERSION, SLV_58),
SLC_VAR("owner"),
SLC_VAR("vehstatus"),
SLC_VAR("current_order.dest"),
SLC_VAR("sprite_cache.sprite_seq.seq[0].sprite"),
SLC_VAR("age"),
SLC_VAR("tick_counter"),
SLC_VAR("image_override"),
SLC_VAR("big_ufo_destroyer_target"),
SLC_VAR("flags"),
SLC_NULL(16, SLV_2, SLV_144),
};
/** Original field order for vehicle_desc. */
const SaveLoadCompat _vehicle_sl_compat[] = {
SLC_VAR("type"),
SLC_VAR("train"),
SLC_VAR("roadveh"),
SLC_VAR("ship"),
SLC_VAR("aircraft"),
SLC_VAR("effect"),
SLC_VAR("disaster"),
};
}
#endif /* SAVELOAD_COMPAT_VEHICLE_H */

@ -0,0 +1,78 @@
/*
* This file is part of OpenTTD.
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file depot_sl.cpp Code handling saving and loading of depots */
#include "../../stdafx.h"
#include "saveload.h"
#include "compat/depot_sl_compat.h"
#include "../../depot_base.h"
#include "../../town.h"
#include "../../safeguards.h"
namespace upstream_sl {
static TownID _town_index;
static const SaveLoad _depot_desc[] = {
SLE_CONDVAR(Depot, xy, SLE_FILE_U16 | SLE_VAR_U32, SL_MIN_VERSION, SLV_6),
SLE_CONDVAR(Depot, xy, SLE_UINT32, SLV_6, SL_MAX_VERSION),
SLEG_CONDVAR("town_index", _town_index, SLE_UINT16, SL_MIN_VERSION, SLV_141),
SLE_CONDREF(Depot, town, REF_TOWN, SLV_141, SL_MAX_VERSION),
SLE_CONDVAR(Depot, town_cn, SLE_UINT16, SLV_141, SL_MAX_VERSION),
SLE_CONDSTR(Depot, name, SLE_STR, 0, SLV_141, SL_MAX_VERSION),
SLE_CONDVAR(Depot, build_date, SLE_INT32, SLV_142, SL_MAX_VERSION),
};
struct DEPTChunkHandler : ChunkHandler {
DEPTChunkHandler() : ChunkHandler('DEPT', CH_TABLE) {}
void Save() const override
{
SlTableHeader(_depot_desc);
for (Depot *depot : Depot::Iterate()) {
SlSetArrayIndex(depot->index);
SlObject(depot, _depot_desc);
}
}
void Load() const override
{
const std::vector<SaveLoad> slt = SlCompatTableHeader(_depot_desc, _depot_sl_compat);
int index;
while ((index = SlIterateArray()) != -1) {
Depot *depot = new (index) Depot();
SlObject(depot, slt);
/* Set the town 'pointer' so we can restore it later. */
if (IsSavegameVersionBefore(SLV_141)) depot->town = (Town *)(size_t)_town_index;
}
}
void FixPointers() const override
{
for (Depot *depot : Depot::Iterate()) {
SlObject(depot, _depot_desc);
if (IsSavegameVersionBefore(SLV_141)) depot->town = Town::Get((size_t)depot->town);
}
}
};
static const DEPTChunkHandler DEPT;
static const ChunkHandlerRef depot_chunk_handlers[] = {
DEPT,
};
extern const ChunkHandlerTable _depot_chunk_handlers(depot_chunk_handlers);
}

@ -0,0 +1,109 @@
/*
* This file is part of OpenTTD.
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file economy_sl.cpp Code handling saving and loading of economy data */
#include "../../stdafx.h"
#include "saveload.h"
#include "compat/economy_sl_compat.h"
#include "../../economy_func.h"
#include "../../economy_base.h"
#include "../../safeguards.h"
namespace upstream_sl {
static const SaveLoad _economy_desc[] = {
SLE_CONDVAR(Economy, old_max_loan_unround, SLE_FILE_I32 | SLE_VAR_I64, SL_MIN_VERSION, SLV_65),
SLE_CONDVAR(Economy, old_max_loan_unround, SLE_INT64, SLV_65, SLV_126),
SLE_CONDVAR(Economy, old_max_loan_unround_fract, SLE_UINT16, SLV_70, SLV_126),
SLE_CONDVAR(Economy, inflation_prices, SLE_UINT64, SLV_126, SL_MAX_VERSION),
SLE_CONDVAR(Economy, inflation_payment, SLE_UINT64, SLV_126, 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, SLV_102, SL_MAX_VERSION),
};
/** Economy variables */
struct ECMYChunkHandler : ChunkHandler {
ECMYChunkHandler() : ChunkHandler('ECMY', CH_TABLE) {}
void Save() const override
{
SlTableHeader(_economy_desc);
SlSetArrayIndex(0);
SlObject(&_economy, _economy_desc);
}
void Load() const override
{
const std::vector<SaveLoad> slt = SlCompatTableHeader(_economy_desc, _economy_sl_compat);
if (!IsSavegameVersionBefore(SLV_RIFF_TO_ARRAY) && SlIterateArray() == -1) return;
SlObject(&_economy, slt);
if (!IsSavegameVersionBefore(SLV_RIFF_TO_ARRAY) && SlIterateArray() != -1) SlErrorCorrupt("Too many ECMY entries");
StartupIndustryDailyChanges(IsSavegameVersionBefore(SLV_102)); // old savegames will need to be initialized
}
};
static const SaveLoad _cargopayment_desc[] = {
SLE_REF(CargoPayment, front, REF_VEHICLE),
SLE_VAR(CargoPayment, route_profit, SLE_INT64),
SLE_VAR(CargoPayment, visual_profit, SLE_INT64),
SLE_CONDVAR(CargoPayment, visual_transfer, SLE_INT64, SLV_181, SL_MAX_VERSION),
};
struct CAPYChunkHandler : ChunkHandler {
CAPYChunkHandler() : ChunkHandler('CAPY', CH_TABLE) {}
void Save() const override
{
SlTableHeader(_cargopayment_desc);
for (CargoPayment *cp : CargoPayment::Iterate()) {
SlSetArrayIndex(cp->index);
SlObject(cp, _cargopayment_desc);
}
}
void Load() const override
{
const std::vector<SaveLoad> slt = SlCompatTableHeader(_cargopayment_desc, _cargopayment_sl_compat);
int index;
while ((index = SlIterateArray()) != -1) {
CargoPayment *cp = new (index) CargoPayment();
SlObject(cp, slt);
}
}
void FixPointers() const override
{
for (CargoPayment *cp : CargoPayment::Iterate()) {
SlObject(cp, _cargopayment_desc);
}
}
};
static const CAPYChunkHandler CAPY;
static const ECMYChunkHandler ECMY;
static const ChunkHandlerRef economy_chunk_handlers[] = {
CAPY,
ECMY,
};
extern const ChunkHandlerTable _economy_chunk_handlers(economy_chunk_handlers);
}

@ -0,0 +1,129 @@
/*
* This file is part of OpenTTD.
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file engine_sl.cpp Code handling saving and loading of engines */
#include "../../stdafx.h"
#include "saveload.h"
#include "compat/engine_sl_compat.h"
#include "../../engine_base.h"
#include "../../string_func.h"
#include <vector>
#include "../../safeguards.h"
Engine *GetTempDataEngine(EngineID index);
namespace upstream_sl {
static const SaveLoad _engine_desc[] = {
SLE_CONDVAR(Engine, intro_date, SLE_FILE_U16 | SLE_VAR_I32, SL_MIN_VERSION, SLV_31),
SLE_CONDVAR(Engine, intro_date, SLE_INT32, SLV_31, SL_MAX_VERSION),
SLE_CONDVAR(Engine, age, SLE_FILE_U16 | SLE_VAR_I32, SL_MIN_VERSION, SLV_31),
SLE_CONDVAR(Engine, age, SLE_INT32, SLV_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, flags, SLE_UINT8),
SLE_CONDVAR(Engine, preview_asked, SLE_UINT16, SLV_179, SL_MAX_VERSION),
SLE_CONDVAR(Engine, preview_company, SLE_UINT8, SLV_179, SL_MAX_VERSION),
SLE_VAR(Engine, preview_wait, SLE_UINT8),
SLE_CONDVAR(Engine, company_avail, SLE_FILE_U8 | SLE_VAR_U16, SL_MIN_VERSION, SLV_104),
SLE_CONDVAR(Engine, company_avail, SLE_UINT16, SLV_104, SL_MAX_VERSION),
SLE_CONDVAR(Engine, company_hidden, SLE_UINT16, SLV_193, SL_MAX_VERSION),
SLE_CONDSTR(Engine, name, SLE_STR, 0, SLV_84, SL_MAX_VERSION),
};
struct ENGNChunkHandler : ChunkHandler {
ENGNChunkHandler() : ChunkHandler('ENGN', CH_TABLE) {}
void Save() const override
{
SlTableHeader(_engine_desc);
for (Engine *e : Engine::Iterate()) {
SlSetArrayIndex(e->index);
SlObject(e, _engine_desc);
}
}
void Load() const override
{
const std::vector<SaveLoad> slt = SlCompatTableHeader(_engine_desc, _engine_sl_compat);
/* 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, slt);
if (IsSavegameVersionBefore(SLV_179)) {
/* preview_company_rank was replaced with preview_company and preview_asked.
* Just cancel any previews. */
e->flags &= ~4; // ENGINE_OFFER_WINDOW_OPEN
e->preview_company = INVALID_COMPANY;
e->preview_asked = (CompanyMask)-1;
}
}
}
};
/** Save and load the mapping between the engine id in the pool, and the grf file it came from. */
static const SaveLoad _engine_id_mapping_desc[] = {
SLE_VAR(EngineIDMapping, grfid, SLE_UINT32),
SLE_VAR(EngineIDMapping, internal_id, SLE_UINT16),
SLE_VAR(EngineIDMapping, type, SLE_UINT8),
SLE_VAR(EngineIDMapping, substitute_id, SLE_UINT8),
};
struct EIDSChunkHandler : ChunkHandler {
EIDSChunkHandler() : ChunkHandler('EIDS', CH_TABLE) {}
void Save() const override
{
SlTableHeader(_engine_id_mapping_desc);
uint index = 0;
for (EngineIDMapping &eid : _engine_mngr) {
SlSetArrayIndex(index);
SlObject(&eid, _engine_id_mapping_desc);
index++;
}
}
void Load() const override
{
const std::vector<SaveLoad> slt = SlCompatTableHeader(_engine_id_mapping_desc, _engine_id_mapping_sl_compat);
_engine_mngr.clear();
while (SlIterateArray() != -1) {
EngineIDMapping *eid = &_engine_mngr.emplace_back();
SlObject(eid, slt);
}
}
};
static const EIDSChunkHandler EIDS;
static const ENGNChunkHandler ENGN;
static const ChunkHandlerRef engine_chunk_handlers[] = {
EIDS,
ENGN,
};
extern const ChunkHandlerTable _engine_chunk_handlers(engine_chunk_handlers);
}

@ -0,0 +1,210 @@
/*
* This file is part of OpenTTD.
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file game_sl.cpp Handles the saveload part of the GameScripts */
#include "../../stdafx.h"
#include "../../debug.h"
#include "saveload.h"
#include "compat/game_sl_compat.h"
#include "../../string_func.h"
#include "../../game/game.hpp"
#include "../../game/game_config.hpp"
#include "../../network/network.h"
#include "../../game/game_instance.hpp"
#include "../../game/game_text.hpp"
#include "../../safeguards.h"
extern GameStrings *_current_data;
namespace upstream_sl {
static std::string _game_saveload_name;
static int _game_saveload_version;
static std::string _game_saveload_settings;
static bool _game_saveload_is_random;
static const SaveLoad _game_script_desc[] = {
SLEG_SSTR("name", _game_saveload_name, SLE_STR),
SLEG_SSTR("settings", _game_saveload_settings, SLE_STR),
SLEG_VAR("version", _game_saveload_version, SLE_UINT32),
SLEG_VAR("is_random", _game_saveload_is_random, SLE_BOOL),
};
static void SaveReal_GSDT(int *index_ptr)
{
GameConfig *config = GameConfig::GetConfig();
if (config->HasScript()) {
_game_saveload_name = config->GetName();
_game_saveload_version = config->GetVersion();
} else {
/* No GameScript is configured for this so store an empty string as name. */
_game_saveload_name.clear();
_game_saveload_version = -1;
}
_game_saveload_is_random = config->IsRandom();
_game_saveload_settings = config->SettingsToString();
SlObject(nullptr, _game_script_desc);
Game::Save();
}
struct GSDTChunkHandler : ChunkHandler {
GSDTChunkHandler() : ChunkHandler('GSDT', CH_TABLE) {}
void Load() const override
{
const std::vector<SaveLoad> slt = SlCompatTableHeader(_game_script_desc, _game_script_sl_compat);
/* Free all current data */
GameConfig::GetConfig(GameConfig::SSS_FORCE_GAME)->Change(nullptr);
if (SlIterateArray() == -1) return;
_game_saveload_version = -1;
SlObject(nullptr, slt);
if (_networking && !_network_server) {
GameInstance::LoadEmpty();
if (SlIterateArray() != -1) SlErrorCorrupt("Too many GameScript configs");
return;
}
GameConfig *config = GameConfig::GetConfig(GameConfig::SSS_FORCE_GAME);
if (!_game_saveload_name.empty()) {
config->Change(_game_saveload_name.c_str(), _game_saveload_version, false, _game_saveload_is_random);
if (!config->HasScript()) {
/* No version of the GameScript available that can load the data. Try to load the
* latest version of the GameScript instead. */
config->Change(_game_saveload_name.c_str(), -1, false, _game_saveload_is_random);
if (!config->HasScript()) {
if (_game_saveload_name.compare("%_dummy") != 0) {
DEBUG(script, 0, "The savegame has an GameScript by the name '%s', version %u which is no longer available.", _game_saveload_name.c_str(), _game_saveload_version);
DEBUG(script, 0, "This game will continue to run without GameScript.");
} else {
DEBUG(script, 0, "The savegame had no GameScript available at the time of saving.");
DEBUG(script, 0, "This game will continue to run without GameScript.");
}
} else {
DEBUG(script, 0, "The savegame has an GameScript by the name '%s', version %u which is no longer available.", _game_saveload_name.c_str(), _game_saveload_version);
DEBUG(script, 0, "The latest version of that GameScript has been loaded instead, but it'll not get the savegame data as it's incompatible.");
}
/* Make sure the GameScript doesn't get the saveload data, as it was not the
* writer of the saveload data in the first place */
_game_saveload_version = -1;
}
}
config->StringToSettings(_game_saveload_settings);
/* Start the GameScript directly if it was active in the savegame */
Game::StartNew();
Game::Load(_game_saveload_version);
if (SlIterateArray() != -1) SlErrorCorrupt("Too many GameScript configs");
}
void Save() const override
{
SlTableHeader(_game_script_desc);
SlSetArrayIndex(0);
SlAutolength((AutolengthProc *)SaveReal_GSDT, nullptr);
}
};
static std::string _game_saveload_string;
static uint32 _game_saveload_strings;
class SlGameLanguageString : public DefaultSaveLoadHandler<SlGameLanguageString, LanguageStrings> {
public:
inline static const SaveLoad description[] = {
SLEG_SSTR("string", _game_saveload_string, SLE_STR | SLF_ALLOW_CONTROL),
};
inline const static SaveLoadCompatTable compat_description = _game_language_string_sl_compat;
void Save(LanguageStrings *ls) const override
{
SlSetStructListLength(ls->lines.size());
for (const auto &string : ls->lines) {
_game_saveload_string = string;
SlObject(nullptr, this->GetDescription());
}
}
void Load(LanguageStrings *ls) const override
{
uint32 length = IsSavegameVersionBefore(SLV_SAVELOAD_LIST_LENGTH) ? _game_saveload_strings : (uint32)SlGetStructListLength(UINT32_MAX);
for (uint32 i = 0; i < length; i++) {
SlObject(nullptr, this->GetLoadDescription());
ls->lines.emplace_back(_game_saveload_string);
}
}
};
static const SaveLoad _game_language_desc[] = {
SLE_SSTR(LanguageStrings, language, SLE_STR),
SLEG_CONDVAR("count", _game_saveload_strings, SLE_UINT32, SL_MIN_VERSION, SLV_SAVELOAD_LIST_LENGTH),
SLEG_STRUCTLIST("strings", SlGameLanguageString),
};
struct GSTRChunkHandler : ChunkHandler {
GSTRChunkHandler() : ChunkHandler('GSTR', CH_TABLE) {}
void Load() const override
{
const std::vector<SaveLoad> slt = SlCompatTableHeader(_game_language_desc, _game_language_sl_compat);
delete _current_data;
_current_data = new GameStrings();
while (SlIterateArray() != -1) {
LanguageStrings ls;
SlObject(&ls, slt);
_current_data->raw_strings.push_back(std::move(ls));
}
/* If there were no strings in the savegame, set GameStrings to nullptr */
if (_current_data->raw_strings.size() == 0) {
delete _current_data;
_current_data = nullptr;
return;
}
_current_data->Compile();
ReconsiderGameScriptLanguage();
}
void Save() const override
{
SlTableHeader(_game_language_desc);
if (_current_data == nullptr) return;
for (uint i = 0; i < _current_data->raw_strings.size(); i++) {
SlSetArrayIndex(i);
SlObject(&_current_data->raw_strings[i], _game_language_desc);
}
}
};
static const GSTRChunkHandler GSTR;
static const GSDTChunkHandler GSDT;
static const ChunkHandlerRef game_chunk_handlers[] = {
GSTR,
GSDT,
};
extern const ChunkHandlerTable _game_chunk_handlers(game_chunk_handlers);
}

@ -0,0 +1,416 @@
/*
* This file is part of OpenTTD.
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file gamelog_sl.cpp Code handling saving and loading of gamelog data */
#include "../../stdafx.h"
#include "saveload.h"
#include "compat/gamelog_sl_compat.h"
#include "../../gamelog_internal.h"
#include "../../fios.h"
#include "../../safeguards.h"
namespace upstream_sl {
class SlGamelogMode : public DefaultSaveLoadHandler<SlGamelogMode, LoggedChange> {
public:
inline static const SaveLoad description[] = {
SLE_VAR(LoggedChange, mode.mode, SLE_UINT8),
SLE_VAR(LoggedChange, mode.landscape, SLE_UINT8),
};
inline const static SaveLoadCompatTable compat_description = _gamelog_mode_sl_compat;
void Save(LoggedChange *lc) const override
{
if (lc->ct != GLCT_MODE) return;
SlObject(lc, this->GetDescription());
}
void Load(LoggedChange *lc) const override
{
if (lc->ct != GLCT_MODE) return;
SlObject(lc, this->GetLoadDescription());
}
void LoadCheck(LoggedChange *lc) const override { this->Load(lc); }
};
class SlGamelogRevision : public DefaultSaveLoadHandler<SlGamelogRevision, LoggedChange> {
public:
inline static const SaveLoad description[] = {
SLE_ARR(LoggedChange, revision.text, SLE_UINT8, GAMELOG_REVISION_LENGTH),
SLE_VAR(LoggedChange, revision.newgrf, SLE_UINT32),
SLE_VAR(LoggedChange, revision.slver, SLE_UINT16),
SLE_VAR(LoggedChange, revision.modified, SLE_UINT8),
};
inline const static SaveLoadCompatTable compat_description = _gamelog_revision_sl_compat;
void Save(LoggedChange *lc) const override
{
if (lc->ct != GLCT_REVISION) return;
SlObject(lc, this->GetDescription());
}
void Load(LoggedChange *lc) const override
{
if (lc->ct != GLCT_REVISION) return;
SlObject(lc, this->GetLoadDescription());
}
void LoadCheck(LoggedChange *lc) const override { this->Load(lc); }
};
class SlGamelogOldver : public DefaultSaveLoadHandler<SlGamelogOldver, LoggedChange> {
public:
inline static const SaveLoad description[] = {
SLE_VAR(LoggedChange, oldver.type, SLE_UINT32),
SLE_VAR(LoggedChange, oldver.version, SLE_UINT32),
};
inline const static SaveLoadCompatTable compat_description = _gamelog_oldver_sl_compat;
void Save(LoggedChange *lc) const override
{
if (lc->ct != GLCT_OLDVER) return;
SlObject(lc, this->GetDescription());
}
void Load(LoggedChange *lc) const override
{
if (lc->ct != GLCT_OLDVER) return;
SlObject(lc, this->GetLoadDescription());
}
void LoadCheck(LoggedChange *lc) const override { this->Load(lc); }
};
class SlGamelogSetting : public DefaultSaveLoadHandler<SlGamelogSetting, LoggedChange> {
public:
inline static const SaveLoad description[] = {
SLE_STR(LoggedChange, setting.name, SLE_STR, 128),
SLE_VAR(LoggedChange, setting.oldval, SLE_INT32),
SLE_VAR(LoggedChange, setting.newval, SLE_INT32),
};
inline const static SaveLoadCompatTable compat_description = _gamelog_setting_sl_compat;
void Save(LoggedChange *lc) const override
{
if (lc->ct != GLCT_SETTING) return;
SlObject(lc, this->GetDescription());
}
void Load(LoggedChange *lc) const override
{
if (lc->ct != GLCT_SETTING) return;
SlObject(lc, this->GetLoadDescription());
}
void LoadCheck(LoggedChange *lc) const override { this->Load(lc); }
};
class SlGamelogGrfadd : public DefaultSaveLoadHandler<SlGamelogGrfadd, LoggedChange> {
public:
inline static const SaveLoad description[] = {
SLE_VAR(LoggedChange, grfadd.grfid, SLE_UINT32 ),
SLE_ARR(LoggedChange, grfadd.md5sum, SLE_UINT8, 16),
};
inline const static SaveLoadCompatTable compat_description = _gamelog_grfadd_sl_compat;
void Save(LoggedChange *lc) const override
{
if (lc->ct != GLCT_GRFADD) return;
SlObject(lc, this->GetDescription());
}
void Load(LoggedChange *lc) const override
{
if (lc->ct != GLCT_GRFADD) return;
SlObject(lc, this->GetLoadDescription());
}
void LoadCheck(LoggedChange *lc) const override { this->Load(lc); }
};
class SlGamelogGrfrem : public DefaultSaveLoadHandler<SlGamelogGrfrem, LoggedChange> {
public:
inline static const SaveLoad description[] = {
SLE_VAR(LoggedChange, grfrem.grfid, SLE_UINT32),
};
inline const static SaveLoadCompatTable compat_description = _gamelog_grfrem_sl_compat;
void Save(LoggedChange *lc) const override
{
if (lc->ct != GLCT_GRFREM) return;
SlObject(lc, this->GetDescription());
}
void Load(LoggedChange *lc) const override
{
if (lc->ct != GLCT_GRFREM) return;
SlObject(lc, this->GetLoadDescription());
}
void LoadCheck(LoggedChange *lc) const override { this->Load(lc); }
};
class SlGamelogGrfcompat : public DefaultSaveLoadHandler<SlGamelogGrfcompat, LoggedChange> {
public:
inline static const SaveLoad description[] = {
SLE_VAR(LoggedChange, grfcompat.grfid, SLE_UINT32 ),
SLE_ARR(LoggedChange, grfcompat.md5sum, SLE_UINT8, 16),
};
inline const static SaveLoadCompatTable compat_description = _gamelog_grfcompat_sl_compat;
void Save(LoggedChange *lc) const override
{
if (lc->ct != GLCT_GRFCOMPAT) return;
SlObject(lc, this->GetDescription());
}
void Load(LoggedChange *lc) const override
{
if (lc->ct != GLCT_GRFCOMPAT) return;
SlObject(lc, this->GetLoadDescription());
}
void LoadCheck(LoggedChange *lc) const override { this->Load(lc); }
};
class SlGamelogGrfparam : public DefaultSaveLoadHandler<SlGamelogGrfparam, LoggedChange> {
public:
inline static const SaveLoad description[] = {
SLE_VAR(LoggedChange, grfparam.grfid, SLE_UINT32),
};
inline const static SaveLoadCompatTable compat_description = _gamelog_grfparam_sl_compat;
void Save(LoggedChange *lc) const override
{
if (lc->ct != GLCT_GRFPARAM) return;
SlObject(lc, this->GetDescription());
}
void Load(LoggedChange *lc) const override
{
if (lc->ct != GLCT_GRFPARAM) return;
SlObject(lc, this->GetLoadDescription());
}
void LoadCheck(LoggedChange *lc) const override { this->Load(lc); }
};
class SlGamelogGrfmove : public DefaultSaveLoadHandler<SlGamelogGrfmove, LoggedChange> {
public:
inline static const SaveLoad description[] = {
SLE_VAR(LoggedChange, grfmove.grfid, SLE_UINT32),
SLE_VAR(LoggedChange, grfmove.offset, SLE_INT32),
};
inline const static SaveLoadCompatTable compat_description = _gamelog_grfmove_sl_compat;
void Save(LoggedChange *lc) const override
{
if (lc->ct != GLCT_GRFMOVE) return;
SlObject(lc, this->GetDescription());
}
void Load(LoggedChange *lc) const override
{
if (lc->ct != GLCT_GRFMOVE) return;
SlObject(lc, this->GetLoadDescription());
}
void LoadCheck(LoggedChange *lc) const override { this->Load(lc); }
};
class SlGamelogGrfbug : public DefaultSaveLoadHandler<SlGamelogGrfbug, LoggedChange> {
public:
inline static const SaveLoad description[] = {
SLE_VAR(LoggedChange, grfbug.data, SLE_UINT64),
SLE_VAR(LoggedChange, grfbug.grfid, SLE_UINT32),
SLE_VAR(LoggedChange, grfbug.bug, SLE_UINT8),
};
inline const static SaveLoadCompatTable compat_description = _gamelog_grfbug_sl_compat;
void Save(LoggedChange *lc) const override
{
if (lc->ct != GLCT_GRFBUG) return;
SlObject(lc, this->GetDescription());
}
void Load(LoggedChange *lc) const override
{
if (lc->ct != GLCT_GRFBUG) return;
SlObject(lc, this->GetLoadDescription());
}
void LoadCheck(LoggedChange *lc) const override { this->Load(lc); }
};
static bool _is_emergency_save = true;
class SlGamelogEmergency : public DefaultSaveLoadHandler<SlGamelogEmergency, LoggedChange> {
public:
/* We need to store something, so store a "true" value. */
inline static const SaveLoad description[] = {
SLEG_CONDVAR("is_emergency_save", _is_emergency_save, SLE_BOOL, SLV_RIFF_TO_ARRAY, SL_MAX_VERSION),
};
inline const static SaveLoadCompatTable compat_description = _gamelog_emergency_sl_compat;
void Save(LoggedChange *lc) const override
{
if (lc->ct != GLCT_EMERGENCY) return;
_is_emergency_save = true;
SlObject(lc, this->GetDescription());
}
void Load(LoggedChange *lc) const override
{
if (lc->ct != GLCT_EMERGENCY) return;
SlObject(lc, this->GetLoadDescription());
}
void LoadCheck(LoggedChange *lc) const override { this->Load(lc); }
};
class SlGamelogAction : public DefaultSaveLoadHandler<SlGamelogAction, LoggedAction> {
public:
inline static const SaveLoad description[] = {
SLE_SAVEBYTE(LoggedChange, ct),
SLEG_STRUCT("mode", SlGamelogMode),
SLEG_STRUCT("revision", SlGamelogRevision),
SLEG_STRUCT("oldver", SlGamelogOldver),
SLEG_STRUCT("setting", SlGamelogSetting),
SLEG_STRUCT("grfadd", SlGamelogGrfadd),
SLEG_STRUCT("grfrem", SlGamelogGrfrem),
SLEG_STRUCT("grfcompat", SlGamelogGrfcompat),
SLEG_STRUCT("grfparam", SlGamelogGrfparam),
SLEG_STRUCT("grfmove", SlGamelogGrfmove),
SLEG_STRUCT("grfbug", SlGamelogGrfbug),
SLEG_STRUCT("emergency", SlGamelogEmergency),
};
inline const static SaveLoadCompatTable compat_description = _gamelog_action_sl_compat;
void Save(LoggedAction *la) const override
{
SlSetStructListLength(la->changes);
const LoggedChange *lcend = &la->change[la->changes];
for (LoggedChange *lc = la->change; lc != lcend; lc++) {
assert((uint)lc->ct < GLCT_END);
SlObject(lc, this->GetDescription());
}
}
void Load(LoggedAction *la) const override
{
if (IsSavegameVersionBefore(SLV_RIFF_TO_ARRAY)) {
byte type;
while ((type = SlReadByte()) != GLCT_NONE) {
if (type >= GLCT_END) SlErrorCorrupt("Invalid gamelog change type");
GamelogChangeType ct = (GamelogChangeType)type;
la->change = ReallocT(la->change, la->changes + 1);
LoggedChange *lc = &la->change[la->changes++];
memset(lc, 0, sizeof(*lc));
lc->ct = ct;
SlObject(lc, this->GetLoadDescription());
}
return;
}
size_t length = SlGetStructListLength(UINT32_MAX);
la->change = ReallocT(la->change, length);
for (size_t i = 0; i < length; i++) {
LoggedChange *lc = &la->change[i];
memset(lc, 0, sizeof(*lc));
lc->ct = (GamelogChangeType)SlReadByte();
SlObject(lc, this->GetLoadDescription());
}
}
void LoadCheck(LoggedAction *la) const override { this->Load(la); }
};
static const SaveLoad _gamelog_desc[] = {
SLE_CONDVAR(LoggedAction, at, SLE_UINT8, SLV_RIFF_TO_ARRAY, SL_MAX_VERSION),
SLE_VAR(LoggedAction, tick, SLE_UINT16),
SLEG_STRUCTLIST("action", SlGamelogAction),
};
struct GLOGChunkHandler : ChunkHandler {
GLOGChunkHandler() : ChunkHandler('GLOG', CH_TABLE) {}
void LoadCommon(LoggedAction *&gamelog_action, uint &gamelog_actions) const
{
assert(gamelog_action == nullptr);
assert(gamelog_actions == 0);
const std::vector<SaveLoad> slt = SlCompatTableHeader(_gamelog_desc, _gamelog_sl_compat);
if (IsSavegameVersionBefore(SLV_RIFF_TO_ARRAY)) {
byte type;
while ((type = SlReadByte()) != GLAT_NONE) {
if (type >= GLAT_END) SlErrorCorrupt("Invalid gamelog action type");
gamelog_action = ReallocT(gamelog_action, gamelog_actions + 1);
LoggedAction *la = &gamelog_action[gamelog_actions++];
memset(la, 0, sizeof(*la));
la->at = (GamelogActionType)type;
SlObject(la, slt);
}
return;
}
while (SlIterateArray() != -1) {
gamelog_action = ReallocT(gamelog_action, gamelog_actions + 1);
LoggedAction *la = &gamelog_action[gamelog_actions++];
memset(la, 0, sizeof(*la));
SlObject(la, slt);
}
}
void Save() const override
{
SlTableHeader(_gamelog_desc);
const LoggedAction *laend = &_gamelog_action[_gamelog_actions];
uint i = 0;
for (LoggedAction *la = _gamelog_action; la != laend; la++, i++) {
SlSetArrayIndex(i);
SlObject(la, _gamelog_desc);
}
}
void Load() const override
{
this->LoadCommon(_gamelog_action, _gamelog_actions);
}
void LoadCheck(size_t) const override
{
this->LoadCommon(_load_check_data.gamelog_action, _load_check_data.gamelog_actions);
}
};
static const GLOGChunkHandler GLOG;
static const ChunkHandlerRef gamelog_chunk_handlers[] = {
GLOG,
};
extern const ChunkHandlerTable _gamelog_chunk_handlers(gamelog_chunk_handlers);
}

@ -0,0 +1,62 @@
/*
* This file is part of OpenTTD.
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file goal_sl.cpp Code handling saving and loading of goals */
#include "../../stdafx.h"
#include "saveload.h"
#include "compat/goal_sl_compat.h"
#include "../../goal_base.h"
#include "../../safeguards.h"
namespace upstream_sl {
static const SaveLoad _goals_desc[] = {
SLE_VAR(Goal, company, SLE_FILE_U16 | SLE_VAR_U8),
SLE_VAR(Goal, type, SLE_FILE_U16 | SLE_VAR_U8),
SLE_VAR(Goal, dst, SLE_UINT32),
SLE_STR(Goal, text, SLE_STR | SLF_ALLOW_CONTROL, 0),
SLE_CONDSTR(Goal, progress, SLE_STR | SLF_ALLOW_CONTROL, 0, SLV_182, SL_MAX_VERSION),
SLE_CONDVAR(Goal, completed, SLE_BOOL, SLV_182, SL_MAX_VERSION),
};
struct GOALChunkHandler : ChunkHandler {
GOALChunkHandler() : ChunkHandler('GOAL', CH_TABLE) {}
void Save() const override
{
SlTableHeader(_goals_desc);
for (Goal *s : Goal::Iterate()) {
SlSetArrayIndex(s->index);
SlObject(s, _goals_desc);
}
}
void Load() const override
{
const std::vector<SaveLoad> slt = SlCompatTableHeader(_goals_desc, _goals_sl_compat);
int index;
while ((index = SlIterateArray()) != -1) {
Goal *s = new (index) Goal();
SlObject(s, slt);
}
}
};
static const GOALChunkHandler GOAL;
static const ChunkHandlerRef goal_chunk_handlers[] = {
GOAL,
};
extern const ChunkHandlerTable _goal_chunk_handlers(goal_chunk_handlers);
}

@ -0,0 +1,75 @@
/*
* This file is part of OpenTTD.
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file group_sl.cpp Code handling saving and loading of economy data */
#include "../../stdafx.h"
#include "../../group.h"
#include "../../company_base.h"
#include "saveload.h"
#include "compat/group_sl_compat.h"
#include "../../safeguards.h"
namespace upstream_sl {
static const SaveLoad _group_desc[] = {
SLE_CONDVAR(Group, name, SLE_NAME, SL_MIN_VERSION, SLV_84),
SLE_CONDSSTR(Group, name, SLE_STR | SLF_ALLOW_CONTROL, SLV_84, SL_MAX_VERSION),
SLE_VAR(Group, owner, SLE_UINT8),
SLE_VAR(Group, vehicle_type, SLE_UINT8),
SLE_VAR(Group, flags, SLE_UINT8),
SLE_CONDVAR(Group, livery.in_use, SLE_UINT8, SLV_GROUP_LIVERIES, SL_MAX_VERSION),
SLE_CONDVAR(Group, livery.colour1, SLE_UINT8, SLV_GROUP_LIVERIES, SL_MAX_VERSION),
SLE_CONDVAR(Group, livery.colour2, SLE_UINT8, SLV_GROUP_LIVERIES, SL_MAX_VERSION),
SLE_CONDVAR(Group, parent, SLE_UINT16, SLV_189, SL_MAX_VERSION),
};
struct GRPSChunkHandler : ChunkHandler {
GRPSChunkHandler() : ChunkHandler('GRPS', CH_TABLE) {}
void Save() const override
{
SlTableHeader(_group_desc);
for (Group *g : Group::Iterate()) {
SlSetArrayIndex(g->index);
SlObject(g, _group_desc);
}
}
void Load() const override
{
const std::vector<SaveLoad> slt = SlCompatTableHeader(_group_desc, _group_sl_compat);
int index;
while ((index = SlIterateArray()) != -1) {
Group *g = new (index) Group();
SlObject(g, slt);
if (IsSavegameVersionBefore(SLV_189)) g->parent = INVALID_GROUP;
if (IsSavegameVersionBefore(SLV_GROUP_LIVERIES)) {
const Company *c = Company::Get(g->owner);
g->livery.colour1 = c->livery[LS_DEFAULT].colour1;
g->livery.colour2 = c->livery[LS_DEFAULT].colour2;
}
}
}
};
static const GRPSChunkHandler GRPS;
static const ChunkHandlerRef group_chunk_handlers[] = {
GRPS,
};
extern const ChunkHandlerTable _group_chunk_handlers(group_chunk_handlers);
}

@ -0,0 +1,212 @@
/*
* This file is part of OpenTTD.
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file industry_sl.cpp Code handling saving and loading of industries */
#include "../../stdafx.h"
#include "saveload.h"
#include "compat/industry_sl_compat.h"
#include "../../industry.h"
#include "newgrf_sl.h"
#include "../../safeguards.h"
namespace upstream_sl {
static OldPersistentStorage _old_ind_persistent_storage;
static const SaveLoad _industry_desc[] = {
SLE_CONDVAR(Industry, location.tile, SLE_FILE_U16 | SLE_VAR_U32, SL_MIN_VERSION, SLV_6),
SLE_CONDVAR(Industry, location.tile, SLE_UINT32, SLV_6, SL_MAX_VERSION),
SLE_VAR(Industry, location.w, SLE_FILE_U8 | SLE_VAR_U16),
SLE_VAR(Industry, location.h, SLE_FILE_U8 | SLE_VAR_U16),
SLE_REF(Industry, town, REF_TOWN),
SLE_CONDREF(Industry, neutral_station, REF_STATION, SLV_SERVE_NEUTRAL_INDUSTRIES, SL_MAX_VERSION),
SLE_CONDARR(Industry, produced_cargo, SLE_UINT8, 2, SLV_78, SLV_EXTEND_INDUSTRY_CARGO_SLOTS),
SLE_CONDARR(Industry, produced_cargo, SLE_UINT8, 16, SLV_EXTEND_INDUSTRY_CARGO_SLOTS, SL_MAX_VERSION),
SLE_CONDARR(Industry, incoming_cargo_waiting, SLE_UINT16, 3, SLV_70, SLV_EXTEND_INDUSTRY_CARGO_SLOTS),
SLE_CONDARR(Industry, incoming_cargo_waiting, SLE_UINT16, 16, SLV_EXTEND_INDUSTRY_CARGO_SLOTS, SL_MAX_VERSION),
SLE_CONDARR(Industry, produced_cargo_waiting, SLE_UINT16, 2, SL_MIN_VERSION, SLV_EXTEND_INDUSTRY_CARGO_SLOTS),
SLE_CONDARR(Industry, produced_cargo_waiting, SLE_UINT16, 16, SLV_EXTEND_INDUSTRY_CARGO_SLOTS, SL_MAX_VERSION),
SLE_CONDARR(Industry, production_rate, SLE_UINT8, 2, SL_MIN_VERSION, SLV_EXTEND_INDUSTRY_CARGO_SLOTS),
SLE_CONDARR(Industry, production_rate, SLE_UINT8, 16, SLV_EXTEND_INDUSTRY_CARGO_SLOTS, SL_MAX_VERSION),
SLE_CONDARR(Industry, accepts_cargo, SLE_UINT8, 3, SLV_78, SLV_EXTEND_INDUSTRY_CARGO_SLOTS),
SLE_CONDARR(Industry, accepts_cargo, SLE_UINT8, 16, SLV_EXTEND_INDUSTRY_CARGO_SLOTS, SL_MAX_VERSION),
SLE_VAR(Industry, prod_level, SLE_UINT8),
SLE_CONDARR(Industry, this_month_production, SLE_UINT16, 2, SL_MIN_VERSION, SLV_EXTEND_INDUSTRY_CARGO_SLOTS),
SLE_CONDARR(Industry, this_month_production, SLE_UINT16, 16, SLV_EXTEND_INDUSTRY_CARGO_SLOTS, SL_MAX_VERSION),
SLE_CONDARR(Industry, this_month_transported, SLE_UINT16, 2, SL_MIN_VERSION, SLV_EXTEND_INDUSTRY_CARGO_SLOTS),
SLE_CONDARR(Industry, this_month_transported, SLE_UINT16, 16, SLV_EXTEND_INDUSTRY_CARGO_SLOTS, SL_MAX_VERSION),
SLE_CONDARR(Industry, last_month_pct_transported, SLE_UINT8, 2, SL_MIN_VERSION, SLV_EXTEND_INDUSTRY_CARGO_SLOTS),
SLE_CONDARR(Industry, last_month_pct_transported, SLE_UINT8, 16, SLV_EXTEND_INDUSTRY_CARGO_SLOTS, SL_MAX_VERSION),
SLE_CONDARR(Industry, last_month_production, SLE_UINT16, 2, SL_MIN_VERSION, SLV_EXTEND_INDUSTRY_CARGO_SLOTS),
SLE_CONDARR(Industry, last_month_production, SLE_UINT16, 16, SLV_EXTEND_INDUSTRY_CARGO_SLOTS, SL_MAX_VERSION),
SLE_CONDARR(Industry, last_month_transported, SLE_UINT16, 2, SL_MIN_VERSION, SLV_EXTEND_INDUSTRY_CARGO_SLOTS),
SLE_CONDARR(Industry, last_month_transported, SLE_UINT16, 16, SLV_EXTEND_INDUSTRY_CARGO_SLOTS, SL_MAX_VERSION),
SLE_VAR(Industry, counter, SLE_UINT16),
SLE_VAR(Industry, type, SLE_UINT8),
SLE_VAR(Industry, owner, SLE_UINT8),
SLE_VAR(Industry, random_colour, SLE_UINT8),
SLE_CONDVAR(Industry, last_prod_year, SLE_FILE_U8 | SLE_VAR_I32, SL_MIN_VERSION, SLV_31),
SLE_CONDVAR(Industry, last_prod_year, SLE_INT32, SLV_31, SL_MAX_VERSION),
SLE_VAR(Industry, was_cargo_delivered, SLE_UINT8),
SLE_CONDVAR(Industry, ctlflags, SLE_UINT8, SLV_GS_INDUSTRY_CONTROL, SL_MAX_VERSION),
SLE_CONDVAR(Industry, founder, SLE_UINT8, SLV_70, SL_MAX_VERSION),
SLE_CONDVAR(Industry, construction_date, SLE_INT32, SLV_70, SL_MAX_VERSION),
SLE_CONDVAR(Industry, construction_type, SLE_UINT8, SLV_70, SL_MAX_VERSION),
SLE_CONDVAR(Industry, last_cargo_accepted_at[0], SLE_INT32, SLV_70, SLV_EXTEND_INDUSTRY_CARGO_SLOTS),
SLE_CONDARR(Industry, last_cargo_accepted_at, SLE_INT32, 16, SLV_EXTEND_INDUSTRY_CARGO_SLOTS, SL_MAX_VERSION),
SLE_CONDVAR(Industry, selected_layout, SLE_UINT8, SLV_73, SL_MAX_VERSION),
SLE_CONDVAR(Industry, exclusive_supplier, SLE_UINT8, SLV_GS_INDUSTRY_CONTROL, SL_MAX_VERSION),
SLE_CONDVAR(Industry, exclusive_consumer, SLE_UINT8, SLV_GS_INDUSTRY_CONTROL, SL_MAX_VERSION),
SLEG_CONDARR("storage", _old_ind_persistent_storage.storage, SLE_UINT32, 16, SLV_76, SLV_161),
SLE_CONDREF(Industry, psa, REF_STORAGE, SLV_161, SL_MAX_VERSION),
SLE_CONDVAR(Industry, random, SLE_UINT16, SLV_82, SL_MAX_VERSION),
SLE_CONDSSTR(Industry, text, SLE_STR | SLF_ALLOW_CONTROL, SLV_INDUSTRY_TEXT, SL_MAX_VERSION),
};
struct INDYChunkHandler : ChunkHandler {
INDYChunkHandler() : ChunkHandler('INDY', CH_TABLE) {}
void Save() const override
{
SlTableHeader(_industry_desc);
/* Write the industries */
for (Industry *ind : Industry::Iterate()) {
SlSetArrayIndex(ind->index);
SlObject(ind, _industry_desc);
}
}
void Load() const override
{
const std::vector<SaveLoad> slt = SlCompatTableHeader(_industry_desc, _industry_sl_compat);
int index;
Industry::ResetIndustryCounts();
while ((index = SlIterateArray()) != -1) {
Industry *i = new (index) Industry();
SlObject(i, slt);
/* Before savegame version 161, persistent storages were not stored in a pool. */
if (IsSavegameVersionBefore(SLV_161) && !IsSavegameVersionBefore(SLV_76)) {
/* Store the old persistent storage. The GRFID will be added later. */
assert(PersistentStorage::CanAllocateItem());
i->psa = new PersistentStorage(0, 0, 0);
memcpy(i->psa->storage, _old_ind_persistent_storage.storage, sizeof(_old_ind_persistent_storage.storage));
}
Industry::IncIndustryTypeCount(i->type);
}
}
void FixPointers() const override
{
for (Industry *i : Industry::Iterate()) {
SlObject(i, _industry_desc);
}
}
};
struct IIDSChunkHandler : NewGRFMappingChunkHandler {
IIDSChunkHandler() : NewGRFMappingChunkHandler('IIDS', _industry_mngr) {}
};
struct TIDSChunkHandler : NewGRFMappingChunkHandler {
TIDSChunkHandler() : NewGRFMappingChunkHandler('TIDS', _industile_mngr) {}
};
/** Description of the data to save and load in #IndustryBuildData. */
static const SaveLoad _industry_builder_desc[] = {
SLEG_VAR("wanted_inds", _industry_builder.wanted_inds, SLE_UINT32),
};
/** Industry builder. */
struct IBLDChunkHandler : ChunkHandler {
IBLDChunkHandler() : ChunkHandler('IBLD', CH_TABLE) {}
void Save() const override
{
SlTableHeader(_industry_builder_desc);
SlSetArrayIndex(0);
SlGlobList(_industry_builder_desc);
}
void Load() const override
{
const std::vector<SaveLoad> slt = SlCompatTableHeader(_industry_builder_desc, _industry_builder_sl_compat);
if (!IsSavegameVersionBefore(SLV_RIFF_TO_ARRAY) && SlIterateArray() == -1) return;
SlGlobList(slt);
if (!IsSavegameVersionBefore(SLV_RIFF_TO_ARRAY) && SlIterateArray() != -1) SlErrorCorrupt("Too many IBLD entries");
}
};
/** Description of the data to save and load in #IndustryTypeBuildData. */
static const SaveLoad _industrytype_builder_desc[] = {
SLE_VAR(IndustryTypeBuildData, probability, SLE_UINT32),
SLE_VAR(IndustryTypeBuildData, min_number, SLE_UINT8),
SLE_VAR(IndustryTypeBuildData, target_count, SLE_UINT16),
SLE_VAR(IndustryTypeBuildData, max_wait, SLE_UINT16),
SLE_VAR(IndustryTypeBuildData, wait_count, SLE_UINT16),
};
/** Industry-type build data. */
struct ITBLChunkHandler : ChunkHandler {
ITBLChunkHandler() : ChunkHandler('ITBL', CH_TABLE) {}
void Save() const override
{
SlTableHeader(_industrytype_builder_desc);
for (int i = 0; i < NUM_INDUSTRYTYPES; i++) {
SlSetArrayIndex(i);
SlObject(_industry_builder.builddata + i, _industrytype_builder_desc);
}
}
void Load() const override
{
const std::vector<SaveLoad> slt = SlCompatTableHeader(_industrytype_builder_desc, _industrytype_builder_sl_compat);
for (IndustryType it = 0; it < NUM_INDUSTRYTYPES; it++) {
_industry_builder.builddata[it].Reset();
}
int index;
while ((index = SlIterateArray()) != -1) {
if ((uint)index >= NUM_INDUSTRYTYPES) SlErrorCorrupt("Too many industry builder datas");
SlObject(_industry_builder.builddata + index, slt);
}
}
};
static const INDYChunkHandler INDY;
static const IIDSChunkHandler IIDS;
static const TIDSChunkHandler TIDS;
static const IBLDChunkHandler IBLD;
static const ITBLChunkHandler ITBL;
static const ChunkHandlerRef industry_chunk_handlers[] = {
INDY,
IIDS,
TIDS,
IBLD,
ITBL,
};
extern const ChunkHandlerTable _industry_chunk_handlers(industry_chunk_handlers);
}

@ -0,0 +1,74 @@
/*
* This file is part of OpenTTD.
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file labelmaps_sl.cpp Code handling saving and loading of rail type label mappings */
#include "../../stdafx.h"
#include "saveload.h"
#include "compat/labelmaps_sl_compat.h"
#include "../../station_map.h"
#include "../../tunnelbridge_map.h"
#include "../../safeguards.h"
void ResetLabelMaps();
extern std::vector<RailTypeLabel> _railtype_list;
namespace upstream_sl {
/** Container for a label for SaveLoad system */
struct LabelObject {
uint32 label;
};
static const SaveLoad _label_object_desc[] = {
SLE_VAR(LabelObject, label, SLE_UINT32),
};
struct RAILChunkHandler : ChunkHandler {
RAILChunkHandler() : ChunkHandler('RAIL', CH_TABLE) {}
void Save() const override
{
SlTableHeader(_label_object_desc);
LabelObject lo;
for (RailType r = RAILTYPE_BEGIN; r != RAILTYPE_END; r++) {
lo.label = GetRailTypeInfo(r)->label;
SlSetArrayIndex(r);
SlObject(&lo, _label_object_desc);
}
}
void Load() const override
{
const std::vector<SaveLoad> slt = SlCompatTableHeader(_label_object_desc, _label_object_sl_compat);
ResetLabelMaps();
LabelObject lo;
while (SlIterateArray() != -1) {
SlObject(&lo, slt);
_railtype_list.push_back((RailTypeLabel)lo.label);
}
}
};
static const RAILChunkHandler RAIL;
static const ChunkHandlerRef labelmaps_chunk_handlers[] = {
RAIL,
};
extern const ChunkHandlerTable _labelmaps_chunk_handlers(labelmaps_chunk_handlers);
}

@ -0,0 +1,331 @@
/*
* This file is part of OpenTTD.
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file linkgraph_sl.cpp Code handling saving and loading of link graphs */
#include "../../stdafx.h"
#include "saveload.h"
#include "compat/linkgraph_sl_compat.h"
#include "../../linkgraph/linkgraph.h"
#include "../../linkgraph/linkgraphjob.h"
#include "../../linkgraph/linkgraphschedule.h"
#include "../../network/network.h"
#include "../../safeguards.h"
namespace upstream_sl {
typedef LinkGraph::BaseNode Node;
typedef LinkGraph::BaseEdge Edge;
static uint16 _num_nodes;
static LinkGraph *_linkgraph; ///< Contains the current linkgraph being saved/loaded.
static NodeID _linkgraph_from; ///< Contains the current "from" node being saved/loaded.
class SlLinkgraphEdge : public DefaultSaveLoadHandler<SlLinkgraphEdge, Node> {
public:
inline static const SaveLoad description[] = {
SLE_VAR(Edge, capacity, SLE_UINT32),
SLE_VAR(Edge, usage, SLE_UINT32),
//SLE_CONDVAR(Edge, travel_time_sum, SLE_UINT64, SLV_LINKGRAPH_TRAVEL_TIME, SL_MAX_VERSION),
SLE_VAR(Edge, last_unrestricted_update, SLE_INT32),
SLE_CONDVAR(Edge, last_restricted_update, SLE_INT32, SLV_187, SL_MAX_VERSION),
SLE_VAR(Edge, next_edge, SLE_UINT16),
};
inline const static SaveLoadCompatTable compat_description = _linkgraph_edge_sl_compat;
void Save(Node *bn) const override
{
uint16 size = 0;
for (NodeID to = _linkgraph_from; to != INVALID_NODE; to = _linkgraph->edges[_linkgraph_from][to].next_edge) {
size++;
}
SlSetStructListLength(size);
for (NodeID to = _linkgraph_from; to != INVALID_NODE; to = _linkgraph->edges[_linkgraph_from][to].next_edge) {
SlObject(&_linkgraph->edges[_linkgraph_from][to], this->GetDescription());
}
}
void Load(Node *bn) const override
{
uint16 max_size = _linkgraph->Size();
if (IsSavegameVersionBefore(SLV_191)) {
/* We used to save the full matrix ... */
for (NodeID to = 0; to < max_size; ++to) {
SlObject(&_linkgraph->edges[_linkgraph_from][to], this->GetLoadDescription());
}
return;
}
size_t used_size = IsSavegameVersionBefore(SLV_SAVELOAD_LIST_LENGTH) ? max_size : SlGetStructListLength(UINT16_MAX);
/* ... but as that wasted a lot of space we save a sparse matrix now. */
for (NodeID to = _linkgraph_from; to != INVALID_NODE; to = _linkgraph->edges[_linkgraph_from][to].next_edge) {
if (used_size == 0) SlErrorCorrupt("Link graph structure overflow");
used_size--;
if (to >= max_size) SlErrorCorrupt("Link graph structure overflow");
SlObject(&_linkgraph->edges[_linkgraph_from][to], this->GetLoadDescription());
}
if (!IsSavegameVersionBefore(SLV_SAVELOAD_LIST_LENGTH) && used_size > 0) SlErrorCorrupt("Corrupted link graph");
}
};
class SlLinkgraphNode : public DefaultSaveLoadHandler<SlLinkgraphNode, LinkGraph> {
public:
inline static const SaveLoad description[] = {
SLE_CONDVAR(Node, xy, SLE_UINT32, SLV_191, SL_MAX_VERSION),
SLE_VAR(Node, supply, SLE_UINT32),
SLE_VAR(Node, demand, SLE_UINT32),
SLE_VAR(Node, station, SLE_UINT16),
SLE_VAR(Node, last_update, SLE_INT32),
SLEG_STRUCTLIST("edges", SlLinkgraphEdge),
};
inline const static SaveLoadCompatTable compat_description = _linkgraph_node_sl_compat;
void Save(LinkGraph *lg) const override
{
_linkgraph = lg;
SlSetStructListLength(lg->Size());
for (NodeID from = 0; from < lg->Size(); ++from) {
_linkgraph_from = from;
SlObject(&lg->nodes[from], this->GetDescription());
}
}
void Load(LinkGraph *lg) const override
{
_linkgraph = lg;
uint16 length = IsSavegameVersionBefore(SLV_SAVELOAD_LIST_LENGTH) ? _num_nodes : (uint16)SlGetStructListLength(UINT16_MAX);
lg->Init(length);
for (NodeID from = 0; from < length; ++from) {
_linkgraph_from = from;
SlObject(&lg->nodes[from], this->GetLoadDescription());
}
}
};
/**
* Get a SaveLoad array for a link graph.
* @return SaveLoad array for link graph.
*/
SaveLoadTable GetLinkGraphDesc()
{
static const SaveLoad link_graph_desc[] = {
SLE_VAR(LinkGraph, last_compression, SLE_INT32),
SLEG_CONDVAR("num_nodes", _num_nodes, SLE_UINT16, SL_MIN_VERSION, SLV_SAVELOAD_LIST_LENGTH),
SLE_VAR(LinkGraph, cargo, SLE_UINT8),
SLEG_STRUCTLIST("nodes", SlLinkgraphNode),
};
return link_graph_desc;
}
/**
* Proxy to reuse LinkGraph to save/load a LinkGraphJob.
* One of the members of a LinkGraphJob is a LinkGraph, but SLEG_STRUCT()
* doesn't allow us to select a member. So instead, we add a bit of glue to
* accept a LinkGraphJob, get the LinkGraph, and use that to call the
* save/load routines for a regular LinkGraph.
*/
class SlLinkgraphJobProxy : public DefaultSaveLoadHandler<SlLinkgraphJobProxy, LinkGraphJob> {
public:
inline static const SaveLoad description[] = {{}}; // Needed to keep DefaultSaveLoadHandler happy.
SaveLoadTable GetDescription() const override { return GetLinkGraphDesc(); }
inline const static SaveLoadCompatTable compat_description = _linkgraph_sl_compat;
void Save(LinkGraphJob *lgj) const override
{
SlObject(const_cast<LinkGraph *>(&lgj->Graph()), this->GetDescription());
}
void Load(LinkGraphJob *lgj) const override
{
SlObject(const_cast<LinkGraph *>(&lgj->Graph()), this->GetLoadDescription());
}
};
/**
* Get a SaveLoad array for a link graph job. The settings struct is derived from
* the global settings saveload array. The exact entries are calculated when the function
* is called the first time.
* It's necessary to keep a copy of the settings for each link graph job so that you can
* change the settings while in-game and still not mess with current link graph runs.
* Of course the settings have to be saved and loaded, too, to avoid desyncs.
* @return Array of SaveLoad structs.
*/
SaveLoadTable GetLinkGraphJobDesc()
{
static const SaveLoad job_desc[] = {
SLE_VAR2(LinkGraphJob, "linkgraph.recalc_interval", settings.recalc_interval, SLE_UINT16),
SLE_VAR2(LinkGraphJob, "linkgraph.recalc_time", settings.recalc_time, SLE_UINT16),
SLE_VAR2(LinkGraphJob, "linkgraph.distribution_pax", settings.distribution_pax, SLE_UINT8),
SLE_VAR2(LinkGraphJob, "linkgraph.distribution_mail", settings.distribution_mail, SLE_UINT8),
SLE_VAR2(LinkGraphJob, "linkgraph.distribution_armoured", settings.distribution_armoured, SLE_UINT8),
SLE_VAR2(LinkGraphJob, "linkgraph.distribution_default", settings.distribution_default, SLE_UINT8),
SLE_VAR2(LinkGraphJob, "linkgraph.accuracy", settings.accuracy, SLE_UINT8),
SLE_VAR2(LinkGraphJob, "linkgraph.demand_distance", settings.demand_distance, SLE_UINT8),
SLE_VAR2(LinkGraphJob, "linkgraph.demand_size", settings.demand_size, SLE_UINT8),
SLE_VAR2(LinkGraphJob, "linkgraph.short_path_saturation", settings.short_path_saturation, SLE_UINT8),
SLE_VAR2(LinkGraphJob, "join_date", join_date_ticks, SLE_INT32),
SLE_VAR(LinkGraphJob, link_graph.index, SLE_UINT16),
SLEG_STRUCT("linkgraph", SlLinkgraphJobProxy),
};
return job_desc;
}
/**
* Get a SaveLoad array for the link graph schedule.
* @return SaveLoad array for the link graph schedule.
*/
SaveLoadTable GetLinkGraphScheduleDesc()
{
static const SaveLoad schedule_desc[] = {
SLE_REFLIST(LinkGraphSchedule, schedule, REF_LINK_GRAPH),
SLE_REFLIST(LinkGraphSchedule, running, REF_LINK_GRAPH_JOB),
};
return schedule_desc;
}
/**
* Spawn the threads for running link graph calculations.
* Has to be done after loading as the cargo classes might have changed.
*/
void AfterLoadLinkGraphs()
{
if (IsSavegameVersionBefore(SLV_191)) {
for (LinkGraph *lg : LinkGraph::Iterate()) {
for (NodeID node_id = 0; node_id < lg->Size(); ++node_id) {
const Station *st = Station::GetIfValid((*lg)[node_id].Station());
if (st != nullptr) (*lg)[node_id].UpdateLocation(st->xy);
}
}
for (LinkGraphJob *lgj : LinkGraphJob::Iterate()) {
LinkGraph *lg = &(const_cast<LinkGraph &>(lgj->Graph()));
for (NodeID node_id = 0; node_id < lg->Size(); ++node_id) {
const Station *st = Station::GetIfValid((*lg)[node_id].Station());
if (st != nullptr) (*lg)[node_id].UpdateLocation(st->xy);
}
}
}
for (LinkGraphJob *lgj : LinkGraphJob::Iterate()) {
GetLinkGraphJobDayLengthScaleAfterLoad(lgj);
}
LinkGraphSchedule::instance.SpawnAll();
if (!_networking || _network_server) {
AfterLoad_LinkGraphPauseControl();
}
}
/**
* All link graphs.
*/
struct LGRPChunkHandler : ChunkHandler {
LGRPChunkHandler() : ChunkHandler('LGRP', CH_TABLE) {}
void Save() const override
{
SlTableHeader(GetLinkGraphDesc());
for (LinkGraph *lg : LinkGraph::Iterate()) {
SlSetArrayIndex(lg->index);
SlObject(lg, GetLinkGraphDesc());
}
}
void Load() const override
{
const std::vector<SaveLoad> slt = SlCompatTableHeader(GetLinkGraphDesc(), _linkgraph_sl_compat);
int index;
while ((index = SlIterateArray()) != -1) {
LinkGraph *lg = new (index) LinkGraph();
SlObject(lg, slt);
}
}
};
/**
* All link graph jobs.
*/
struct LGRJChunkHandler : ChunkHandler {
LGRJChunkHandler() : ChunkHandler('LGRJ', CH_TABLE) {}
void Save() const override
{
SlTableHeader(GetLinkGraphJobDesc());
for (LinkGraphJob *lgj : LinkGraphJob::Iterate()) {
SlSetArrayIndex(lgj->index);
SlObject(lgj, GetLinkGraphJobDesc());
}
}
void Load() const override
{
const std::vector<SaveLoad> slt = SlCompatTableHeader(GetLinkGraphJobDesc(), _linkgraph_job_sl_compat);
int index;
while ((index = SlIterateArray()) != -1) {
LinkGraphJob *lgj = new (index) LinkGraphJob();
SlObject(lgj, slt);
}
}
};
/**
* Link graph schedule.
*/
struct LGRSChunkHandler : ChunkHandler {
LGRSChunkHandler() : ChunkHandler('LGRS', CH_TABLE) {}
void Save() const override
{
SlTableHeader(GetLinkGraphScheduleDesc());
SlSetArrayIndex(0);
SlObject(&LinkGraphSchedule::instance, GetLinkGraphScheduleDesc());
}
void Load() const override
{
const std::vector<SaveLoad> slt = SlCompatTableHeader(GetLinkGraphScheduleDesc(), _linkgraph_schedule_sl_compat);
if (!IsSavegameVersionBefore(SLV_RIFF_TO_ARRAY) && SlIterateArray() == -1) return;
SlObject(&LinkGraphSchedule::instance, slt);
if (!IsSavegameVersionBefore(SLV_RIFF_TO_ARRAY) && SlIterateArray() != -1) SlErrorCorrupt("Too many LGRS entries");
}
void FixPointers() const override
{
SlObject(&LinkGraphSchedule::instance, GetLinkGraphScheduleDesc());
}
};
static const LGRPChunkHandler LGRP;
static const LGRJChunkHandler LGRJ;
static const LGRSChunkHandler LGRS;
static const ChunkHandlerRef linkgraph_chunk_handlers[] = {
LGRP,
LGRJ,
LGRS,
};
extern const ChunkHandlerTable _linkgraph_chunk_handlers(linkgraph_chunk_handlers);
}

@ -0,0 +1,385 @@
/*
* This file is part of OpenTTD.
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file map_sl.cpp Code handling saving and loading of map */
#include "../../stdafx.h"
#include "saveload.h"
#include "compat/map_sl_compat.h"
#include "../../map_func.h"
#include "../../core/bitmath_func.hpp"
#include "../../fios.h"
#include <array>
#include "../../safeguards.h"
namespace upstream_sl {
static uint32 _map_dim_x;
static uint32 _map_dim_y;
static const SaveLoad _map_desc[] = {
SLEG_CONDVAR("dim_x", _map_dim_x, SLE_UINT32, SLV_6, SL_MAX_VERSION),
SLEG_CONDVAR("dim_y", _map_dim_y, SLE_UINT32, SLV_6, SL_MAX_VERSION),
};
struct MAPSChunkHandler : ChunkHandler {
MAPSChunkHandler() : ChunkHandler('MAPS', CH_TABLE) {}
void Save() const override
{
SlTableHeader(_map_desc);
_map_dim_x = MapSizeX();
_map_dim_y = MapSizeY();
SlSetArrayIndex(0);
SlGlobList(_map_desc);
}
void Load() const override
{
const std::vector<SaveLoad> slt = SlCompatTableHeader(_map_desc, _map_sl_compat);
if (!IsSavegameVersionBefore(SLV_RIFF_TO_ARRAY) && SlIterateArray() == -1) return;
SlGlobList(slt);
if (!IsSavegameVersionBefore(SLV_RIFF_TO_ARRAY) && SlIterateArray() != -1) SlErrorCorrupt("Too many MAPS entries");
AllocateMap(_map_dim_x, _map_dim_y);
}
void LoadCheck(size_t) const override
{
const std::vector<SaveLoad> slt = SlCompatTableHeader(_map_desc, _map_sl_compat);
if (!IsSavegameVersionBefore(SLV_RIFF_TO_ARRAY) && SlIterateArray() == -1) return;
SlGlobList(slt);
if (!IsSavegameVersionBefore(SLV_RIFF_TO_ARRAY) && SlIterateArray() != -1) SlErrorCorrupt("Too many MAPS entries");
_load_check_data.map_size_x = _map_dim_x;
_load_check_data.map_size_y = _map_dim_y;
}
};
static const uint MAP_SL_BUF_SIZE = 4096;
struct MAPTChunkHandler : ChunkHandler {
MAPTChunkHandler() : ChunkHandler('MAPT', CH_RIFF) {}
void Load() const override
{
std::array<byte, MAP_SL_BUF_SIZE> buf;
TileIndex size = MapSize();
for (TileIndex i = 0; i != size;) {
SlCopy(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT8);
for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _m[i++].type = buf[j];
}
}
void Save() const override
{
std::array<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;
SlCopy(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT8);
}
}
};
struct MAPHChunkHandler : ChunkHandler {
MAPHChunkHandler() : ChunkHandler('MAPH', CH_RIFF) {}
void Load() const override
{
std::array<byte, MAP_SL_BUF_SIZE> buf;
TileIndex size = MapSize();
for (TileIndex i = 0; i != size;) {
SlCopy(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT8);
for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _m[i++].height = buf[j];
}
}
void Save() const override
{
std::array<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++].height;
SlCopy(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT8);
}
}
};
struct MAPOChunkHandler : ChunkHandler {
MAPOChunkHandler() : ChunkHandler('MAPO', CH_RIFF) {}
void Load() const override
{
std::array<byte, MAP_SL_BUF_SIZE> buf;
TileIndex size = MapSize();
for (TileIndex i = 0; i != size;) {
SlCopy(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT8);
for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _m[i++].m1 = buf[j];
}
}
void Save() const override
{
std::array<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;
SlCopy(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT8);
}
}
};
struct MAP2ChunkHandler : ChunkHandler {
MAP2ChunkHandler() : ChunkHandler('MAP2', CH_RIFF) {}
void Load() const override
{
std::array<uint16, MAP_SL_BUF_SIZE> buf;
TileIndex size = MapSize();
for (TileIndex i = 0; i != size;) {
SlCopy(buf.data(), MAP_SL_BUF_SIZE,
/* In those versions the m2 was 8 bits */
IsSavegameVersionBefore(SLV_5) ? SLE_FILE_U8 | SLE_VAR_U16 : SLE_UINT16
);
for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _m[i++].m2 = buf[j];
}
}
void Save() const override
{
std::array<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;
SlCopy(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT16);
}
}
};
struct M3LOChunkHandler : ChunkHandler {
M3LOChunkHandler() : ChunkHandler('M3LO', CH_RIFF) {}
void Load() const override
{
std::array<byte, MAP_SL_BUF_SIZE> buf;
TileIndex size = MapSize();
for (TileIndex i = 0; i != size;) {
SlCopy(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT8);
for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _m[i++].m3 = buf[j];
}
}
void Save() const override
{
std::array<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;
SlCopy(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT8);
}
}
};
struct M3HIChunkHandler : ChunkHandler {
M3HIChunkHandler() : ChunkHandler('M3HI', CH_RIFF) {}
void Load() const override
{
std::array<byte, MAP_SL_BUF_SIZE> buf;
TileIndex size = MapSize();
for (TileIndex i = 0; i != size;) {
SlCopy(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT8);
for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _m[i++].m4 = buf[j];
}
}
void Save() const override
{
std::array<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;
SlCopy(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT8);
}
}
};
struct MAP5ChunkHandler : ChunkHandler {
MAP5ChunkHandler() : ChunkHandler('MAP5', CH_RIFF) {}
void Load() const override
{
std::array<byte, MAP_SL_BUF_SIZE> buf;
TileIndex size = MapSize();
for (TileIndex i = 0; i != size;) {
SlCopy(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT8);
for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _m[i++].m5 = buf[j];
}
}
void Save() const override
{
std::array<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;
SlCopy(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT8);
}
}
};
struct MAPEChunkHandler : ChunkHandler {
MAPEChunkHandler() : ChunkHandler('MAPE', CH_RIFF) {}
void Load() const override
{
std::array<byte, MAP_SL_BUF_SIZE> buf;
TileIndex size = MapSize();
if (IsSavegameVersionBefore(SLV_42)) {
for (TileIndex i = 0; i != size;) {
/* 1024, otherwise we overflow on 64x64 maps! */
SlCopy(buf.data(), 1024, SLE_UINT8);
for (uint j = 0; j != 1024; j++) {
_me[i++].m6 = GB(buf[j], 0, 2);
_me[i++].m6 = GB(buf[j], 2, 2);
_me[i++].m6 = GB(buf[j], 4, 2);
_me[i++].m6 = GB(buf[j], 6, 2);
}
}
} else {
for (TileIndex i = 0; i != size;) {
SlCopy(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT8);
for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _me[i++].m6 = buf[j];
}
}
}
void Save() const override
{
std::array<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++].m6;
SlCopy(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT8);
}
}
};
struct MAP7ChunkHandler : ChunkHandler {
MAP7ChunkHandler() : ChunkHandler('MAP7', CH_RIFF) {}
void Load() const override
{
std::array<byte, MAP_SL_BUF_SIZE> buf;
TileIndex size = MapSize();
for (TileIndex i = 0; i != size;) {
SlCopy(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT8);
for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _me[i++].m7 = buf[j];
}
}
void Save() const override
{
std::array<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;
SlCopy(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT8);
}
}
};
struct MAP8ChunkHandler : ChunkHandler {
MAP8ChunkHandler() : ChunkHandler('MAP8', CH_RIFF) {}
void Load() const override
{
std::array<uint16, MAP_SL_BUF_SIZE> buf;
TileIndex size = MapSize();
for (TileIndex i = 0; i != size;) {
SlCopy(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT16);
for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _me[i++].m8 = buf[j];
}
}
void Save() const override
{
std::array<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] = _me[i++].m8;
SlCopy(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT16);
}
}
};
static const MAPSChunkHandler MAPS;
static const MAPTChunkHandler MAPT;
static const MAPHChunkHandler MAPH;
static const MAPOChunkHandler MAPO;
static const MAP2ChunkHandler MAP2;
static const M3LOChunkHandler M3LO;
static const M3HIChunkHandler M3HI;
static const MAP5ChunkHandler MAP5;
static const MAPEChunkHandler MAPE;
static const MAP7ChunkHandler MAP7;
static const MAP8ChunkHandler MAP8;
static const ChunkHandlerRef map_chunk_handlers[] = {
MAPS,
MAPT,
MAPH,
MAPO,
MAP2,
M3LO,
M3HI,
MAP5,
MAPE,
MAP7,
MAP8,
};
extern const ChunkHandlerTable _map_chunk_handlers(map_chunk_handlers);
}

@ -0,0 +1,138 @@
/*
* This file is part of OpenTTD.
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file misc_sl.cpp Saving and loading of things that didn't fit anywhere else */
#include "../../stdafx.h"
#include "saveload.h"
#include "compat/misc_sl_compat.h"
#include "../../date_func.h"
#include "../../zoom_func.h"
#include "../../window_gui.h"
#include "../../window_func.h"
#include "../../viewport_func.h"
#include "../../gfx_func.h"
#include "../../core/random_func.hpp"
#include "../../fios.h"
#include "../../safeguards.h"
extern TileIndex _cur_tileloop_tile;
extern uint16 _disaster_delay;
extern byte _trees_tick_ctr;
/* Keep track of current game position */
extern int _saved_scrollpos_x;
extern int _saved_scrollpos_y;
extern ZoomLevel _saved_scrollpos_zoom;
extern byte _age_cargo_skip_counter; ///< Skip aging of cargo? Used before savegame version 162.
namespace upstream_sl {
static const SaveLoad _date_desc[] = {
SLEG_CONDVAR("date", _date, SLE_FILE_U16 | SLE_VAR_I32, SL_MIN_VERSION, SLV_31),
SLEG_CONDVAR("date", _date, SLE_INT32, SLV_31, SL_MAX_VERSION),
SLEG_VAR("date_fract", _date_fract, SLE_UINT16),
SLEG_VAR("tick_counter", _tick_counter, SLE_UINT16),
SLEG_CONDVAR("age_cargo_skip_counter", _age_cargo_skip_counter, SLE_UINT8, SL_MIN_VERSION, SLV_162),
SLEG_CONDVAR("cur_tileloop_tile", _cur_tileloop_tile, SLE_FILE_U16 | SLE_VAR_U32, SL_MIN_VERSION, SLV_6),
SLEG_CONDVAR("cur_tileloop_tile", _cur_tileloop_tile, SLE_UINT32, SLV_6, SL_MAX_VERSION),
SLEG_VAR("next_disaster_start", _disaster_delay, SLE_UINT16),
SLEG_VAR("random_state[0]", _random.state[0], SLE_UINT32),
SLEG_VAR("random_state[1]", _random.state[1], SLE_UINT32),
SLEG_VAR("company_tick_counter", _cur_company_tick_index, SLE_FILE_U8 | SLE_VAR_U32),
SLEG_CONDVAR("next_competitor_start", _next_competitor_start, SLE_FILE_U16 | SLE_VAR_U32, SL_MIN_VERSION, SLV_109),
SLEG_CONDVAR("next_competitor_start", _next_competitor_start, SLE_UINT32, SLV_109, SL_MAX_VERSION),
SLEG_VAR("trees_tick_counter", _trees_tick_ctr, SLE_UINT8),
SLEG_CONDVAR("pause_mode", _pause_mode, SLE_UINT8, SLV_4, SL_MAX_VERSION),
};
static const SaveLoad _date_check_desc[] = {
SLEG_CONDVAR("date", _load_check_data.current_date, SLE_FILE_U16 | SLE_VAR_I32, SL_MIN_VERSION, SLV_31),
SLEG_CONDVAR("date", _load_check_data.current_date, SLE_INT32, SLV_31, SL_MAX_VERSION),
};
/* Save load date related variables as well as persistent tick counters
* XXX: currently some unrelated stuff is just put here */
struct DATEChunkHandler : ChunkHandler {
DATEChunkHandler() : ChunkHandler('DATE', CH_TABLE) {}
void Save() const override
{
SlTableHeader(_date_desc);
SlSetArrayIndex(0);
SlGlobList(_date_desc);
}
void LoadCommon(const SaveLoadTable &slt, const SaveLoadCompatTable &slct) const
{
const std::vector<SaveLoad> oslt = SlCompatTableHeader(slt, slct);
if (!IsSavegameVersionBefore(SLV_RIFF_TO_ARRAY) && SlIterateArray() == -1) return;
SlGlobList(oslt);
if (!IsSavegameVersionBefore(SLV_RIFF_TO_ARRAY) && SlIterateArray() != -1) SlErrorCorrupt("Too many DATE entries");
}
void Load() const override
{
this->LoadCommon(_date_desc, _date_sl_compat);
}
void LoadCheck(size_t) const override
{
this->LoadCommon(_date_check_desc, _date_check_sl_compat);
if (IsSavegameVersionBefore(SLV_31)) {
_load_check_data.current_date += DAYS_TILL_ORIGINAL_BASE_YEAR;
}
}
};
static const SaveLoad _view_desc[] = {
SLEG_CONDVAR("x", _saved_scrollpos_x, SLE_FILE_I16 | SLE_VAR_I32, SL_MIN_VERSION, SLV_6),
SLEG_CONDVAR("x", _saved_scrollpos_x, SLE_INT32, SLV_6, SL_MAX_VERSION),
SLEG_CONDVAR("y", _saved_scrollpos_y, SLE_FILE_I16 | SLE_VAR_I32, SL_MIN_VERSION, SLV_6),
SLEG_CONDVAR("y", _saved_scrollpos_y, SLE_INT32, SLV_6, SL_MAX_VERSION),
SLEG_VAR("zoom", _saved_scrollpos_zoom, SLE_UINT8),
};
struct VIEWChunkHandler : ChunkHandler {
VIEWChunkHandler() : ChunkHandler('VIEW', CH_TABLE) {}
void Save() const override
{
SlTableHeader(_view_desc);
SlSetArrayIndex(0);
SlGlobList(_view_desc);
}
void Load() const override
{
const std::vector<SaveLoad> slt = SlCompatTableHeader(_view_desc, _view_sl_compat);
if (!IsSavegameVersionBefore(SLV_RIFF_TO_ARRAY) && SlIterateArray() == -1) return;
SlGlobList(slt);
if (!IsSavegameVersionBefore(SLV_RIFF_TO_ARRAY) && SlIterateArray() != -1) SlErrorCorrupt("Too many DATE entries");
}
};
static const DATEChunkHandler DATE;
static const VIEWChunkHandler VIEW;
static const ChunkHandlerRef misc_chunk_handlers[] = {
DATE,
VIEW,
};
extern const ChunkHandlerTable _misc_chunk_handlers(misc_chunk_handlers);
}

@ -0,0 +1,135 @@
/*
* This file is part of OpenTTD.
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file newgrf_sl.cpp Code handling saving and loading of newgrf config */
#include "../../stdafx.h"
#include "saveload.h"
#include "compat/newgrf_sl_compat.h"
#include "newgrf_sl.h"
#include "../../fios.h"
#include "../../safeguards.h"
namespace upstream_sl {
/** Save and load the mapping between a spec and the NewGRF it came from. */
static const SaveLoad _newgrf_mapping_desc[] = {
SLE_VAR(EntityIDMapping, grfid, SLE_UINT32),
SLE_VAR(EntityIDMapping, entity_id, SLE_UINT8),
SLE_VAR(EntityIDMapping, substitute_id, SLE_UINT8),
};
/**
* Save a GRF ID + local id -> OpenTTD's id mapping.
*/
void NewGRFMappingChunkHandler::Save() const
{
SlTableHeader(_newgrf_mapping_desc);
for (uint i = 0; i < this->mapping.GetMaxMapping(); i++) {
if (this->mapping.mapping_ID[i].grfid == 0 &&
this->mapping.mapping_ID[i].entity_id == 0) continue;
SlSetArrayIndex(i);
SlObject(&this->mapping.mapping_ID[i], _newgrf_mapping_desc);
}
}
/**
* Load a GRF ID + local id -> OpenTTD's id mapping.
*/
void NewGRFMappingChunkHandler::Load() const
{
const std::vector<SaveLoad> slt = SlCompatTableHeader(_newgrf_mapping_desc, _newgrf_mapping_sl_compat);
/* Clear the current mapping stored.
* This will create the manager if ever it is not yet done */
this->mapping.ResetMapping();
uint max_id = this->mapping.GetMaxMapping();
int index;
while ((index = SlIterateArray()) != -1) {
if ((uint)index >= max_id) SlErrorCorrupt("Too many NewGRF entity mappings");
SlObject(&this->mapping.mapping_ID[index], slt);
}
}
static const SaveLoad _grfconfig_desc[] = {
SLE_STR(GRFConfig, filename, SLE_STR, 0x40),
SLE_VAR(GRFConfig, ident.grfid, SLE_UINT32),
SLE_ARR(GRFConfig, ident.md5sum, SLE_UINT8, 16),
SLE_CONDVAR(GRFConfig, version, SLE_UINT32, SLV_151, SL_MAX_VERSION),
SLE_ARR(GRFConfig, param, SLE_UINT32, 0x80),
SLE_VAR(GRFConfig, num_params, SLE_UINT8),
SLE_CONDVAR(GRFConfig, palette, SLE_UINT8, SLV_101, SL_MAX_VERSION),
};
struct NGRFChunkHandler : ChunkHandler {
NGRFChunkHandler() : ChunkHandler('NGRF', CH_TABLE) {}
void Save() const override
{
SlTableHeader(_grfconfig_desc);
int index = 0;
for (GRFConfig *c = _grfconfig; c != nullptr; c = c->next) {
if (HasBit(c->flags, GCF_STATIC) || HasBit(c->flags, GCF_INIT_ONLY)) continue;
SlSetArrayIndex(index++);
SlObject(c, _grfconfig_desc);
}
}
void LoadCommon(GRFConfig *&grfconfig) const
{
const std::vector<SaveLoad> slt = SlCompatTableHeader(_grfconfig_desc, _grfconfig_sl_compat);
ClearGRFConfigList(&grfconfig);
while (SlIterateArray() != -1) {
GRFConfig *c = new GRFConfig();
SlObject(c, slt);
if (IsSavegameVersionBefore(SLV_101)) c->SetSuitablePalette();
AppendToGRFConfigList(&grfconfig, c);
}
}
void Load() const override
{
this->LoadCommon(_grfconfig);
if (_game_mode == GM_MENU) {
/* Intro game must not have NewGRF. */
if (_grfconfig != nullptr) SlErrorCorrupt("The intro game must not use NewGRF");
/* Activate intro NewGRFs (townnames) */
ResetGRFConfig(false);
} else {
/* Append static NewGRF configuration */
AppendStaticGRFConfigs(&_grfconfig);
}
}
void LoadCheck(size_t) const override
{
this->LoadCommon(_load_check_data.grfconfig);
}
};
static const NGRFChunkHandler NGRF;
static const ChunkHandlerRef newgrf_chunk_handlers[] = {
NGRF,
};
extern const ChunkHandlerTable _newgrf_chunk_handlers(newgrf_chunk_handlers);
}

@ -0,0 +1,27 @@
/*
* This file is part of OpenTTD.
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file newgrf_sl.h Code handling saving and loading of NewGRF mappings. */
#ifndef SAVELOAD_UPSTREAM_NEWGRF_SL_H
#define SAVELOAD_UPSTREAM_NEWGRF_SL_H
#include "../../newgrf_commons.h"
namespace upstream_sl {
struct NewGRFMappingChunkHandler : ChunkHandler {
OverrideManagerBase &mapping;
NewGRFMappingChunkHandler(uint32 id, OverrideManagerBase &mapping) : ChunkHandler(id, CH_TABLE), mapping(mapping) {}
void Save() const override;
void Load() const override;
};
}
#endif /* SAVELOAD_UPSTREAM_NEWGRF_SL_H */

@ -0,0 +1,84 @@
/*
* This file is part of OpenTTD.
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file object_sl.cpp Code handling saving and loading of objects */
#include "../../stdafx.h"
#include "saveload.h"
#include "compat/object_sl_compat.h"
#include "../../object_base.h"
#include "../../object_map.h"
#include "newgrf_sl.h"
#include "../../safeguards.h"
namespace upstream_sl {
static const SaveLoad _object_desc[] = {
SLE_VAR(Object, location.tile, SLE_UINT32),
SLE_VAR(Object, location.w, SLE_FILE_U8 | SLE_VAR_U16),
SLE_VAR(Object, location.h, SLE_FILE_U8 | SLE_VAR_U16),
SLE_REF(Object, town, REF_TOWN),
SLE_VAR(Object, build_date, SLE_UINT32),
SLE_CONDVAR(Object, colour, SLE_UINT8, SLV_148, SL_MAX_VERSION),
SLE_CONDVAR(Object, view, SLE_UINT8, SLV_155, SL_MAX_VERSION),
SLE_CONDVAR(Object, type, SLE_UINT16, SLV_186, SL_MAX_VERSION),
};
struct OBJSChunkHandler : ChunkHandler {
OBJSChunkHandler() : ChunkHandler('OBJS', CH_TABLE) {}
void Save() const override
{
SlTableHeader(_object_desc);
/* Write the objects */
for (Object *o : Object::Iterate()) {
SlSetArrayIndex(o->index);
SlObject(o, _object_desc);
}
}
void Load() const override
{
const std::vector<SaveLoad> slt = SlCompatTableHeader(_object_desc, _object_sl_compat);
int index;
while ((index = SlIterateArray()) != -1) {
Object *o = new (index) Object();
SlObject(o, slt);
}
}
void FixPointers() const override
{
for (Object *o : Object::Iterate()) {
SlObject(o, _object_desc);
if (IsSavegameVersionBefore(SLV_148) && !IsTileType(o->location.tile, MP_OBJECT)) {
/* Due to a small bug stale objects could remain. */
delete o;
}
}
}
};
struct OBIDChunkHandler : NewGRFMappingChunkHandler {
OBIDChunkHandler() : NewGRFMappingChunkHandler('OBID', _object_mngr) {}
};
static const OBIDChunkHandler OBID;
static const OBJSChunkHandler OBJS;
static const ChunkHandlerRef object_chunk_handlers[] = {
OBID,
OBJS,
};
extern const ChunkHandlerTable _object_chunk_handlers(object_chunk_handlers);
}

@ -0,0 +1,273 @@
/*
* This file is part of OpenTTD.
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file order_sl.cpp Code handling saving and loading of orders */
#include "../../stdafx.h"
#include "saveload.h"
#include "compat/order_sl_compat.h"
#include "../../order_backup.h"
#include "../../order_base.h"
#include "../../settings_type.h"
#include "../../network/network.h"
#include "../../safeguards.h"
namespace upstream_sl {
/**
* 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.IsType(OT_NOTHING) && packed != 0) order.MakeDummy();
return order;
}
SaveLoadTable GetOrderDescription()
{
static const SaveLoad _order_desc[] = {
SLE_VAR(Order, type, SLE_UINT8),
SLE_VAR(Order, flags, SLE_FILE_U8 | SLE_VAR_U16),
SLE_VAR(Order, dest, SLE_UINT16),
SLE_REF(Order, next, REF_ORDER),
SLE_CONDVAR(Order, refit_cargo, SLE_UINT8, SLV_36, SL_MAX_VERSION),
SLE_CONDVAR(Order, wait_time, SLE_FILE_U16 | SLE_VAR_U32, SLV_67, SL_MAX_VERSION),
SLE_CONDVAR(Order, travel_time, SLE_FILE_U16 | SLE_VAR_U32, SLV_67, SL_MAX_VERSION),
SLE_CONDVAR(Order, max_speed, SLE_UINT16, SLV_172, SL_MAX_VERSION),
};
return _order_desc;
}
struct ORDRChunkHandler : ChunkHandler {
ORDRChunkHandler() : ChunkHandler('ORDR', CH_TABLE) {}
void Save() const override
{
const SaveLoadTable slt = GetOrderDescription();
SlTableHeader(slt);
for (Order *order : Order::Iterate()) {
SlSetArrayIndex(order->index);
SlObject(order, slt);
}
}
void Load() const override
{
if (IsSavegameVersionBefore(SLV_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();
if (IsSavegameVersionBefore(SLV_5)) {
/* Pre-version 5 had another layout for orders
* (uint16 instead of uint32) */
len /= sizeof(uint16);
uint16 *orders = MallocT<uint16>(len + 1);
SlCopy(orders, len, SLE_UINT16);
for (size_t i = 0; i < len; ++i) {
Order *o = new (i) Order();
o->AssignOrder(UnpackVersion4Order(orders[i]));
}
free(orders);
} else if (IsSavegameVersionBefore(SLV_5, 2)) {
len /= sizeof(uint32);
uint32 *orders = MallocT<uint32>(len + 1);
SlCopy(orders, len, SLE_UINT32);
for (size_t i = 0; i < len; ++i) {
new (i) Order(orders[i]);
}
free(orders);
}
/* Update all the next pointer */
for (Order *o : Order::Iterate()) {
size_t order_index = o->index;
/* Delete invalid orders */
if (o->IsType(OT_NOTHING)) {
delete o;
continue;
}
/* The orders were built like this:
* While the order is valid, set the previous will get its next pointer set */
Order *prev = Order::GetIfValid(order_index - 1);
if (prev != nullptr) prev->next = o;
}
} else {
const std::vector<SaveLoad> slt = SlCompatTableHeader(GetOrderDescription(), _order_sl_compat);
int index;
while ((index = SlIterateArray()) != -1) {
Order *order = new (index) Order();
SlObject(order, slt);
}
}
}
void FixPointers() const override
{
/* Orders from old savegames have pointers corrected in Load_ORDR */
if (IsSavegameVersionBefore(SLV_5, 2)) return;
for (Order *o : Order::Iterate()) {
SlObject(o, GetOrderDescription());
}
}
};
SaveLoadTable GetOrderListDescription()
{
static const SaveLoad _orderlist_desc[] = {
SLE_REF(OrderList, first, REF_ORDER),
};
return _orderlist_desc;
}
struct ORDLChunkHandler : ChunkHandler {
ORDLChunkHandler() : ChunkHandler('ORDL', CH_TABLE) {}
void Save() const override
{
const SaveLoadTable slt = GetOrderListDescription();
SlTableHeader(slt);
for (OrderList *list : OrderList::Iterate()) {
SlSetArrayIndex(list->index);
SlObject(list, slt);
}
}
void Load() const override
{
const std::vector<SaveLoad> slt = SlCompatTableHeader(GetOrderListDescription(), _orderlist_sl_compat);
int index;
while ((index = SlIterateArray()) != -1) {
/* set num_orders to 0 so it's a valid OrderList */
OrderList *list = new (index) OrderList(0);
SlObject(list, slt);
}
}
void FixPointers() const override
{
for (OrderList *list : OrderList::Iterate()) {
SlObject(list, GetOrderListDescription());
}
}
};
SaveLoadTable GetOrderBackupDescription()
{
static const SaveLoad _order_backup_desc[] = {
SLE_VAR(OrderBackup, user, SLE_UINT32),
SLE_VAR(OrderBackup, tile, SLE_UINT32),
SLE_VAR(OrderBackup, group, SLE_UINT16),
SLE_CONDVAR(OrderBackup, service_interval, SLE_FILE_U32 | SLE_VAR_U16, SL_MIN_VERSION, SLV_192),
SLE_CONDVAR(OrderBackup, service_interval, SLE_UINT16, SLV_192, SL_MAX_VERSION),
SLE_SSTR(OrderBackup, name, SLE_STR),
SLE_CONDREF(OrderBackup, clone, REF_VEHICLE, SLV_192, SL_MAX_VERSION),
SLE_VAR(OrderBackup, cur_real_order_index, SLE_FILE_U8 | SLE_VAR_U16),
SLE_CONDVAR(OrderBackup, cur_implicit_order_index, SLE_FILE_U8 | SLE_VAR_U16, SLV_176, SL_MAX_VERSION),
SLE_CONDVAR(OrderBackup, current_order_time, SLE_UINT32, SLV_176, SL_MAX_VERSION),
SLE_CONDVAR(OrderBackup, lateness_counter, SLE_INT32, SLV_176, SL_MAX_VERSION),
SLE_CONDVAR(OrderBackup, timetable_start, SLE_INT32, SLV_176, SL_MAX_VERSION),
SLE_CONDVAR(OrderBackup, vehicle_flags, SLE_FILE_U8 | SLE_VAR_U16, SLV_176, SLV_180),
SLE_CONDVAR(OrderBackup, vehicle_flags, SLE_UINT16, SLV_180, SL_MAX_VERSION),
SLE_REF(OrderBackup, orders, REF_ORDER),
};
return _order_backup_desc;
}
struct BKORChunkHandler : ChunkHandler {
BKORChunkHandler() : ChunkHandler('BKOR', CH_TABLE) {}
void Save() const override
{
const SaveLoadTable slt = GetOrderBackupDescription();
SlTableHeader(slt);
/* We only save this when we're a network server
* as we want this information on our clients. For
* normal games this information isn't needed. */
if (!_networking || !_network_server) return;
for (OrderBackup *ob : OrderBackup::Iterate()) {
SlSetArrayIndex(ob->index);
SlObject(ob, slt);
}
}
void Load() const override
{
const std::vector<SaveLoad> slt = SlCompatTableHeader(GetOrderBackupDescription(), _order_backup_sl_compat);
int index;
while ((index = SlIterateArray()) != -1) {
/* set num_orders to 0 so it's a valid OrderList */
OrderBackup *ob = new (index) OrderBackup();
SlObject(ob, slt);
if (ob->cur_real_order_index == 0xFF) ob->cur_real_order_index = INVALID_VEH_ORDER_ID;
if (ob->cur_implicit_order_index == 0xFF) ob->cur_implicit_order_index = INVALID_VEH_ORDER_ID;
}
}
void FixPointers() const override
{
for (OrderBackup *ob : OrderBackup::Iterate()) {
SlObject(ob, GetOrderBackupDescription());
}
}
};
static const BKORChunkHandler BKOR;
static const ORDRChunkHandler ORDR;
static const ORDLChunkHandler ORDL;
static const ChunkHandlerRef order_chunk_handlers[] = {
BKOR,
ORDR,
ORDL,
};
extern const ChunkHandlerTable _order_chunk_handlers(order_chunk_handlers);
}

File diff suppressed because it is too large Load Diff

@ -0,0 +1,830 @@
/*
* This file is part of OpenTTD.
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file saveload.h Functions/types related to saving and loading games. */
#ifndef UPSTREAM_SAVELOAD_H
#define UPSTREAM_SAVELOAD_H
#include "../saveload_common.h"
#include "../../fileio_type.h"
#include "../../fios.h"
#include "../../strings_type.h"
#include "../../core/span_type.hpp"
#include <optional>
#include <string>
#include <vector>
extern SaveLoadVersion _sl_version;
extern byte _sl_minor_version;
extern const SaveLoadVersion SAVEGAME_VERSION;
namespace upstream_sl {
typedef void AutolengthProc(void *arg);
/** Type of a chunk. */
enum ChunkType {
CH_RIFF = 0,
CH_ARRAY = 1,
CH_SPARSE_ARRAY = 2,
CH_TABLE = 3,
CH_SPARSE_TABLE = 4,
CH_TYPE_MASK = 0xf, ///< All ChunkType values have to be within this mask.
CH_READONLY, ///< Chunk is never saved.
};
/** Handlers and description of chunk. */
struct ChunkHandler {
uint32 id; ///< Unique ID (4 letters).
ChunkType type; ///< Type of the chunk. @see ChunkType
ChunkHandler(uint32 id, ChunkType type) : id(id), type(type) {}
virtual ~ChunkHandler() {}
/**
* Save the chunk.
* Must be overridden, unless Chunk type is CH_READONLY.
*/
virtual void Save() const { NOT_REACHED(); }
/**
* Load the chunk.
* Must be overridden.
*/
virtual void Load() const = 0;
/**
* Fix the pointers.
* Pointers are saved using the index of the pointed object.
* On load, pointers are filled with indices and need to be fixed to point to the real object.
* Must be overridden if the chunk saves any pointer.
*/
virtual void FixPointers() const {}
/**
* Load the chunk for game preview.
* Default implementation just skips the data.
* @param len Number of bytes to skip.
*/
virtual void LoadCheck(size_t len = 0) const;
};
/** A reference to ChunkHandler. */
using ChunkHandlerRef = std::reference_wrapper<const ChunkHandler>;
/** A table of ChunkHandler entries. */
using ChunkHandlerTable = span<const ChunkHandlerRef>;
/** A table of SaveLoadCompat entries. */
using SaveLoadCompatTable = span<const struct SaveLoadCompat>;
/** Handler for saving/loading an object to/from disk. */
class SaveLoadHandler {
public:
std::optional<std::vector<SaveLoad>> load_description;
virtual ~SaveLoadHandler() {}
/**
* Save the object to disk.
* @param object The object to store.
*/
virtual void Save(void *object) const {}
/**
* Load the object from disk.
* @param object The object to load.
*/
virtual void Load(void *object) const {}
/**
* Similar to load, but used only to validate savegames.
* @param object The object to load.
*/
virtual void LoadCheck(void *object) const {}
/**
* A post-load callback to fix #SL_REF integers into pointers.
* @param object The object to fix.
*/
virtual void FixPointers(void *object) const {}
/**
* Get the description of the fields in the savegame.
*/
virtual SaveLoadTable GetDescription() const = 0;
/**
* Get the pre-header description of the fields in the savegame.
*/
virtual SaveLoadCompatTable GetCompatDescription() const = 0;
/**
* Get the description for how to load the chunk. Depending on the
* savegame version this can either use the headers in the savegame or
* fall back to backwards compatibility and uses hard-coded headers.
*/
SaveLoadTable GetLoadDescription() const;
};
/**
* Default handler for saving/loading an object to/from disk.
*
* This handles a few common things for handlers, meaning the actual handler
* needs less code.
*
* Usage: class SlMine : public DefaultSaveLoadHandler<SlMine, MyObject> {}
*
* @tparam TImpl The class initializing this template.
* @tparam TObject The class of the object using this SaveLoadHandler.
*/
template <class TImpl, class TObject>
class DefaultSaveLoadHandler : public SaveLoadHandler {
public:
SaveLoadTable GetDescription() const override { return static_cast<const TImpl *>(this)->description; }
SaveLoadCompatTable GetCompatDescription() const override { return static_cast<const TImpl *>(this)->compat_description; }
virtual void Save(TObject *object) const {}
void Save(void *object) const override { this->Save(static_cast<TObject *>(object)); }
virtual void Load(TObject *object) const {}
void Load(void *object) const override { this->Load(static_cast<TObject *>(object)); }
virtual void LoadCheck(TObject *object) const {}
void LoadCheck(void *object) const override { this->LoadCheck(static_cast<TObject *>(object)); }
virtual void FixPointers(TObject *object) const {}
void FixPointers(void *object) const override { this->FixPointers(static_cast<TObject *>(object)); }
};
/** Type of reference (#SLE_REF, #SLE_CONDREF). */
enum SLRefType {
REF_ORDER = 0, ///< Load/save a reference to an order.
REF_VEHICLE = 1, ///< Load/save a reference to a vehicle.
REF_STATION = 2, ///< Load/save a reference to a station.
REF_TOWN = 3, ///< Load/save a reference to a town.
REF_VEHICLE_OLD = 4, ///< Load/save an old-style reference to a vehicle (for pre-4.4 savegames).
REF_ROADSTOPS = 5, ///< Load/save a reference to a bus/truck stop.
REF_ENGINE_RENEWS = 6, ///< Load/save a reference to an engine renewal (autoreplace).
REF_CARGO_PACKET = 7, ///< Load/save a reference to a cargo packet.
REF_ORDERLIST = 8, ///< Load/save a reference to an orderlist.
REF_STORAGE = 9, ///< Load/save a reference to a persistent storage.
REF_LINK_GRAPH = 10, ///< Load/save a reference to a link graph.
REF_LINK_GRAPH_JOB = 11, ///< Load/save a reference to a link graph job.
};
/**
* VarTypes is the general bitmasked magic type that tells us
* certain characteristics about the variable it refers to. For example
* SLE_FILE_* gives the size(type) as it would be in the savegame and
* SLE_VAR_* the size(type) as it is in memory during runtime. These are
* the first 8 bits (0-3 SLE_FILE, 4-7 SLE_VAR).
* Bits 8-15 are reserved for various flags as explained below
*/
enum VarTypes {
/* 4 bits allocated a maximum of 16 types for NumberType.
* NOTE: the SLE_FILE_NNN values are stored in the savegame! */
SLE_FILE_END = 0, ///< Used to mark end-of-header in tables.
SLE_FILE_I8 = 1,
SLE_FILE_U8 = 2,
SLE_FILE_I16 = 3,
SLE_FILE_U16 = 4,
SLE_FILE_I32 = 5,
SLE_FILE_U32 = 6,
SLE_FILE_I64 = 7,
SLE_FILE_U64 = 8,
SLE_FILE_STRINGID = 9, ///< StringID offset into strings-array
SLE_FILE_STRING = 10,
SLE_FILE_STRUCT = 11,
/* 4 more possible file-primitives */
SLE_FILE_TYPE_MASK = 0xf, ///< Mask to get the file-type (and not any flags).
SLE_FILE_HAS_LENGTH_FIELD = 1 << 4, ///< Bit stored in savegame to indicate field has a length field for each entry.
/* 4 bits allocated a maximum of 16 types for NumberType */
SLE_VAR_BL = 0 << 4,
SLE_VAR_I8 = 1 << 4,
SLE_VAR_U8 = 2 << 4,
SLE_VAR_I16 = 3 << 4,
SLE_VAR_U16 = 4 << 4,
SLE_VAR_I32 = 5 << 4,
SLE_VAR_U32 = 6 << 4,
SLE_VAR_I64 = 7 << 4,
SLE_VAR_U64 = 8 << 4,
SLE_VAR_NULL = 9 << 4, ///< useful to write zeros in savegame.
SLE_VAR_STRB = 10 << 4, ///< string (with pre-allocated buffer)
SLE_VAR_STR = 12 << 4, ///< string pointer
SLE_VAR_STRQ = 13 << 4, ///< string pointer enclosed in quotes
SLE_VAR_NAME = 14 << 4, ///< old custom name to be converted to a char pointer
/* 1 more possible memory-primitives */
/* Shortcut values */
SLE_VAR_CHAR = SLE_VAR_I8,
/* Default combinations of variables. As savegames change, so can variables
* and thus it is possible that the saved value and internal size do not
* match and you need to specify custom combo. The defaults are listed here */
SLE_BOOL = SLE_FILE_I8 | SLE_VAR_BL,
SLE_INT8 = SLE_FILE_I8 | SLE_VAR_I8,
SLE_UINT8 = SLE_FILE_U8 | SLE_VAR_U8,
SLE_INT16 = SLE_FILE_I16 | SLE_VAR_I16,
SLE_UINT16 = SLE_FILE_U16 | SLE_VAR_U16,
SLE_INT32 = SLE_FILE_I32 | SLE_VAR_I32,
SLE_UINT32 = SLE_FILE_U32 | SLE_VAR_U32,
SLE_INT64 = SLE_FILE_I64 | SLE_VAR_I64,
SLE_UINT64 = SLE_FILE_U64 | SLE_VAR_U64,
SLE_CHAR = SLE_FILE_I8 | SLE_VAR_CHAR,
SLE_STRINGID = SLE_FILE_STRINGID | SLE_VAR_U32,
SLE_STRINGBUF = SLE_FILE_STRING | SLE_VAR_STRB,
SLE_STRING = SLE_FILE_STRING | SLE_VAR_STR,
SLE_STRINGQUOTE = SLE_FILE_STRING | SLE_VAR_STRQ,
SLE_NAME = SLE_FILE_STRINGID | SLE_VAR_NAME,
/* Shortcut values */
SLE_UINT = SLE_UINT32,
SLE_INT = SLE_INT32,
SLE_STRB = SLE_STRINGBUF,
SLE_STR = SLE_STRING,
SLE_STRQ = SLE_STRINGQUOTE,
/* 8 bits allocated for a maximum of 8 flags
* Flags directing saving/loading of a variable */
SLF_ALLOW_CONTROL = 1 << 8, ///< Allow control codes in the strings.
SLF_ALLOW_NEWLINE = 1 << 9, ///< Allow new lines in the strings.
};
typedef uint32 VarType;
/** Type of data saved. */
enum SaveLoadType : byte {
SL_VAR = 0, ///< Save/load a variable.
SL_REF = 1, ///< Save/load a reference.
SL_STRUCT = 2, ///< Save/load a struct.
SL_STR = 3, ///< Save/load a string.
SL_STDSTR = 4, ///< Save/load a \c std::string.
SL_ARR = 5, ///< Save/load a fixed-size array of #SL_VAR elements.
SL_DEQUE = 6, ///< Save/load a deque of #SL_VAR elements.
SL_VECTOR = 7, ///< Save/load a vector of #SL_VAR elements.
SL_REFLIST = 8, ///< Save/load a list of #SL_REF elements.
SL_STRUCTLIST = 9, ///< Save/load a list of structs.
SL_SAVEBYTE = 10, ///< Save (but not load) a byte.
SL_NULL = 11, ///< Save null-bytes and load to nowhere.
SL_REFDEQUE, ///< Save/load a deque of #SL_REF elements.
SL_REFVEC, ///< Save/load a vector of #SL_REF elements.
};
typedef void *SaveLoadAddrProc(void *base, size_t extra);
/** SaveLoad type struct. Do NOT use this directly but use the SLE_ macros defined just below! */
struct SaveLoad {
std::string name; ///< Name of this field (optional, used for tables).
SaveLoadType cmd; ///< The action to take with the saved/loaded type, All types need different action.
VarType conv; ///< Type of the variable to be saved; this field combines both FileVarType and MemVarType.
uint16 length; ///< (Conditional) length of the variable (eg. arrays) (max array size is 65536 elements).
SaveLoadVersion version_from; ///< Save/load the variable starting from this savegame version.
SaveLoadVersion version_to; ///< Save/load the variable before this savegame version.
size_t size; ///< The sizeof size.
SaveLoadAddrProc *address_proc; ///< Callback proc the get the actual variable address in memory.
size_t extra_data; ///< Extra data for the callback proc.
std::shared_ptr<SaveLoadHandler> handler; ///< Custom handler for Save/Load procs.
};
/**
* SaveLoad information for backwards compatibility.
*
* At SLV_SETTINGS_NAME a new method of keeping track of fields in a savegame
* was added, where the order of fields is no longer important. For older
* savegames we still need to know the correct order. This struct is the glue
* to make that happen.
*/
struct SaveLoadCompat {
std::string name; ///< Name of the field.
uint16 length; ///< Length of the NULL field.
SaveLoadVersion version_from; ///< Save/load the variable starting from this savegame version.
SaveLoadVersion version_to; ///< Save/load the variable before this savegame version.
};
/**
* Storage of simple variables, references (pointers), and arrays.
* @param cmd Load/save type. @see SaveLoadType
* @param base Name of the class or struct containing the variable.
* @param variable Name of the variable in the class or struct referenced by \a base.
* @param type Storage of the data in memory and in the savegame.
* @param from First savegame version that has the field.
* @param to Last savegame version that has the field.
* @param extra Extra data to pass to the address callback function.
* @note In general, it is better to use one of the SLE_* macros below.
*/
#define SLE_GENERAL(cmd, base, variable, type, length, from, to, extra) SaveLoad {#variable, cmd, type, length, from, to, cpp_sizeof(base, variable), [] (void *b, size_t) -> void * { assert(b != nullptr); return const_cast<void *>(static_cast<const void *>(std::addressof(static_cast<base *>(b)->variable))); }, extra, nullptr}
#define SLE_GENERAL2(cmd, base, name, variable, type, length, from, to, extra) SaveLoad {name, cmd, type, length, from, to, cpp_sizeof(base, variable), [] (void *b, size_t) -> void * { assert(b != nullptr); return const_cast<void *>(static_cast<const void *>(std::addressof(static_cast<base *>(b)->variable))); }, extra, nullptr}
/**
* Storage of a variable in some savegame versions.
* @param base Name of the class or struct containing the variable.
* @param variable Name of the variable in the class or struct referenced by \a base.
* @param type Storage of the data in memory and in the savegame.
* @param from First savegame version that has the field.
* @param to Last savegame version that has the field.
*/
#define SLE_CONDVAR(base, variable, type, from, to) SLE_GENERAL(SL_VAR, base, variable, type, 0, from, to, 0)
#define SLE_CONDVAR2(base, name, variable, type, from, to) SLE_GENERAL2(SL_VAR, base, name, variable, type, 0, from, to, 0)
/**
* Storage of a reference in some savegame versions.
* @param base Name of the class or struct containing the variable.
* @param variable Name of the variable in the class or struct referenced by \a base.
* @param type Type of the reference, a value from #SLRefType.
* @param from First savegame version that has the field.
* @param to Last savegame version that has the field.
*/
#define SLE_CONDREF(base, variable, type, from, to) SLE_GENERAL(SL_REF, base, variable, type, 0, from, to, 0)
/**
* Storage of a fixed-size array of #SL_VAR elements in some savegame versions.
* @param base Name of the class or struct containing the array.
* @param variable Name of the variable in the class or struct referenced by \a base.
* @param type Storage of the data in memory and in the savegame.
* @param length Number of elements in the array.
* @param from First savegame version that has the array.
* @param to Last savegame version that has the array.
*/
#define SLE_CONDARR(base, variable, type, length, from, to) SLE_GENERAL(SL_ARR, base, variable, type, length, from, to, 0)
/**
* Storage of a string in some savegame versions.
* @param base Name of the class or struct containing the string.
* @param variable Name of the variable in the class or struct referenced by \a base.
* @param type Storage of the data in memory and in the savegame.
* @param length Number of elements in the string (only used for fixed size buffers).
* @param from First savegame version that has the string.
* @param to Last savegame version that has the string.
*/
#define SLE_CONDSTR(base, variable, type, length, from, to) SLE_GENERAL(SL_STR, base, variable, type, length, from, to, 0)
/**
* Storage of a \c std::string in some savegame versions.
* @param base Name of the class or struct containing the string.
* @param variable Name of the variable in the class or struct referenced by \a base.
* @param type Storage of the data in memory and in the savegame.
* @param from First savegame version that has the string.
* @param to Last savegame version that has the string.
*/
#define SLE_CONDSSTR(base, variable, type, from, to) SLE_GENERAL(SL_STDSTR, base, variable, type, 0, from, to, 0)
/**
* Storage of a list of #SL_REF elements in some savegame versions.
* @param base Name of the class or struct containing the list.
* @param variable Name of the variable in the class or struct referenced by \a base.
* @param type Storage of the data in memory and in the savegame.
* @param from First savegame version that has the list.
* @param to Last savegame version that has the list.
*/
#define SLE_CONDREFLIST(base, variable, type, from, to) SLE_GENERAL(SL_REFLIST, base, variable, type, 0, from, to, 0)
/**
* Storage of a deque of #SL_REF elements in some savegame versions.
* @param base Name of the class or struct containing the list.
* @param variable Name of the variable in the class or struct referenced by \a base.
* @param type Storage of the data in memory and in the savegame.
* @param from First savegame version that has the list.
* @param to Last savegame version that has the list.
*/
#define SLE_CONDREFDEQUE(base, variable, type, from, to) SLE_GENERAL(SL_REFDEQUE, base, variable, type, 0, from, to, 0)
/**
* Storage of a vector of #SL_REF elements in some savegame versions.
* @param base Name of the class or struct containing the list.
* @param variable Name of the variable in the class or struct referenced by \a base.
* @param type Storage of the data in memory and in the savegame.
* @param from First savegame version that has the list.
* @param to Last savegame version that has the list.
*/
#define SLE_CONDREFVEC(base, variable, type, from, to) SLE_GENERAL(SL_REFVEC, base, variable, type, 0, from, to, 0)
/**
* Storage of a deque of #SL_VAR elements in some savegame versions.
* @param base Name of the class or struct containing the list.
* @param variable Name of the variable in the class or struct referenced by \a base.
* @param type Storage of the data in memory and in the savegame.
* @param from First savegame version that has the list.
* @param to Last savegame version that has the list.
*/
#define SLE_CONDDEQUE(base, variable, type, from, to) SLE_GENERAL(SL_DEQUE, base, variable, type, 0, from, to, 0)
/**
* Storage of a variable in every version of a savegame.
* @param base Name of the class or struct containing the variable.
* @param variable Name of the variable in the class or struct referenced by \a base.
* @param type Storage of the data in memory and in the savegame.
*/
#define SLE_VAR(base, variable, type) SLE_CONDVAR(base, variable, type, SL_MIN_VERSION, SL_MAX_VERSION)
#define SLE_VAR2(base, name, variable, type) SLE_CONDVAR2(base, name, variable, type, SL_MIN_VERSION, SL_MAX_VERSION)
/**
* Storage of a reference in every version of a savegame.
* @param base Name of the class or struct containing the variable.
* @param variable Name of the variable in the class or struct referenced by \a base.
* @param type Type of the reference, a value from #SLRefType.
*/
#define SLE_REF(base, variable, type) SLE_CONDREF(base, variable, type, SL_MIN_VERSION, SL_MAX_VERSION)
/**
* Storage of fixed-size array of #SL_VAR elements in every version of a savegame.
* @param base Name of the class or struct containing the array.
* @param variable Name of the variable in the class or struct referenced by \a base.
* @param type Storage of the data in memory and in the savegame.
* @param length Number of elements in the array.
*/
#define SLE_ARR(base, variable, type, length) SLE_CONDARR(base, variable, type, length, SL_MIN_VERSION, SL_MAX_VERSION)
/**
* Storage of a string in every savegame version.
* @param base Name of the class or struct containing the string.
* @param variable Name of the variable in the class or struct referenced by \a base.
* @param type Storage of the data in memory and in the savegame.
* @param length Number of elements in the string (only used for fixed size buffers).
*/
#define SLE_STR(base, variable, type, length) SLE_CONDSTR(base, variable, type, length, SL_MIN_VERSION, SL_MAX_VERSION)
/**
* Storage of a \c std::string in every savegame version.
* @param base Name of the class or struct containing the string.
* @param variable Name of the variable in the class or struct referenced by \a base.
* @param type Storage of the data in memory and in the savegame.
*/
#define SLE_SSTR(base, variable, type) SLE_CONDSSTR(base, variable, type, SL_MIN_VERSION, SL_MAX_VERSION)
/**
* Storage of a list of #SL_REF elements in every savegame version.
* @param base Name of the class or struct containing the list.
* @param variable Name of the variable in the class or struct referenced by \a base.
* @param type Storage of the data in memory and in the savegame.
*/
#define SLE_REFLIST(base, variable, type) SLE_CONDREFLIST(base, variable, type, SL_MIN_VERSION, SL_MAX_VERSION)
/**
* Storage of a deque of #SL_REF elements in every savegame version.
* @param base Name of the class or struct containing the list.
* @param variable Name of the variable in the class or struct referenced by \a base.
* @param type Storage of the data in memory and in the savegame.
*/
#define SLE_REFDEQUE(base, variable, type) SLE_CONDREFDEQUE(base, variable, type, SL_MIN_VERSION, SL_MAX_VERSION)
/**
* Storage of a vector of #SL_REF elements in every savegame version.
* @param base Name of the class or struct containing the list.
* @param variable Name of the variable in the class or struct referenced by \a base.
* @param type Storage of the data in memory and in the savegame.
*/
#define SLE_REFVEC(base, variable, type) SLE_CONDREFVEC(base, variable, type, SL_MIN_VERSION, SL_MAX_VERSION)
/**
* Only write byte during saving; never read it during loading.
* When using SLE_SAVEBYTE you will have to read this byte before the table
* this is in is read. This also means SLE_SAVEBYTE can only be used at the
* top of a chunk.
* This is intended to be used to indicate what type of entry this is in a
* list of entries.
* @param base Name of the class or struct containing the variable.
* @param variable Name of the variable in the class or struct referenced by \a base.
*/
#define SLE_SAVEBYTE(base, variable) SLE_GENERAL(SL_SAVEBYTE, base, variable, 0, 0, SL_MIN_VERSION, SL_MAX_VERSION, 0)
/**
* Storage of global simple variables, references (pointers), and arrays.
* @param name The name of the field.
* @param cmd Load/save type. @see SaveLoadType
* @param variable Name of the global variable.
* @param type Storage of the data in memory and in the savegame.
* @param from First savegame version that has the field.
* @param to Last savegame version that has the field.
* @param extra Extra data to pass to the address callback function.
* @note In general, it is better to use one of the SLEG_* macros below.
*/
#define SLEG_GENERAL(name, cmd, variable, type, length, from, to, extra) SaveLoad {name, cmd, type, length, from, to, sizeof(variable), [] (void *, size_t) -> void * { return static_cast<void *>(std::addressof(variable)); }, extra, nullptr}
/**
* Storage of a global variable in some savegame versions.
* @param name The name of the field.
* @param variable Name of the global variable.
* @param type Storage of the data in memory and in the savegame.
* @param from First savegame version that has the field.
* @param to Last savegame version that has the field.
*/
#define SLEG_CONDVAR(name, variable, type, from, to) SLEG_GENERAL(name, SL_VAR, variable, type, 0, from, to, 0)
/**
* Storage of a global reference in some savegame versions.
* @param name The name of the field.
* @param variable Name of the global variable.
* @param type Storage of the data in memory and in the savegame.
* @param from First savegame version that has the field.
* @param to Last savegame version that has the field.
*/
#define SLEG_CONDREF(name, variable, type, from, to) SLEG_GENERAL(name, SL_REF, variable, type, 0, from, to, 0)
/**
* Storage of a global fixed-size array of #SL_VAR elements in some savegame versions.
* @param name The name of the field.
* @param variable Name of the global variable.
* @param type Storage of the data in memory and in the savegame.
* @param length Number of elements in the array.
* @param from First savegame version that has the array.
* @param to Last savegame version that has the array.
*/
#define SLEG_CONDARR(name, variable, type, length, from, to) SLEG_GENERAL(name, SL_ARR, variable, type, length, from, to, 0)
/**
* Storage of a global string in some savegame versions.
* @param name The name of the field.
* @param variable Name of the global variable.
* @param type Storage of the data in memory and in the savegame.
* @param length Number of elements in the string (only used for fixed size buffers).
* @param from First savegame version that has the string.
* @param to Last savegame version that has the string.
*/
#define SLEG_CONDSTR(name, variable, type, length, from, to) SLEG_GENERAL(name, SL_STR, variable, type, length, from, to, 0)
/**
* Storage of a global \c std::string in some savegame versions.
* @param name The name of the field.
* @param variable Name of the global variable.
* @param type Storage of the data in memory and in the savegame.
* @param from First savegame version that has the string.
* @param to Last savegame version that has the string.
*/
#define SLEG_CONDSSTR(name, variable, type, from, to) SLEG_GENERAL(name, SL_STDSTR, variable, type, 0, from, to, 0)
/**
* Storage of a structs in some savegame versions.
* @param name The name of the field.
* @param handler SaveLoadHandler for the structs.
* @param from First savegame version that has the struct.
* @param to Last savegame version that has the struct.
*/
#define SLEG_CONDSTRUCT(name, handler, from, to) SaveLoad {name, SL_STRUCT, 0, 0, from, to, 0, nullptr, 0, std::make_shared<handler>()}
/**
* Storage of a global reference list in some savegame versions.
* @param name The name of the field.
* @param variable Name of the global variable.
* @param type Storage of the data in memory and in the savegame.
* @param from First savegame version that has the list.
* @param to Last savegame version that has the list.
*/
#define SLEG_CONDREFLIST(name, variable, type, from, to) SLEG_GENERAL(name, SL_REFLIST, variable, type, 0, from, to, 0)
/**
* Storage of a global reference deque in some savegame versions.
* @param name The name of the field.
* @param variable Name of the global variable.
* @param type Storage of the data in memory and in the savegame.
* @param from First savegame version that has the list.
* @param to Last savegame version that has the list.
*/
#define SLEG_CONDREFDEQUE(name, variable, type, from, to) SLEG_GENERAL(name, SL_REFDEQUE, variable, type, 0, from, to, 0)
/**
* Storage of a global reference vector in some savegame versions.
* @param name The name of the field.
* @param variable Name of the global variable.
* @param type Storage of the data in memory and in the savegame.
* @param from First savegame version that has the list.
* @param to Last savegame version that has the list.
*/
#define SLEG_CONDREFVEC(name, variable, type, from, to) SLEG_GENERAL(name, SL_REFVEC, variable, type, 0, from, to, 0)
/**
* Storage of a global vector of #SL_VAR elements in some savegame versions.
* @param name The name of the field.
* @param variable Name of the global variable.
* @param type Storage of the data in memory and in the savegame.
* @param from First savegame version that has the list.
* @param to Last savegame version that has the list.
*/
#define SLEG_CONDVECTOR(name, variable, type, from, to) SLEG_GENERAL(name, SL_VECTOR, variable, type, 0, from, to, 0)
/**
* Storage of a list of structs in some savegame versions.
* @param name The name of the field.
* @param handler SaveLoadHandler for the list of structs.
* @param from First savegame version that has the list.
* @param to Last savegame version that has the list.
*/
#define SLEG_CONDSTRUCTLIST(name, handler, from, to) SaveLoad {name, SL_STRUCTLIST, 0, 0, from, to, 0, nullptr, 0, std::make_shared<handler>()}
/**
* Storage of a global variable in every savegame version.
* @param name The name of the field.
* @param variable Name of the global variable.
* @param type Storage of the data in memory and in the savegame.
*/
#define SLEG_VAR(name, variable, type) SLEG_CONDVAR(name, variable, type, SL_MIN_VERSION, SL_MAX_VERSION)
/**
* Storage of a global reference in every savegame version.
* @param name The name of the field.
* @param variable Name of the global variable.
* @param type Storage of the data in memory and in the savegame.
*/
#define SLEG_REF(name, variable, type) SLEG_CONDREF(name, variable, type, SL_MIN_VERSION, SL_MAX_VERSION)
/**
* Storage of a global fixed-size array of #SL_VAR elements in every savegame version.
* @param name The name of the field.
* @param variable Name of the global variable.
* @param type Storage of the data in memory and in the savegame.
*/
#define SLEG_ARR(name, variable, type) SLEG_CONDARR(name, variable, type, lengthof(variable), SL_MIN_VERSION, SL_MAX_VERSION)
/**
* Storage of a global string in every savegame version.
* @param name The name of the field.
* @param variable Name of the global variable.
* @param type Storage of the data in memory and in the savegame.
*/
#define SLEG_STR(name, variable, type) SLEG_CONDSTR(name, variable, type, sizeof(variable), SL_MIN_VERSION, SL_MAX_VERSION)
/**
* Storage of a global \c std::string in every savegame version.
* @param name The name of the field.
* @param variable Name of the global variable.
* @param type Storage of the data in memory and in the savegame.
*/
#define SLEG_SSTR(name, variable, type) SLEG_CONDSSTR(name, variable, type, SL_MIN_VERSION, SL_MAX_VERSION)
/**
* Storage of a structs in every savegame version.
* @param name The name of the field.
* @param handler SaveLoadHandler for the structs.
*/
#define SLEG_STRUCT(name, handler) SLEG_CONDSTRUCT(name, handler, SL_MIN_VERSION, SL_MAX_VERSION)
/**
* Storage of a global reference list in every savegame version.
* @param name The name of the field.
* @param variable Name of the global variable.
* @param type Storage of the data in memory and in the savegame.
*/
#define SLEG_REFLIST(name, variable, type) SLEG_CONDREFLIST(name, variable, type, SL_MIN_VERSION, SL_MAX_VERSION)
/**
* Storage of a global reference deque in every savegame version.
* @param name The name of the field.
* @param variable Name of the global variable.
* @param type Storage of the data in memory and in the savegame.
*/
#define SLEG_REFDEQUE(name, variable, type) SLEG_CONDREFDEQUE(name, variable, type, SL_MIN_VERSION, SL_MAX_VERSION)
/**
* Storage of a global vector of #SL_VAR elements in every savegame version.
* @param name The name of the field.
* @param variable Name of the global variable.
* @param type Storage of the data in memory and in the savegame.
*/
#define SLEG_VECTOR(name, variable, type) SLEG_CONDVECTOR(name, variable, type, SL_MIN_VERSION, SL_MAX_VERSION)
/**
* Storage of a list of structs in every savegame version.
* @param name The name of the field.
* @param handler SaveLoadHandler for the list of structs.
*/
#define SLEG_STRUCTLIST(name, handler) SLEG_CONDSTRUCTLIST(name, handler, SL_MIN_VERSION, SL_MAX_VERSION)
/**
* Field name where the real SaveLoad can be located.
* @param name The name of the field.
*/
#define SLC_VAR(name) {name, 0, SL_MIN_VERSION, SL_MAX_VERSION}
/**
* Empty space in every savegame version.
* @param length Length of the empty space.
* @param from First savegame version that has the empty space.
* @param to Last savegame version that has the empty space.
*/
#define SLC_NULL(length, from, to) {{}, length, from, to}
/** End marker of compat variables save or load. */
#define SLC_END() {{}, 0, SL_MIN_VERSION, SL_MIN_VERSION}
/**
* Checks whether the savegame is below \a major.\a minor.
* @param major Major number of the version to check against.
* @param minor Minor number of the version to check against. If \a minor is 0 or not specified, only the major number is checked.
* @return Savegame version is earlier than the specified version.
*/
static inline bool IsSavegameVersionBefore(SaveLoadVersion major, byte minor = 0)
{
return _sl_version < major || (minor > 0 && _sl_version == major && _sl_minor_version < minor);
}
/**
* Checks whether the savegame is below or at \a major. This should be used to repair data from existing
* savegames which is no longer corrupted in new savegames, but for which otherwise no savegame
* bump is required.
* @param major Major number of the version to check against.
* @return Savegame version is at most the specified version.
*/
static inline bool IsSavegameVersionBeforeOrAt(SaveLoadVersion major)
{
return _sl_version <= major;
}
/**
* Checks if some version from/to combination falls within the range of the
* active savegame version.
* @param version_from Inclusive savegame version lower bound.
* @param version_to Exclusive savegame version upper bound. SL_MAX_VERSION if no upper bound.
* @return Active savegame version falls within the given range.
*/
static inline bool SlIsObjectCurrentlyValid(SaveLoadVersion version_from, SaveLoadVersion version_to)
{
return version_from <= SAVEGAME_VERSION && SAVEGAME_VERSION < version_to;
}
/**
* Get the NumberType of a setting. This describes the integer type
* as it is represented in memory
* @param type VarType holding information about the variable-type
* @return the SLE_VAR_* part of a variable-type description
*/
static inline VarType GetVarMemType(VarType type)
{
return type & 0xF0; // GB(type, 4, 4) << 4;
}
/**
* Get the FileType of a setting. This describes the integer type
* as it is represented in a savegame/file
* @param type VarType holding information about the file-type
* @return the SLE_FILE_* part of a variable-type description
*/
static inline VarType GetVarFileType(VarType type)
{
return type & 0xF; // GB(type, 0, 4);
}
/**
* Check if the given saveload type is a numeric type.
* @param conv the type to check
* @return True if it's a numeric type.
*/
static inline bool IsNumericType(VarType conv)
{
return GetVarMemType(conv) <= SLE_VAR_U64;
}
/**
* Get the address of the variable. Null-variables don't have an address,
* everything else has a callback function that returns the address based
* on the saveload data and the current object for non-globals.
*/
static inline void *GetVariableAddress(const void *object, const SaveLoad &sld)
{
/* Entry is a null-variable, mostly used to read old savegames etc. */
if (GetVarMemType(sld.conv) == SLE_VAR_NULL) {
assert(sld.address_proc == nullptr);
return nullptr;
}
/* Everything else should be a non-null pointer. */
assert(sld.address_proc != nullptr);
return sld.address_proc(const_cast<void *>(object), sld.extra_data);
}
int64 ReadValue(const void *ptr, VarType conv);
void WriteValue(void *ptr, VarType conv, int64 val);
void SlSetArrayIndex(uint index);
int SlIterateArray();
void SlSetStructListLength(size_t length);
size_t SlGetStructListLength(size_t limit);
void SlAutolength(AutolengthProc *proc, void *arg);
size_t SlGetFieldLength();
void SlSetLength(size_t length);
size_t SlCalcObjMemberLength(const void *object, const SaveLoad &sld);
size_t SlCalcObjLength(const void *object, const SaveLoadTable &slt);
void SlGlobList(const SaveLoadTable &slt);
void SlCopy(void *object, size_t length, VarType conv);
std::vector<SaveLoad> SlTableHeader(const SaveLoadTable &slt);
std::vector<SaveLoad> SlCompatTableHeader(const SaveLoadTable &slt, const SaveLoadCompatTable &slct);
void SlObject(void *object, const SaveLoadTable &slt);
}
#endif /* UPSTREAM_SAVELOAD_H */

@ -0,0 +1,228 @@
/*
* This file is part of OpenTTD.
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file settings_sl.cpp Handles the saveload part of the settings. */
#include "../../stdafx.h"
#include "saveload.h"
#include "debug.h"
#include "compat/settings_sl_compat.h"
#include "../../settings_type.h"
#include "../../settings_internal.h"
#include "../../network/network.h"
#include "../../fios.h"
#include "../../safeguards.h"
const SettingTable &GetSettingsTableInternal();
namespace upstream_sl {
/**
* Get the SaveLoad description for the SettingTable.
* @param settings SettingDesc struct containing all information.
* @param is_loading True iff the SaveLoad table is for loading.
* @return Vector with SaveLoad entries for the SettingTable.
*/
static std::vector<SaveLoad> GetSettingsDesc(bool is_loading)
{
std::vector<SaveLoad> saveloads;
for (auto &sd : GetSettingsTableInternal()) {
if (sd->flags & SF_NOT_IN_SAVE) continue;
if (sd->patx_name != nullptr) continue;
if (!sd->save.ext_feature_test.IsFeaturePresent(_sl_version, sd->save.version_from, sd->save.version_to)) continue;
VarType new_type = 0;
switch (sd->save.conv & 0x0F) {
case ::SLE_FILE_I8:
new_type |= SLE_FILE_I8;
break;
case ::SLE_FILE_U8:
new_type |= SLE_FILE_U8;
break;
case ::SLE_FILE_I16:
new_type |= SLE_FILE_I16;
break;
case ::SLE_FILE_U16:
new_type |= SLE_FILE_U16;
break;
case ::SLE_FILE_I32:
new_type |= SLE_FILE_I32;
break;
case ::SLE_FILE_U32:
new_type |= SLE_FILE_U32;
break;
case ::SLE_FILE_I64:
new_type |= SLE_FILE_I64;
break;
case ::SLE_FILE_U64:
new_type |= SLE_FILE_U64;
break;
case ::SLE_FILE_STRINGID:
new_type |= SLE_FILE_STRINGID;
break;
case ::SLE_FILE_STRING:
new_type |= SLE_FILE_STRING;
break;
default:
error("Unexpected save conv for %s: 0x%02X", sd->name, sd->save.conv);
}
switch (sd->save.conv & 0xF0) {
case ::SLE_VAR_BL:
new_type |= SLE_VAR_BL;
break;
case ::SLE_VAR_I8:
new_type |= SLE_VAR_I8;
break;
case ::SLE_VAR_U8:
new_type |= SLE_VAR_U8;
break;
case ::SLE_VAR_I16:
new_type |= SLE_VAR_I16;
break;
case ::SLE_VAR_U16:
new_type |= SLE_VAR_U16;
break;
case ::SLE_VAR_I32:
new_type |= SLE_VAR_I32;
break;
case ::SLE_VAR_U32:
new_type |= SLE_VAR_U32;
break;
case ::SLE_VAR_I64:
new_type |= SLE_VAR_I64;
break;
case ::SLE_VAR_U64:
new_type |= SLE_VAR_U64;
break;
case ::SLE_VAR_NULL:
new_type |= SLE_VAR_NULL;
break;
case ::SLE_VAR_STRB:
new_type |= SLE_VAR_STRB;
break;
case ::SLE_VAR_STR:
new_type |= SLE_VAR_STR;
break;
case ::SLE_VAR_STRQ:
new_type |= SLE_VAR_STRQ;
break;
default:
error("Unexpected save conv for %s: 0x%02X", sd->name, sd->save.conv);
}
if (strcmp(sd->name, "economy.town_growth_rate") == 0) {
SB(new_type, 0, 4, SLE_FILE_U8);
}
SaveLoadType new_cmd;
switch (sd->save.cmd) {
case ::SL_VAR:
new_cmd = SL_VAR;
break;
case ::SL_STR:
new_cmd = SL_STR;
break;
case ::SL_STDSTR:
new_cmd = SL_STDSTR;
break;
default:
error("Unexpected save cmd for %s: %u", sd->name, sd->save.cmd);
}
if (is_loading && (sd->flags & SF_NO_NETWORK_SYNC) && _networking && !_network_server) {
if (IsSavegameVersionBefore(SLV_TABLE_CHUNKS)) {
/* We don't want to read this setting, so we do need to skip over it. */
saveloads.push_back({sd->name, new_cmd, GetVarFileType(new_type) | SLE_VAR_NULL, sd->save.length, SL_MIN_VERSION, SL_MAX_VERSION, 0, nullptr, 0, nullptr});
}
continue;
}
SaveLoadAddrProc *address_proc = [](void *base, size_t extra) -> void* {
return const_cast<byte *>((const byte *)base + (ptrdiff_t)extra);
};
saveloads.push_back({sd->name, new_cmd, new_type, sd->save.length, SL_MIN_VERSION, SL_MAX_VERSION, sd->save.size, address_proc, reinterpret_cast<uintptr_t>(sd->save.address), nullptr});
}
return saveloads;
}
/**
* Save and load handler for settings
* @param settings SettingDesc struct containing all information
* @param object can be either nullptr in which case we load global variables or
* a pointer to a struct which is getting saved
*/
static void LoadSettings(void *object, const SaveLoadCompatTable &slct)
{
const std::vector<SaveLoad> slt = SlCompatTableHeader(GetSettingsDesc(true), slct);
if (!IsSavegameVersionBefore(SLV_RIFF_TO_ARRAY) && SlIterateArray() == -1) return;
SlObject(object, slt);
if (!IsSavegameVersionBefore(SLV_RIFF_TO_ARRAY) && SlIterateArray() != -1) SlErrorCorrupt("Too many settings entries");
/* Ensure all IntSettings are valid (min/max could have changed between versions etc). */
for (auto &sd : GetSettingsTableInternal()) {
if (sd->flags & SF_NOT_IN_SAVE) continue;
if ((sd->flags & SF_NO_NETWORK_SYNC) && _networking && !_network_server) continue;
if (!sd->save.ext_feature_test.IsFeaturePresent(SAVEGAME_VERSION, sd->save.version_from, sd->save.version_to)) continue;
if (sd->IsIntSetting()) {
const IntSettingDesc *int_setting = sd->AsIntSetting();
int_setting->MakeValueValidAndWrite(object, int_setting->Read(object));
}
}
}
/**
* Save and load handler for settings
* @param settings SettingDesc struct containing all information
* @param object can be either nullptr in which case we load global variables or
* a pointer to a struct which is getting saved
*/
static void SaveSettings(void *object)
{
const std::vector<SaveLoad> slt = GetSettingsDesc(false);
SlTableHeader(slt);
SlSetArrayIndex(0);
SlObject(object, slt);
}
struct PATSChunkHandler : ChunkHandler {
PATSChunkHandler() : ChunkHandler('PATS', CH_TABLE) {}
void Load() const override
{
/* Copy over default setting since some might not get loaded in
* a networking environment. This ensures for example that the local
* currency setting stays when joining a network-server */
LoadSettings(&_settings_game, _settings_sl_compat);
}
void LoadCheck(size_t) const override
{
LoadSettings(&_load_check_data.settings, _settings_sl_compat);
}
void Save() const override
{
SaveSettings(&_settings_game);
}
};
static const PATSChunkHandler PATS;
static const ChunkHandlerRef setting_chunk_handlers[] = {
PATS,
};
extern const ChunkHandlerTable _setting_chunk_handlers(setting_chunk_handlers);
}

@ -0,0 +1,81 @@
/*
* This file is part of OpenTTD.
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file signs_sl.cpp Code handling saving and loading of economy data */
#include "../../stdafx.h"
#include "saveload.h"
#include "compat/signs_sl_compat.h"
#include "../../signs_base.h"
#include "../../fios.h"
#include "../../safeguards.h"
namespace upstream_sl {
/** Description of a sign within the savegame. */
static const SaveLoad _sign_desc[] = {
SLE_CONDVAR(Sign, name, SLE_NAME, SL_MIN_VERSION, SLV_84),
SLE_CONDSSTR(Sign, name, SLE_STR | SLF_ALLOW_CONTROL, SLV_84, SL_MAX_VERSION),
SLE_CONDVAR(Sign, x, SLE_FILE_I16 | SLE_VAR_I32, SL_MIN_VERSION, SLV_5),
SLE_CONDVAR(Sign, y, SLE_FILE_I16 | SLE_VAR_I32, SL_MIN_VERSION, SLV_5),
SLE_CONDVAR(Sign, x, SLE_INT32, SLV_5, SL_MAX_VERSION),
SLE_CONDVAR(Sign, y, SLE_INT32, SLV_5, SL_MAX_VERSION),
SLE_CONDVAR(Sign, owner, SLE_UINT8, SLV_6, SL_MAX_VERSION),
SLE_CONDVAR(Sign, z, SLE_FILE_U8 | SLE_VAR_I32, SL_MIN_VERSION, SLV_164),
SLE_CONDVAR(Sign, z, SLE_INT32, SLV_164, SL_MAX_VERSION),
};
struct SIGNChunkHandler : ChunkHandler {
SIGNChunkHandler() : ChunkHandler('SIGN', CH_TABLE) {}
void Save() const override
{
SlTableHeader(_sign_desc);
for (Sign *si : Sign::Iterate()) {
SlSetArrayIndex(si->index);
SlObject(si, _sign_desc);
}
}
void Load() const override
{
const std::vector<SaveLoad> slt = SlCompatTableHeader(_sign_desc, _sign_sl_compat);
int index;
while ((index = SlIterateArray()) != -1) {
Sign *si = new (index) Sign();
SlObject(si, slt);
/* Before version 6.1, signs didn't have owner.
* Before version 83, invalid signs were determined by si->str == 0.
* Before version 103, owner could be a bankrupted company.
* - we can't use IsValidCompany() now, so this is fixed in AfterLoadGame()
* All signs that were saved are valid (including those with just 'Sign' and INVALID_OWNER).
* - so set owner to OWNER_NONE if needed (signs from pre-version 6.1 would be lost) */
if (IsSavegameVersionBefore(SLV_6, 1) || (IsSavegameVersionBefore(SLV_83) && si->owner == INVALID_OWNER)) {
si->owner = OWNER_NONE;
}
/* Signs placed in scenario editor shall now be OWNER_DEITY */
if (IsSavegameVersionBefore(SLV_171) && si->owner == OWNER_NONE && SaveLoadFileTypeIsScenario()) {
si->owner = OWNER_DEITY;
}
}
}
};
static const SIGNChunkHandler SIGN;
static const ChunkHandlerRef sign_chunk_handlers[] = {
SIGN,
};
extern const ChunkHandlerTable _sign_chunk_handlers(sign_chunk_handlers);
}

@ -0,0 +1,531 @@
/*
* This file is part of OpenTTD.
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file station_sl.cpp Code handling saving and loading of stations. */
#include "../../stdafx.h"
#include "saveload.h"
#include "compat/station_sl_compat.h"
#include "../../station_base.h"
#include "../../waypoint_base.h"
#include "../../roadstop_base.h"
#include "../../vehicle_base.h"
#include "../../newgrf_station.h"
#include "table/strings.h"
#include "../../safeguards.h"
namespace upstream_sl {
static const SaveLoad _roadstop_desc[] = {
SLE_VAR(RoadStop, xy, SLE_UINT32),
SLE_VAR(RoadStop, status, SLE_UINT8),
SLE_REF(RoadStop, next, REF_ROADSTOPS),
};
static uint16 _waiting_acceptance;
static uint32 _old_num_flows;
static uint16 _cargo_source;
static uint32 _cargo_source_xy;
static uint8 _cargo_days;
static Money _cargo_feeder_share;
CargoPacketList _packets;
uint32 _old_num_dests;
struct FlowSaveLoad {
FlowSaveLoad() : source(0), via(0), share(0), restricted(false) {}
StationID source;
StationID via;
uint32 share;
bool restricted;
};
typedef std::pair<const StationID, CargoPacketList > StationCargoPair;
static OldPersistentStorage _old_st_persistent_storage;
static byte _old_last_vehicle_type;
/**
* Swap the temporary packets with the packets without specific destination in
* the given goods entry. Assert that at least one of those is empty.
* @param ge Goods entry to swap with.
*/
static void SwapPackets(GoodsEntry *ge)
{
StationCargoPacketMap &ge_packets = const_cast<StationCargoPacketMap &>(*ge->cargo.Packets());
if (_packets.empty()) {
std::map<StationID, CargoPacketList>::iterator it(ge_packets.find(INVALID_STATION));
if (it == ge_packets.end()) {
return;
} else {
it->second.swap(_packets);
}
} else {
assert(ge_packets[INVALID_STATION].empty());
ge_packets[INVALID_STATION].swap(_packets);
}
}
class SlStationSpecList : public DefaultSaveLoadHandler<SlStationSpecList, BaseStation> {
public:
inline static const SaveLoad description[] = {
SLE_CONDVAR(StationSpecList, grfid, SLE_UINT32, SLV_27, SL_MAX_VERSION),
SLE_CONDVAR(StationSpecList, localidx, SLE_UINT8, SLV_27, SL_MAX_VERSION),
};
inline const static SaveLoadCompatTable compat_description = _station_spec_list_sl_compat;
void Save(BaseStation *bst) const override
{
SlSetStructListLength(bst->num_specs);
for (uint i = 0; i < bst->num_specs; i++) {
SlObject(&bst->speclist[i], this->GetDescription());
}
}
void Load(BaseStation *bst) const override
{
if (!IsSavegameVersionBefore(SLV_SAVELOAD_LIST_LENGTH)) {
bst->num_specs = (uint8)SlGetStructListLength(UINT8_MAX);
}
if (bst->num_specs != 0) {
/* Allocate speclist memory when loading a game */
bst->speclist = CallocT<StationSpecList>(bst->num_specs);
for (uint i = 0; i < bst->num_specs; i++) {
SlObject(&bst->speclist[i], this->GetLoadDescription());
}
}
}
};
class SlStationCargo : public DefaultSaveLoadHandler<SlStationCargo, GoodsEntry> {
public:
inline static const SaveLoad description[] = {
SLE_VAR(StationCargoPair, first, SLE_UINT16),
SLE_REFDEQUE(StationCargoPair, second, REF_CARGO_PACKET),
};
inline const static SaveLoadCompatTable compat_description = _station_cargo_sl_compat;
void Save(GoodsEntry *ge) const override
{
// removed
NOT_REACHED();
}
void Load(GoodsEntry *ge) const override
{
size_t num_dests = IsSavegameVersionBefore(SLV_SAVELOAD_LIST_LENGTH) ? _old_num_dests : SlGetStructListLength(UINT32_MAX);
StationCargoPair pair;
for (uint j = 0; j < num_dests; ++j) {
SlObject(&pair, this->GetLoadDescription());
const_cast<StationCargoPacketMap &>(*(ge->cargo.Packets()))[pair.first].swap(pair.second);
assert(pair.second.empty());
}
}
void FixPointers(GoodsEntry *ge) const override
{
for (StationCargoPacketMap::ConstMapIterator it = ge->cargo.Packets()->begin(); it != ge->cargo.Packets()->end(); ++it) {
SlObject(const_cast<StationCargoPair *>(&(*it)), this->GetDescription());
}
}
};
class SlStationFlow : public DefaultSaveLoadHandler<SlStationFlow, GoodsEntry> {
public:
inline static const SaveLoad description[] = {
SLE_VAR(FlowSaveLoad, source, SLE_UINT16),
SLE_VAR(FlowSaveLoad, via, SLE_UINT16),
SLE_VAR(FlowSaveLoad, share, SLE_UINT32),
SLE_CONDVAR(FlowSaveLoad, restricted, SLE_BOOL, SLV_187, SL_MAX_VERSION),
};
inline const static SaveLoadCompatTable compat_description = _station_flow_sl_compat;
void Save(GoodsEntry *ge) const override
{
// removed
NOT_REACHED();
}
void Load(GoodsEntry *ge) const override
{
size_t num_flows = IsSavegameVersionBefore(SLV_SAVELOAD_LIST_LENGTH) ? _old_num_flows : SlGetStructListLength(UINT32_MAX);
FlowSaveLoad flow;
FlowStat *fs = nullptr;
StationID prev_source = INVALID_STATION;
for (uint32 j = 0; j < num_flows; ++j) {
SlObject(&flow, this->GetLoadDescription());
if (fs == nullptr || prev_source != flow.source) {
fs = &(*(ge->flows.insert(ge->flows.end(), FlowStat(flow.source, flow.via, flow.share, flow.restricted))));
} else {
fs->AppendShare(flow.via, flow.share, flow.restricted);
}
prev_source = flow.source;
}
}
};
class SlStationGoods : public DefaultSaveLoadHandler<SlStationGoods, BaseStation> {
public:
#if defined(_MSC_VER) && (_MSC_VER == 1915 || _MSC_VER == 1916)
/* This table access private members of other classes; they have this
* class as friend. For MSVC CL 19.15 and 19.16 this doesn't work for
* "inline static const", so we are forced to wrap the table in a
* function. CL 19.16 is the latest for VS2017. */
inline static const SaveLoad description[] = {{}};
SaveLoadTable GetDescription() const override {
#else
inline
#endif
static const SaveLoad description[] = {
SLEG_CONDVAR("waiting_acceptance", _waiting_acceptance, SLE_UINT16, SL_MIN_VERSION, SLV_68),
SLE_CONDVAR(GoodsEntry, status, SLE_UINT8, SLV_68, SL_MAX_VERSION),
SLE_VAR(GoodsEntry, time_since_pickup, SLE_UINT8),
SLE_VAR(GoodsEntry, rating, SLE_UINT8),
SLEG_CONDVAR("cargo_source", _cargo_source, SLE_FILE_U8 | SLE_VAR_U16, SL_MIN_VERSION, SLV_7),
SLEG_CONDVAR("cargo_source", _cargo_source, SLE_UINT16, SLV_7, SLV_68),
SLEG_CONDVAR("cargo_source_xy", _cargo_source_xy, SLE_UINT32, SLV_44, SLV_68),
SLEG_CONDVAR("cargo_days", _cargo_days, SLE_UINT8, SL_MIN_VERSION, SLV_68),
SLE_VAR(GoodsEntry, last_speed, SLE_UINT8),
SLE_VAR(GoodsEntry, last_age, SLE_UINT8),
SLEG_CONDVAR("cargo_feeder_share", _cargo_feeder_share, SLE_FILE_U32 | SLE_VAR_I64, SLV_14, SLV_65),
SLEG_CONDVAR("cargo_feeder_share", _cargo_feeder_share, SLE_INT64, SLV_65, SLV_68),
SLE_CONDVAR(GoodsEntry, amount_fract, SLE_UINT8, SLV_150, SL_MAX_VERSION),
SLEG_CONDREFDEQUE("packets", _packets, REF_CARGO_PACKET, SLV_68, SLV_183),
SLEG_CONDVAR("old_num_dests", _old_num_dests, SLE_UINT32, SLV_183, SLV_SAVELOAD_LIST_LENGTH),
SLE_CONDVAR(GoodsEntry, cargo.reserved_count, SLE_UINT, SLV_181, SL_MAX_VERSION),
SLE_CONDVAR(GoodsEntry, link_graph, SLE_UINT16, SLV_183, SL_MAX_VERSION),
SLE_CONDVAR(GoodsEntry, node, SLE_UINT16, SLV_183, SL_MAX_VERSION),
SLEG_CONDVAR("old_num_flows", _old_num_flows, SLE_UINT32, SLV_183, SLV_SAVELOAD_LIST_LENGTH),
SLE_CONDVAR(GoodsEntry, max_waiting_cargo, SLE_UINT32, SLV_183, SL_MAX_VERSION),
SLEG_CONDSTRUCTLIST("flow", SlStationFlow, SLV_183, SL_MAX_VERSION),
SLEG_CONDSTRUCTLIST("cargo", SlStationCargo, SLV_183, SL_MAX_VERSION),
};
#if defined(_MSC_VER) && (_MSC_VER == 1915 || _MSC_VER == 1916)
return description;
}
#endif
inline const static SaveLoadCompatTable compat_description = _station_goods_sl_compat;
/**
* Get the number of cargoes used by this savegame version.
* @return The number of cargoes used by this savegame version.
*/
size_t GetNumCargo() const
{
if (IsSavegameVersionBefore(SLV_55)) return 12;
if (IsSavegameVersionBefore(SLV_EXTEND_CARGOTYPES)) return 32;
if (IsSavegameVersionBefore(SLV_SAVELOAD_LIST_LENGTH)) return NUM_CARGO;
/* Read from the savegame how long the list is. */
return SlGetStructListLength(NUM_CARGO);
}
void Save(BaseStation *bst) const override
{
Station *st = Station::From(bst);
SlSetStructListLength(NUM_CARGO);
for (CargoID i = 0; i < NUM_CARGO; i++) {
SlObject(&st->goods[i], this->GetDescription());
}
}
void Load(BaseStation *bst) const override
{
Station *st = Station::From(bst);
/* Before savegame version 161, persistent storages were not stored in a pool. */
if (IsSavegameVersionBefore(SLV_161) && !IsSavegameVersionBefore(SLV_145) && st->facilities & FACIL_AIRPORT) {
/* Store the old persistent storage. The GRFID will be added later. */
assert(PersistentStorage::CanAllocateItem());
st->airport.psa = new PersistentStorage(0, 0, 0);
memcpy(st->airport.psa->storage, _old_st_persistent_storage.storage, sizeof(_old_st_persistent_storage.storage));
}
size_t num_cargo = this->GetNumCargo();
for (CargoID i = 0; i < num_cargo; i++) {
GoodsEntry *ge = &st->goods[i];
SlObject(ge, this->GetLoadDescription());
if (IsSavegameVersionBefore(SLV_183)) {
SwapPackets(ge);
}
if (IsSavegameVersionBefore(SLV_68)) {
SB(ge->status, GoodsEntry::GES_ACCEPTANCE, 1, HasBit(_waiting_acceptance, 15));
if (GB(_waiting_acceptance, 0, 12) != 0) {
/* In old versions, enroute_from used 0xFF as INVALID_STATION */
StationID source = (IsSavegameVersionBefore(SLV_7) && _cargo_source == 0xFF) ? INVALID_STATION : _cargo_source;
/* Make sure we can allocate the CargoPacket. This is safe
* as there can only be ~64k stations and 32 cargoes in these
* savegame versions. As the CargoPacketPool has more than
* 16 million entries; it fits by an order of magnitude. */
assert(CargoPacket::CanAllocateItem());
/* Don't construct the packet with station here, because that'll fail with old savegames */
CargoPacket *cp = new CargoPacket(GB(_waiting_acceptance, 0, 12), _cargo_days, source, _cargo_source_xy, _cargo_source_xy, _cargo_feeder_share);
ge->cargo.Append(cp, INVALID_STATION);
SB(ge->status, GoodsEntry::GES_RATING, 1, 1);
}
}
}
}
void FixPointers(BaseStation *bst) const override
{
Station *st = Station::From(bst);
uint num_cargo = IsSavegameVersionBefore(SLV_55) ? 12 : IsSavegameVersionBefore(SLV_EXTEND_CARGOTYPES) ? 32 : NUM_CARGO;
for (CargoID i = 0; i < num_cargo; i++) {
GoodsEntry *ge = &st->goods[i];
if (IsSavegameVersionBefore(SLV_183)) {
SwapPackets(ge); // We have to swap back again to be in the format pre-183 expects.
SlObject(ge, this->GetDescription());
SwapPackets(ge);
} else {
SlObject(ge, this->GetDescription());
}
}
}
};
/**
* SaveLoad handler for the BaseStation, which all other stations / waypoints
* make use of.
*/
class SlStationBase : public DefaultSaveLoadHandler<SlStationBase, BaseStation> {
public:
inline static const SaveLoad description[] = {
SLE_VAR(BaseStation, xy, SLE_UINT32),
SLE_REF(BaseStation, town, REF_TOWN),
SLE_VAR(BaseStation, string_id, SLE_STRINGID),
SLE_STR(BaseStation, name, SLE_STR | SLF_ALLOW_CONTROL, 0),
SLE_VAR(BaseStation, delete_ctr, SLE_UINT8),
SLE_VAR(BaseStation, owner, SLE_UINT8),
SLE_VAR(BaseStation, facilities, SLE_UINT8),
SLE_VAR(BaseStation, build_date, SLE_INT32),
/* Used by newstations for graphic variations */
SLE_VAR(BaseStation, random_bits, SLE_UINT16),
SLE_VAR(BaseStation, waiting_triggers, SLE_UINT8),
SLE_CONDVAR(BaseStation, num_specs, SLE_UINT8, SL_MIN_VERSION, SLV_SAVELOAD_LIST_LENGTH),
};
inline const static SaveLoadCompatTable compat_description = _station_base_sl_compat;
void Save(BaseStation *bst) const override
{
SlObject(bst, this->GetDescription());
}
void Load(BaseStation *bst) const override
{
SlObject(bst, this->GetLoadDescription());
}
void FixPointers(BaseStation *bst) const override
{
SlObject(bst, this->GetDescription());
}
};
/**
* SaveLoad handler for a normal station (read: not a waypoint).
*/
class SlStationNormal : public DefaultSaveLoadHandler<SlStationNormal, BaseStation> {
public:
inline static const SaveLoad description[] = {
SLEG_STRUCT("base", SlStationBase),
SLE_VAR(Station, train_station.tile, SLE_UINT32),
SLE_VAR(Station, train_station.w, SLE_FILE_U8 | SLE_VAR_U16),
SLE_VAR(Station, train_station.h, SLE_FILE_U8 | SLE_VAR_U16),
SLE_REF(Station, bus_stops, REF_ROADSTOPS),
SLE_REF(Station, truck_stops, REF_ROADSTOPS),
SLE_CONDVAR(Station, ship_station.tile, SLE_UINT32, SLV_MULTITILE_DOCKS, SL_MAX_VERSION),
SLE_CONDVAR(Station, ship_station.w, SLE_FILE_U8 | SLE_VAR_U16, SLV_MULTITILE_DOCKS, SL_MAX_VERSION),
SLE_CONDVAR(Station, ship_station.h, SLE_FILE_U8 | SLE_VAR_U16, SLV_MULTITILE_DOCKS, SL_MAX_VERSION),
SLE_CONDVAR(Station, docking_station.tile, SLE_UINT32, SLV_MULTITILE_DOCKS, SL_MAX_VERSION),
SLE_CONDVAR(Station, docking_station.w, SLE_FILE_U8 | SLE_VAR_U16, SLV_MULTITILE_DOCKS, SL_MAX_VERSION),
SLE_CONDVAR(Station, docking_station.h, SLE_FILE_U8 | SLE_VAR_U16, SLV_MULTITILE_DOCKS, SL_MAX_VERSION),
SLE_VAR(Station, airport.tile, SLE_UINT32),
SLE_CONDVAR(Station, airport.w, SLE_FILE_U8 | SLE_VAR_U16, SLV_140, SL_MAX_VERSION),
SLE_CONDVAR(Station, airport.h, SLE_FILE_U8 | SLE_VAR_U16, SLV_140, SL_MAX_VERSION),
SLE_VAR(Station, airport.type, SLE_UINT8),
SLE_CONDVAR(Station, airport.layout, SLE_UINT8, SLV_145, SL_MAX_VERSION),
SLE_VAR(Station, airport.flags, SLE_UINT64),
SLE_CONDVAR(Station, airport.rotation, SLE_UINT8, SLV_145, SL_MAX_VERSION),
SLEG_CONDARR("storage", _old_st_persistent_storage.storage, SLE_UINT32, 16, SLV_145, SLV_161),
SLE_CONDREF(Station, airport.psa, REF_STORAGE, SLV_161, SL_MAX_VERSION),
SLE_VAR(Station, indtype, SLE_UINT8),
SLE_VAR(Station, time_since_load, SLE_UINT8),
SLE_VAR(Station, time_since_unload, SLE_UINT8),
SLEG_VAR("last_vehicle_type", _old_last_vehicle_type, SLE_UINT8),
SLE_VAR(Station, had_vehicle_of_type, SLE_UINT8),
SLE_REFVEC(Station, loading_vehicles, REF_VEHICLE),
SLE_CONDVAR(Station, always_accepted, SLE_FILE_U32 | SLE_VAR_U64, SLV_127, SLV_EXTEND_CARGOTYPES),
SLE_CONDVAR(Station, always_accepted, SLE_UINT64, SLV_EXTEND_CARGOTYPES, SL_MAX_VERSION),
SLEG_STRUCTLIST("goods", SlStationGoods),
};
inline const static SaveLoadCompatTable compat_description = _station_normal_sl_compat;
void Save(BaseStation *bst) const
{
if ((bst->facilities & FACIL_WAYPOINT) != 0) return;
SlObject(bst, this->GetDescription());
}
void Load(BaseStation *bst) const
{
if ((bst->facilities & FACIL_WAYPOINT) != 0) return;
SlObject(bst, this->GetLoadDescription());
for (CargoID i = 0; i < NUM_CARGO; i++) {
Station::From(bst)->goods[i].last_vehicle_type = _old_last_vehicle_type;
}
}
void FixPointers(BaseStation *bst) const
{
if ((bst->facilities & FACIL_WAYPOINT) != 0) return;
SlObject(bst, this->GetDescription());
}
};
class SlStationWaypoint : public DefaultSaveLoadHandler<SlStationWaypoint, BaseStation> {
public:
inline static const SaveLoad description[] = {
SLEG_STRUCT("base", SlStationBase),
SLE_VAR(Waypoint, town_cn, SLE_UINT16),
SLE_CONDVAR(Waypoint, train_station.tile, SLE_UINT32, SLV_124, SL_MAX_VERSION),
SLE_CONDVAR(Waypoint, train_station.w, SLE_FILE_U8 | SLE_VAR_U16, SLV_124, SL_MAX_VERSION),
SLE_CONDVAR(Waypoint, train_station.h, SLE_FILE_U8 | SLE_VAR_U16, SLV_124, SL_MAX_VERSION),
};
inline const static SaveLoadCompatTable compat_description = _station_waypoint_sl_compat;
void Save(BaseStation *bst) const
{
if ((bst->facilities & FACIL_WAYPOINT) == 0) return;
SlObject(bst, this->GetDescription());
}
void Load(BaseStation *bst) const
{
if ((bst->facilities & FACIL_WAYPOINT) == 0) return;
SlObject(bst, this->GetLoadDescription());
}
void FixPointers(BaseStation *bst) const
{
if ((bst->facilities & FACIL_WAYPOINT) == 0) return;
SlObject(bst, this->GetDescription());
}
};
static const SaveLoad _station_desc[] = {
SLE_SAVEBYTE(BaseStation, facilities),
SLEG_STRUCT("normal", SlStationNormal),
SLEG_STRUCT("waypoint", SlStationWaypoint),
SLEG_CONDSTRUCTLIST("speclist", SlStationSpecList, SLV_27, SL_MAX_VERSION),
};
struct STNNChunkHandler : ChunkHandler {
STNNChunkHandler() : ChunkHandler('STNN', CH_TABLE) {}
void Save() const override
{
SlTableHeader(_station_desc);
/* Write the stations */
for (BaseStation *st : BaseStation::Iterate()) {
SlSetArrayIndex(st->index);
SlObject(st, _station_desc);
}
}
void Load() const override
{
const std::vector<SaveLoad> slt = SlCompatTableHeader(_station_desc, _station_sl_compat);
_old_num_flows = 0;
int index;
while ((index = SlIterateArray()) != -1) {
bool waypoint = (SlReadByte() & FACIL_WAYPOINT) != 0;
BaseStation *bst = waypoint ? (BaseStation *)new (index) Waypoint() : new (index) Station();
SlObject(bst, slt);
}
}
void FixPointers() const override
{
/* From SLV_123 we store stations in STNN; before that in STNS. So do not
* fix pointers when the version is below SLV_123, as that would fix
* pointers twice: once in STNS chunk and once here. */
if (IsSavegameVersionBefore(SLV_123)) return;
for (BaseStation *bst : BaseStation::Iterate()) {
SlObject(bst, _station_desc);
}
}
};
struct ROADChunkHandler : ChunkHandler {
ROADChunkHandler() : ChunkHandler('ROAD', CH_TABLE) {}
void Save() const override
{
SlTableHeader(_roadstop_desc);
for (RoadStop *rs : RoadStop::Iterate()) {
SlSetArrayIndex(rs->index);
SlObject(rs, _roadstop_desc);
}
}
void Load() const override
{
const std::vector<SaveLoad> slt = SlCompatTableHeader(_roadstop_desc, _roadstop_sl_compat);
int index;
while ((index = SlIterateArray()) != -1) {
RoadStop *rs = new (index) RoadStop(INVALID_TILE);
SlObject(rs, slt);
}
}
void FixPointers() const override
{
for (RoadStop *rs : RoadStop::Iterate()) {
SlObject(rs, _roadstop_desc);
}
}
};
static const STNNChunkHandler STNN;
static const ROADChunkHandler ROAD;
static const ChunkHandlerRef station_chunk_handlers[] = {
STNN,
ROAD,
};
extern const ChunkHandlerTable _station_chunk_handlers(station_chunk_handlers);
}

@ -0,0 +1,65 @@
/*
* This file is part of OpenTTD.
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file storage_sl.cpp Code handling saving and loading of persistent storages. */
#include "../../stdafx.h"
#include "saveload.h"
#include "compat/storage_sl_compat.h"
#include "../../newgrf_storage.h"
#include "../../safeguards.h"
namespace upstream_sl {
/** Description of the data to save and load in #PersistentStorage. */
static const SaveLoad _storage_desc[] = {
SLE_CONDVAR(PersistentStorage, grfid, SLE_UINT32, SLV_6, SL_MAX_VERSION),
SLE_CONDARR(PersistentStorage, storage, SLE_UINT32, 16, SLV_161, SLV_EXTEND_PERSISTENT_STORAGE),
SLE_CONDARR(PersistentStorage, storage, SLE_UINT32, 256, SLV_EXTEND_PERSISTENT_STORAGE, SL_MAX_VERSION),
};
/** Persistent storage data. */
struct PSACChunkHandler : ChunkHandler {
PSACChunkHandler() : ChunkHandler('PSAC', CH_TABLE) {}
void Load() const override
{
const std::vector<SaveLoad> slt = SlCompatTableHeader(_storage_desc, _storage_sl_compat);
int index;
while ((index = SlIterateArray()) != -1) {
assert(PersistentStorage::CanAllocateItem());
PersistentStorage *ps = new (index) PersistentStorage(0, 0, 0);
SlObject(ps, slt);
}
}
void Save() const override
{
SlTableHeader(_storage_desc);
/* Write the industries */
for (PersistentStorage *ps : PersistentStorage::Iterate()) {
ps->ClearChanges();
SlSetArrayIndex(ps->index);
SlObject(ps, _storage_desc);
}
}
};
static const PSACChunkHandler PSAC;
static const ChunkHandlerRef persistent_storage_chunk_handlers[] = {
PSAC,
};
extern const ChunkHandlerTable _persistent_storage_chunk_handlers(persistent_storage_chunk_handlers);
}

@ -0,0 +1,115 @@
/*
* This file is part of OpenTTD.
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file story_sl.cpp Code handling saving and loading of story pages */
#include "../../stdafx.h"
#include "saveload.h"
#include "compat/story_sl_compat.h"
#include "../../story_base.h"
#include "../../safeguards.h"
namespace upstream_sl {
static const SaveLoad _story_page_elements_desc[] = {
SLE_CONDVAR(StoryPageElement, sort_value, SLE_FILE_U16 | SLE_VAR_U32, SL_MIN_VERSION, SLV_185),
SLE_CONDVAR(StoryPageElement, sort_value, SLE_UINT32, SLV_185, SL_MAX_VERSION),
SLE_VAR(StoryPageElement, page, SLE_UINT16),
SLE_CONDVAR(StoryPageElement, type, SLE_FILE_U16 | SLE_VAR_U8, SL_MIN_VERSION, SLV_185),
SLE_CONDVAR(StoryPageElement, type, SLE_UINT8, SLV_185, SL_MAX_VERSION),
SLE_VAR(StoryPageElement, referenced_id, SLE_UINT32),
SLE_STR(StoryPageElement, text, SLE_STR | SLF_ALLOW_CONTROL, 0),
};
struct STPEChunkHandler : ChunkHandler {
STPEChunkHandler() : ChunkHandler('STPE', CH_TABLE) {}
void Save() const override
{
SlTableHeader(_story_page_elements_desc);
for (StoryPageElement *s : StoryPageElement::Iterate()) {
SlSetArrayIndex(s->index);
SlObject(s, _story_page_elements_desc);
}
}
void Load() const override
{
const std::vector<SaveLoad> slt = SlCompatTableHeader(_story_page_elements_desc, _story_page_elements_sl_compat);
int index;
uint32 max_sort_value = 0;
while ((index = SlIterateArray()) != -1) {
StoryPageElement *s = new (index) StoryPageElement();
SlObject(s, slt);
if (s->sort_value > max_sort_value) {
max_sort_value = s->sort_value;
}
}
/* Update the next sort value, so that the next
* created page is shown after all existing pages.
*/
_story_page_element_next_sort_value = max_sort_value + 1;
}
};
static const SaveLoad _story_pages_desc[] = {
SLE_CONDVAR(StoryPage, sort_value, SLE_FILE_U16 | SLE_VAR_U32, SL_MIN_VERSION, SLV_185),
SLE_CONDVAR(StoryPage, sort_value, SLE_UINT32, SLV_185, SL_MAX_VERSION),
SLE_VAR(StoryPage, date, SLE_UINT32),
SLE_CONDVAR(StoryPage, company, SLE_FILE_U16 | SLE_VAR_U8, SL_MIN_VERSION, SLV_185),
SLE_CONDVAR(StoryPage, company, SLE_UINT8, SLV_185, SL_MAX_VERSION),
SLE_STR(StoryPage, title, SLE_STR | SLF_ALLOW_CONTROL, 0),
};
struct STPAChunkHandler : ChunkHandler {
STPAChunkHandler() : ChunkHandler('STPA', CH_TABLE) {}
void Save() const override
{
SlTableHeader(_story_pages_desc);
for (StoryPage *s : StoryPage::Iterate()) {
SlSetArrayIndex(s->index);
SlObject(s, _story_pages_desc);
}
}
void Load() const override
{
const std::vector<SaveLoad> slt = SlCompatTableHeader(_story_pages_desc, _story_pages_sl_compat);
int index;
uint32 max_sort_value = 0;
while ((index = SlIterateArray()) != -1) {
StoryPage *s = new (index) StoryPage();
SlObject(s, slt);
if (s->sort_value > max_sort_value) {
max_sort_value = s->sort_value;
}
}
/* Update the next sort value, so that the next
* created page is shown after all existing pages.
*/
_story_page_next_sort_value = max_sort_value + 1;
}
};
static const STPEChunkHandler STPE;
static const STPAChunkHandler STPA;
static const ChunkHandlerRef story_page_chunk_handlers[] = {
STPE,
STPA,
};
extern const ChunkHandlerTable _story_page_chunk_handlers(story_page_chunk_handlers);
}

@ -0,0 +1,66 @@
/*
* This file is part of OpenTTD.
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file subsidy_sl.cpp Code handling saving and loading of subsidies */
#include "../../stdafx.h"
#include "saveload.h"
#include "compat/subsidy_sl_compat.h"
#include "../../subsidy_base.h"
#include "../../safeguards.h"
namespace upstream_sl {
static const SaveLoad _subsidies_desc[] = {
SLE_VAR(Subsidy, cargo_type, SLE_UINT8),
SLE_CONDVAR(Subsidy, remaining, SLE_FILE_U8 | SLE_VAR_U16, SL_MIN_VERSION, SLV_CUSTOM_SUBSIDY_DURATION),
SLE_CONDVAR(Subsidy, remaining, SLE_UINT16, SLV_CUSTOM_SUBSIDY_DURATION, SL_MAX_VERSION),
SLE_CONDVAR(Subsidy, awarded, SLE_UINT8, SLV_125, SL_MAX_VERSION),
SLE_CONDVAR(Subsidy, src_type, SLE_UINT8, SLV_125, SL_MAX_VERSION),
SLE_CONDVAR(Subsidy, dst_type, SLE_UINT8, SLV_125, SL_MAX_VERSION),
SLE_CONDVAR(Subsidy, src, SLE_FILE_U8 | SLE_VAR_U16, SL_MIN_VERSION, SLV_5),
SLE_CONDVAR(Subsidy, src, SLE_UINT16, SLV_5, SL_MAX_VERSION),
SLE_CONDVAR(Subsidy, dst, SLE_FILE_U8 | SLE_VAR_U16, SL_MIN_VERSION, SLV_5),
SLE_CONDVAR(Subsidy, dst, SLE_UINT16, SLV_5, SL_MAX_VERSION),
};
struct SUBSChunkHandler : ChunkHandler {
SUBSChunkHandler() : ChunkHandler('SUBS', CH_TABLE) {}
void Save() const override
{
SlTableHeader(_subsidies_desc);
for (Subsidy *s : Subsidy::Iterate()) {
SlSetArrayIndex(s->index);
SlObject(s, _subsidies_desc);
}
}
void Load() const override
{
const std::vector<SaveLoad> slt = SlCompatTableHeader(_subsidies_desc, _subsidies_sl_compat);
int index;
while ((index = SlIterateArray()) != -1) {
Subsidy *s = new (index) Subsidy();
SlObject(s, slt);
}
}
};
static const SUBSChunkHandler SUBS;
static const ChunkHandlerRef subsidy_chunk_handlers[] = {
SUBS,
};
extern const ChunkHandlerTable _subsidy_chunk_handlers(subsidy_chunk_handlers);
}

@ -0,0 +1,238 @@
/*
* This file is part of OpenTTD.
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file town_sl.cpp Code handling saving and loading of towns and houses */
#include "../../stdafx.h"
#include "saveload.h"
#include "compat/town_sl_compat.h"
#include "newgrf_sl.h"
#include "../../newgrf_house.h"
#include "../../town.h"
#include "../../landscape.h"
#include "../../subsidy_func.h"
#include "../../strings_func.h"
#include "../../tilematrix_type.hpp"
#include "../../safeguards.h"
namespace upstream_sl {
typedef TileMatrix<CargoTypes, 4> AcceptanceMatrix;
class SlTownSupplied : public DefaultSaveLoadHandler<SlTownSupplied, Town> {
public:
inline static const SaveLoad description[] = {
SLE_CONDVAR(TransportedCargoStat<uint32>, old_max, SLE_UINT32, SLV_165, SL_MAX_VERSION),
SLE_CONDVAR(TransportedCargoStat<uint32>, new_max, SLE_UINT32, SLV_165, SL_MAX_VERSION),
SLE_CONDVAR(TransportedCargoStat<uint32>, old_act, SLE_UINT32, SLV_165, SL_MAX_VERSION),
SLE_CONDVAR(TransportedCargoStat<uint32>, new_act, SLE_UINT32, SLV_165, SL_MAX_VERSION),
};
inline const static SaveLoadCompatTable compat_description = _town_supplied_sl_compat;
/**
* Get the number of cargoes used by this savegame version.
* @return The number of cargoes used by this savegame version.
*/
size_t GetNumCargo() const
{
if (IsSavegameVersionBefore(SLV_EXTEND_CARGOTYPES)) return 32;
if (IsSavegameVersionBefore(SLV_SAVELOAD_LIST_LENGTH)) return NUM_CARGO;
/* Read from the savegame how long the list is. */
return SlGetStructListLength(NUM_CARGO);
}
void Save(Town *t) const override
{
SlSetStructListLength(NUM_CARGO);
for (CargoID i = 0; i < NUM_CARGO; i++) {
SlObject(&t->supplied[i], this->GetDescription());
}
}
void Load(Town *t) const override
{
size_t num_cargo = this->GetNumCargo();
for (CargoID i = 0; i < num_cargo; i++) {
SlObject(&t->supplied[i], this->GetLoadDescription());
}
}
};
class SlTownReceived : public DefaultSaveLoadHandler<SlTownReceived, Town> {
public:
inline static const SaveLoad description[] = {
SLE_CONDVAR(TransportedCargoStat<uint16>, old_max, SLE_UINT16, SLV_165, SL_MAX_VERSION),
SLE_CONDVAR(TransportedCargoStat<uint16>, new_max, SLE_UINT16, SLV_165, SL_MAX_VERSION),
SLE_CONDVAR(TransportedCargoStat<uint16>, old_act, SLE_UINT16, SLV_165, SL_MAX_VERSION),
SLE_CONDVAR(TransportedCargoStat<uint16>, new_act, SLE_UINT16, SLV_165, SL_MAX_VERSION),
};
inline const static SaveLoadCompatTable compat_description = _town_received_sl_compat;
void Save(Town *t) const override
{
SlSetStructListLength(NUM_TE);
for (size_t i = TE_BEGIN; i < TE_END; i++) {
SlObject(&t->received[i], this->GetDescription());
}
}
void Load(Town *t) const override
{
size_t length = IsSavegameVersionBefore(SLV_SAVELOAD_LIST_LENGTH) ? (size_t)TE_END : SlGetStructListLength(TE_END);
for (size_t i = 0; i < length; i++) {
SlObject(&t->received[i], this->GetLoadDescription());
}
}
};
class SlTownAcceptanceMatrix : public DefaultSaveLoadHandler<SlTownAcceptanceMatrix, Town> {
public:
inline static const SaveLoad description[] = {
SLE_VAR(AcceptanceMatrix, area.tile, SLE_UINT32),
SLE_VAR(AcceptanceMatrix, area.w, SLE_UINT16),
SLE_VAR(AcceptanceMatrix, area.h, SLE_UINT16),
};
inline const static SaveLoadCompatTable compat_description = _town_acceptance_matrix_sl_compat;
void Load(Town *t) const override
{
/* Discard now unused acceptance matrix. */
AcceptanceMatrix dummy;
SlObject(&dummy, this->GetLoadDescription());
if (dummy.area.w != 0) {
uint arr_len = dummy.area.w / AcceptanceMatrix::GRID * dummy.area.h / AcceptanceMatrix::GRID;
SlSkipBytes(4 * arr_len);
}
}
};
static const SaveLoad _town_desc[] = {
SLE_CONDVAR(Town, xy, SLE_FILE_U16 | SLE_VAR_U32, SL_MIN_VERSION, SLV_6),
SLE_CONDVAR(Town, xy, SLE_UINT32, SLV_6, SL_MAX_VERSION),
SLE_CONDVAR(Town, townnamegrfid, SLE_UINT32, SLV_66, SL_MAX_VERSION),
SLE_VAR(Town, townnametype, SLE_UINT16),
SLE_VAR(Town, townnameparts, SLE_UINT32),
SLE_CONDSTR(Town, name, SLE_STR | SLF_ALLOW_CONTROL, 0, SLV_84, SL_MAX_VERSION),
SLE_VAR(Town, flags, SLE_UINT8),
SLE_CONDVAR(Town, statues, SLE_FILE_U8 | SLE_VAR_U16, SL_MIN_VERSION, SLV_104),
SLE_CONDVAR(Town, statues, SLE_UINT16, SLV_104, SL_MAX_VERSION),
SLE_CONDVAR(Town, have_ratings, SLE_FILE_U8 | SLE_VAR_U16, SL_MIN_VERSION, SLV_104),
SLE_CONDVAR(Town, have_ratings, SLE_UINT16, SLV_104, SL_MAX_VERSION),
SLE_CONDARR(Town, ratings, SLE_INT16, 8, SL_MIN_VERSION, SLV_104),
SLE_CONDARR(Town, ratings, SLE_INT16, MAX_COMPANIES, SLV_104, SL_MAX_VERSION),
SLE_CONDARR(Town, unwanted, SLE_INT8, 8, SLV_4, SLV_104),
SLE_CONDARR(Town, unwanted, SLE_INT8, MAX_COMPANIES, SLV_104, SL_MAX_VERSION),
SLE_CONDVAR(Town, supplied[CT_PASSENGERS].old_max, SLE_FILE_U16 | SLE_VAR_U32, SL_MIN_VERSION, SLV_9),
SLE_CONDVAR(Town, supplied[CT_PASSENGERS].old_max, SLE_UINT32, SLV_9, SLV_165),
SLE_CONDVAR(Town, supplied[CT_MAIL].old_max, SLE_FILE_U16 | SLE_VAR_U32, SL_MIN_VERSION, SLV_9),
SLE_CONDVAR(Town, supplied[CT_MAIL].old_max, SLE_UINT32, SLV_9, SLV_165),
SLE_CONDVAR(Town, supplied[CT_PASSENGERS].new_max, SLE_FILE_U16 | SLE_VAR_U32, SL_MIN_VERSION, SLV_9),
SLE_CONDVAR(Town, supplied[CT_PASSENGERS].new_max, SLE_UINT32, SLV_9, SLV_165),
SLE_CONDVAR(Town, supplied[CT_MAIL].new_max, SLE_FILE_U16 | SLE_VAR_U32, SL_MIN_VERSION, SLV_9),
SLE_CONDVAR(Town, supplied[CT_MAIL].new_max, SLE_UINT32, SLV_9, SLV_165),
SLE_CONDVAR(Town, supplied[CT_PASSENGERS].old_act, SLE_FILE_U16 | SLE_VAR_U32, SL_MIN_VERSION, SLV_9),
SLE_CONDVAR(Town, supplied[CT_PASSENGERS].old_act, SLE_UINT32, SLV_9, SLV_165),
SLE_CONDVAR(Town, supplied[CT_MAIL].old_act, SLE_FILE_U16 | SLE_VAR_U32, SL_MIN_VERSION, SLV_9),
SLE_CONDVAR(Town, supplied[CT_MAIL].old_act, SLE_UINT32, SLV_9, SLV_165),
SLE_CONDVAR(Town, supplied[CT_PASSENGERS].new_act, SLE_FILE_U16 | SLE_VAR_U32, SL_MIN_VERSION, SLV_9),
SLE_CONDVAR(Town, supplied[CT_PASSENGERS].new_act, SLE_UINT32, SLV_9, SLV_165),
SLE_CONDVAR(Town, supplied[CT_MAIL].new_act, SLE_FILE_U16 | SLE_VAR_U32, SL_MIN_VERSION, SLV_9),
SLE_CONDVAR(Town, supplied[CT_MAIL].new_act, SLE_UINT32, SLV_9, SLV_165),
SLE_CONDVAR(Town, received[TE_FOOD].old_act, SLE_UINT16, SL_MIN_VERSION, SLV_165),
SLE_CONDVAR(Town, received[TE_WATER].old_act, SLE_UINT16, SL_MIN_VERSION, SLV_165),
SLE_CONDVAR(Town, received[TE_FOOD].new_act, SLE_UINT16, SL_MIN_VERSION, SLV_165),
SLE_CONDVAR(Town, received[TE_WATER].new_act, SLE_UINT16, SL_MIN_VERSION, SLV_165),
SLE_CONDARR(Town, goal, SLE_UINT32, NUM_TE, SLV_165, SL_MAX_VERSION),
SLE_CONDSSTR(Town, text, SLE_STR | SLF_ALLOW_CONTROL, SLV_168, SL_MAX_VERSION),
SLE_CONDVAR(Town, time_until_rebuild, SLE_FILE_U8 | SLE_VAR_U16, SL_MIN_VERSION, SLV_54),
SLE_CONDVAR(Town, time_until_rebuild, SLE_UINT16, SLV_54, SL_MAX_VERSION),
SLE_CONDVAR(Town, grow_counter, SLE_FILE_U8 | SLE_VAR_U16, SL_MIN_VERSION, SLV_54),
SLE_CONDVAR(Town, grow_counter, SLE_UINT16, SLV_54, SL_MAX_VERSION),
SLE_CONDVAR(Town, growth_rate, SLE_FILE_U8 | SLE_VAR_I16, SL_MIN_VERSION, SLV_54),
SLE_CONDVAR(Town, growth_rate, SLE_FILE_I16 | SLE_VAR_U16, SLV_54, SLV_165),
SLE_CONDVAR(Town, growth_rate, SLE_UINT16, SLV_165, 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, SLV_2, SL_MAX_VERSION),
SLE_CONDVAR(Town, exclusive_counter, SLE_UINT8, SLV_2, SL_MAX_VERSION),
SLE_CONDVAR(Town, larger_town, SLE_BOOL, SLV_56, SL_MAX_VERSION),
SLE_CONDVAR(Town, layout, SLE_UINT8, SLV_113, SL_MAX_VERSION),
SLE_CONDREFLIST(Town, psa_list, REF_STORAGE, SLV_161, SL_MAX_VERSION),
SLEG_CONDSTRUCTLIST("supplied", SlTownSupplied, SLV_165, SL_MAX_VERSION),
SLEG_CONDSTRUCTLIST("received", SlTownReceived, SLV_165, SL_MAX_VERSION),
SLEG_CONDSTRUCTLIST("acceptance_matrix", SlTownAcceptanceMatrix, SLV_166, SLV_REMOVE_TOWN_CARGO_CACHE),
};
struct HIDSChunkHandler : NewGRFMappingChunkHandler {
HIDSChunkHandler() : NewGRFMappingChunkHandler('HIDS', _house_mngr) {}
};
struct CITYChunkHandler : ChunkHandler {
CITYChunkHandler() : ChunkHandler('CITY', CH_TABLE) {}
void Save() const override
{
SlTableHeader(_town_desc);
for (Town *t : Town::Iterate()) {
SlSetArrayIndex(t->index);
SlObject(t, _town_desc);
}
}
void Load() const override
{
const std::vector<SaveLoad> slt = SlCompatTableHeader(_town_desc, _town_sl_compat);
int index;
while ((index = SlIterateArray()) != -1) {
Town *t = new (index) Town();
SlObject(t, slt);
if (t->townnamegrfid == 0 && !IsInsideMM(t->townnametype, SPECSTR_TOWNNAME_START, SPECSTR_TOWNNAME_LAST + 1) && GetStringTab(t->townnametype) != TEXT_TAB_OLD_CUSTOM) {
SlErrorCorrupt("Invalid town name generator");
}
}
}
void FixPointers() const override
{
if (IsSavegameVersionBefore(SLV_161)) return;
for (Town *t : Town::Iterate()) {
SlObject(t, _town_desc);
}
}
};
static const HIDSChunkHandler HIDS;
static const CITYChunkHandler CITY;
static const ChunkHandlerRef town_chunk_handlers[] = {
HIDS,
CITY,
};
extern const ChunkHandlerTable _town_chunk_handlers(town_chunk_handlers);
}

@ -0,0 +1,547 @@
/*
* This file is part of OpenTTD.
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file vehicle_sl.cpp Code handling saving and loading of vehicles */
#include "../../stdafx.h"
#include "saveload.h"
#include "compat/vehicle_sl_compat.h"
#include "../../vehicle_func.h"
#include "../../train.h"
#include "../../roadveh.h"
#include "../../ship.h"
#include "../../aircraft.h"
#include "../../station_base.h"
#include "../../effectvehicle_base.h"
#include "../../company_base.h"
#include "../../company_func.h"
#include "../../disaster_vehicle.h"
#include <map>
#include "../../safeguards.h"
void AfterLoadVehicles(bool part_of_load);
bool TrainController(Train *v, Vehicle *nomove, bool reverse = true); // From train_cmd.cpp
void ReverseTrainDirection(Train *v);
void ReverseTrainSwapVeh(Train *v, int l, int r);
namespace upstream_sl {
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;
class SlVehicleCommon : public DefaultSaveLoadHandler<SlVehicleCommon, Vehicle> {
public:
#if defined(_MSC_VER) && (_MSC_VER == 1915 || _MSC_VER == 1916)
/* This table access private members of other classes; they have this
* class as friend. For MSVC CL 19.15 and 19.16 this doesn't work for
* "inline static const", so we are forced to wrap the table in a
* function. CL 19.16 is the latest for VS2017. */
inline static const SaveLoad description[] = {{}};
SaveLoadTable GetDescription() const override {
#else
inline
#endif
static const SaveLoad description[] = {
SLE_VAR(Vehicle, subtype, SLE_UINT8),
SLE_REF(Vehicle, next, REF_VEHICLE_OLD),
//SLE_CONDVAR(Vehicle, name, SLE_NAME, SL_MIN_VERSION, SLV_84),
SLE_CONDSTR(Vehicle, name, SLE_STR | SLF_ALLOW_CONTROL, 0, SLV_84, SL_MAX_VERSION),
SLE_CONDVAR(Vehicle, unitnumber, SLE_FILE_U8 | SLE_VAR_U16, SL_MIN_VERSION, SLV_8),
SLE_CONDVAR(Vehicle, unitnumber, SLE_UINT16, SLV_8, SL_MAX_VERSION),
SLE_VAR(Vehicle, owner, SLE_UINT8),
SLE_CONDVAR(Vehicle, tile, SLE_FILE_U16 | SLE_VAR_U32, SL_MIN_VERSION, SLV_6),
SLE_CONDVAR(Vehicle, tile, SLE_UINT32, SLV_6, SL_MAX_VERSION),
SLE_CONDVAR(Vehicle, dest_tile, SLE_FILE_U16 | SLE_VAR_U32, SL_MIN_VERSION, SLV_6),
SLE_CONDVAR(Vehicle, dest_tile, SLE_UINT32, SLV_6, SL_MAX_VERSION),
SLE_CONDVAR(Vehicle, x_pos, SLE_FILE_U16 | SLE_VAR_U32, SL_MIN_VERSION, SLV_6),
SLE_CONDVAR(Vehicle, x_pos, SLE_UINT32, SLV_6, SL_MAX_VERSION),
SLE_CONDVAR(Vehicle, y_pos, SLE_FILE_U16 | SLE_VAR_U32, SL_MIN_VERSION, SLV_6),
SLE_CONDVAR(Vehicle, y_pos, SLE_UINT32, SLV_6, SL_MAX_VERSION),
SLE_CONDVAR(Vehicle, z_pos, SLE_FILE_U8 | SLE_VAR_I32, SL_MIN_VERSION, SLV_164),
SLE_CONDVAR(Vehicle, z_pos, SLE_INT32, SLV_164, SL_MAX_VERSION),
SLE_VAR(Vehicle, direction, SLE_UINT8),
SLE_VAR(Vehicle, spritenum, SLE_UINT8),
SLE_VAR(Vehicle, engine_type, SLE_UINT16),
SLE_VAR(Vehicle, cur_speed, SLE_UINT16),
SLE_VAR(Vehicle, subspeed, SLE_UINT8),
SLE_VAR(Vehicle, acceleration, SLE_UINT8),
SLE_CONDVAR(Vehicle, motion_counter, SLE_UINT32, SLV_VEH_MOTION_COUNTER, SL_MAX_VERSION),
SLE_VAR(Vehicle, progress, SLE_UINT8),
SLE_VAR(Vehicle, vehstatus, SLE_UINT8),
SLE_CONDVAR(Vehicle, last_station_visited, SLE_FILE_U8 | SLE_VAR_U16, SL_MIN_VERSION, SLV_5),
SLE_CONDVAR(Vehicle, last_station_visited, SLE_UINT16, SLV_5, SL_MAX_VERSION),
SLE_CONDVAR(Vehicle, last_loading_station, SLE_UINT16, SLV_182, SL_MAX_VERSION),
SLE_VAR(Vehicle, cargo_type, SLE_UINT8),
SLE_CONDVAR(Vehicle, cargo_subtype, SLE_UINT8, SLV_35, SL_MAX_VERSION),
SLEG_CONDVAR("cargo_days", _cargo_days, SLE_UINT8, SL_MIN_VERSION, SLV_68),
SLEG_CONDVAR("cargo_source", _cargo_source, SLE_FILE_U8 | SLE_VAR_U16, SL_MIN_VERSION, SLV_7),
SLEG_CONDVAR("cargo_source", _cargo_source, SLE_UINT16, SLV_7, SLV_68),
SLEG_CONDVAR("cargo_source_xy", _cargo_source_xy, SLE_UINT32, SLV_44, SLV_68),
SLE_VAR(Vehicle, cargo_cap, SLE_UINT16),
SLE_CONDVAR(Vehicle, refit_cap, SLE_UINT16, SLV_182, SL_MAX_VERSION),
SLEG_CONDVAR("cargo_count", _cargo_count, SLE_UINT16, SL_MIN_VERSION, SLV_68),
SLE_CONDREFDEQUE(Vehicle, cargo.packets, REF_CARGO_PACKET, SLV_68, SL_MAX_VERSION),
SLE_CONDARR(Vehicle, cargo.action_counts, SLE_UINT, VehicleCargoList::NUM_MOVE_TO_ACTION, SLV_181, SL_MAX_VERSION),
SLE_CONDVAR(Vehicle, cargo_age_counter, SLE_UINT16, SLV_162, SL_MAX_VERSION),
SLE_VAR(Vehicle, day_counter, SLE_UINT8),
SLE_VAR(Vehicle, tick_counter, SLE_UINT8),
SLE_CONDVAR(Vehicle, running_ticks, SLE_FILE_U8 | SLE_VAR_U16, SLV_88, SL_MAX_VERSION),
SLE_VAR(Vehicle, cur_implicit_order_index, SLE_FILE_U8 | SLE_VAR_U16),
SLE_CONDVAR(Vehicle, cur_real_order_index, SLE_FILE_U8 | SLE_VAR_U16, SLV_158, SL_MAX_VERSION),
/* 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_CONDVAR(Vehicle, current_order.type, SLE_UINT8, SL_MIN_VERSION, SLV_5),
SLE_CONDVAR(Vehicle, current_order.dest, SLE_FILE_U8 | SLE_VAR_U16, SL_MIN_VERSION, SLV_5),
/* Orders for version 5 and on */
SLE_CONDVAR(Vehicle, current_order.type, SLE_UINT8, SLV_5, SL_MAX_VERSION),
SLE_CONDVAR(Vehicle, current_order.flags, SLE_FILE_U8 | SLE_VAR_U16, SLV_5, SL_MAX_VERSION),
SLE_CONDVAR(Vehicle, current_order.dest, SLE_UINT16, SLV_5, SL_MAX_VERSION),
/* Refit in current order */
SLE_CONDVAR(Vehicle, current_order.refit_cargo, SLE_UINT8, SLV_36, SL_MAX_VERSION),
/* Timetable in current order */
SLE_CONDVAR(Vehicle, current_order.wait_time, SLE_FILE_U16 | SLE_VAR_U32, SLV_67, SL_MAX_VERSION),
SLE_CONDVAR(Vehicle, current_order.travel_time, SLE_FILE_U16 | SLE_VAR_U32, SLV_67, SL_MAX_VERSION),
SLE_CONDVAR(Vehicle, current_order.max_speed, SLE_UINT16, SLV_174, SL_MAX_VERSION),
SLE_CONDVAR(Vehicle, timetable_start, SLE_INT32, SLV_129, SL_MAX_VERSION),
SLE_CONDREF(Vehicle, orders, REF_ORDER, SL_MIN_VERSION, SLV_105),
SLE_CONDREF(Vehicle, orders, REF_ORDERLIST, SLV_105, SL_MAX_VERSION),
SLE_CONDVAR(Vehicle, age, SLE_FILE_U16 | SLE_VAR_I32, SL_MIN_VERSION, SLV_31),
SLE_CONDVAR(Vehicle, age, SLE_INT32, SLV_31, SL_MAX_VERSION),
SLE_CONDVAR(Vehicle, max_age, SLE_FILE_U16 | SLE_VAR_I32, SL_MIN_VERSION, SLV_31),
SLE_CONDVAR(Vehicle, max_age, SLE_INT32, SLV_31, SL_MAX_VERSION),
SLE_CONDVAR(Vehicle, date_of_last_service, SLE_FILE_U16 | SLE_VAR_I32, SL_MIN_VERSION, SLV_31),
SLE_CONDVAR(Vehicle, date_of_last_service, SLE_INT32, SLV_31, SL_MAX_VERSION),
SLE_CONDVAR(Vehicle, service_interval, SLE_UINT16, SL_MIN_VERSION, SLV_31),
SLE_CONDVAR(Vehicle, service_interval, SLE_FILE_U32 | SLE_VAR_U16, SLV_31, SLV_180),
SLE_CONDVAR(Vehicle, service_interval, SLE_UINT16, SLV_180, 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, SL_MIN_VERSION, SLV_31),
SLE_CONDVAR(Vehicle, build_year, SLE_INT32, SLV_31, SL_MAX_VERSION),
SLE_VAR(Vehicle, load_unload_ticks, SLE_UINT16),
SLEG_CONDVAR("cargo_paid_for", _cargo_paid_for, SLE_UINT16, SLV_45, SL_MAX_VERSION),
SLE_CONDVAR(Vehicle, vehicle_flags, SLE_FILE_U8 | SLE_VAR_U16, SLV_40, SLV_180),
SLE_CONDVAR(Vehicle, vehicle_flags, SLE_UINT16, SLV_180, SL_MAX_VERSION),
SLE_CONDVAR(Vehicle, profit_this_year, SLE_FILE_I32 | SLE_VAR_I64, SL_MIN_VERSION, SLV_65),
SLE_CONDVAR(Vehicle, profit_this_year, SLE_INT64, SLV_65, SL_MAX_VERSION),
SLE_CONDVAR(Vehicle, profit_last_year, SLE_FILE_I32 | SLE_VAR_I64, SL_MIN_VERSION, SLV_65),
SLE_CONDVAR(Vehicle, profit_last_year, SLE_INT64, SLV_65, SL_MAX_VERSION),
SLEG_CONDVAR("cargo_feeder_share", _cargo_feeder_share, SLE_FILE_I32 | SLE_VAR_I64, SLV_51, SLV_65),
SLEG_CONDVAR("cargo_feeder_share", _cargo_feeder_share, SLE_INT64, SLV_65, SLV_68),
SLEG_CONDVAR("cargo_loaded_at_xy", _cargo_loaded_at_xy, SLE_UINT32, SLV_51, SLV_68),
SLE_CONDVAR(Vehicle, value, SLE_FILE_I32 | SLE_VAR_I64, SL_MIN_VERSION, SLV_65),
SLE_CONDVAR(Vehicle, value, SLE_INT64, SLV_65, SL_MAX_VERSION),
SLE_CONDVAR(Vehicle, random_bits, SLE_UINT8, SLV_2, SL_MAX_VERSION),
SLE_CONDVAR(Vehicle, waiting_triggers, SLE_UINT8, SLV_2, SL_MAX_VERSION),
SLE_CONDREF(Vehicle, next_shared, REF_VEHICLE, SLV_2, SL_MAX_VERSION),
SLE_CONDVAR(Vehicle, group_id, SLE_UINT16, SLV_60, SL_MAX_VERSION),
SLE_CONDVAR(Vehicle, current_order_time, SLE_UINT32, SLV_67, SL_MAX_VERSION),
SLE_CONDVAR(Vehicle, lateness_counter, SLE_INT32, SLV_67, SL_MAX_VERSION),
};
#if defined(_MSC_VER) && (_MSC_VER == 1915 || _MSC_VER == 1916)
return description;
}
#endif
inline const static SaveLoadCompatTable compat_description = _vehicle_common_sl_compat;
void Save(Vehicle *v) const override
{
SlObject(v, this->GetDescription());
}
void Load(Vehicle *v) const override
{
SlObject(v, this->GetLoadDescription());
}
void FixPointers(Vehicle *v) const override
{
SlObject(v, this->GetDescription());
}
};
class SlVehicleTrain : public DefaultSaveLoadHandler<SlVehicleTrain, Vehicle> {
public:
inline static const SaveLoad description[] = {
SLEG_STRUCT("common", SlVehicleCommon),
SLE_VAR(Train, crash_anim_pos, SLE_UINT16),
SLE_VAR(Train, force_proceed, SLE_UINT8),
SLE_VAR(Train, railtype, SLE_UINT8),
SLE_VAR(Train, track, SLE_UINT8),
SLE_CONDVAR(Train, flags, SLE_FILE_U8 | SLE_VAR_U32, SLV_2, SLV_100),
SLE_CONDVAR(Train, flags, SLE_FILE_U16 | SLE_VAR_U32, SLV_100, SL_MAX_VERSION),
SLE_CONDVAR(Train, wait_counter, SLE_UINT16, SLV_136, SL_MAX_VERSION),
SLE_CONDVAR(Train, gv_flags, SLE_UINT16, SLV_139, SL_MAX_VERSION),
};
inline const static SaveLoadCompatTable compat_description = _vehicle_train_sl_compat;
void Save(Vehicle *v) const override
{
if (v->type != VEH_TRAIN) return;
SlObject(v, this->GetDescription());
}
void Load(Vehicle *v) const override
{
if (v->type != VEH_TRAIN) return;
SlObject(v, this->GetLoadDescription());
if (v->cur_real_order_index == 0xFF) v->cur_real_order_index = INVALID_VEH_ORDER_ID;
if (v->cur_implicit_order_index == 0xFF) v->cur_implicit_order_index = INVALID_VEH_ORDER_ID;
}
void FixPointers(Vehicle *v) const override
{
if (v->type != VEH_TRAIN) return;
SlObject(v, this->GetDescription());
}
};
class SlVehicleRoadVeh : public DefaultSaveLoadHandler<SlVehicleRoadVeh, Vehicle> {
public:
inline static const SaveLoad description[] = {
SLEG_STRUCT("common", SlVehicleCommon),
SLE_VAR(RoadVehicle, state, SLE_UINT8),
SLE_VAR(RoadVehicle, frame, SLE_UINT8),
SLE_VAR(RoadVehicle, blocked_ctr, SLE_UINT16),
SLE_VAR(RoadVehicle, overtaking, SLE_UINT8),
SLE_VAR(RoadVehicle, overtaking_ctr, SLE_UINT8),
SLE_VAR(RoadVehicle, crashed_ctr, SLE_UINT16),
SLE_VAR(RoadVehicle, reverse_ctr, SLE_UINT8),
SLE_CONDDEQUE(RoadVehicle, path.td, SLE_UINT8, SLV_ROADVEH_PATH_CACHE, SL_MAX_VERSION),
SLE_CONDDEQUE(RoadVehicle, path.tile, SLE_UINT32, SLV_ROADVEH_PATH_CACHE, SL_MAX_VERSION),
SLE_CONDVAR(RoadVehicle, gv_flags, SLE_UINT16, SLV_139, SL_MAX_VERSION),
};
inline const static SaveLoadCompatTable compat_description = _vehicle_roadveh_sl_compat;
void Save(Vehicle *v) const override
{
if (v->type != VEH_ROAD) return;
SlObject(v, this->GetDescription());
}
void Load(Vehicle *v) const override
{
if (v->type != VEH_ROAD) return;
SlObject(v, this->GetLoadDescription());
}
void FixPointers(Vehicle *v) const override
{
if (v->type != VEH_ROAD) return;
SlObject(v, this->GetDescription());
}
};
class SlVehicleShip : public DefaultSaveLoadHandler<SlVehicleShip, Vehicle> {
public:
inline static const SaveLoad description[] = {
SLEG_STRUCT("common", SlVehicleCommon),
SLE_VAR(Ship, state, SLE_UINT8),
SLE_CONDDEQUE(Ship, path, SLE_UINT8, SLV_SHIP_PATH_CACHE, SL_MAX_VERSION),
SLE_CONDVAR(Ship, rotation, SLE_UINT8, SLV_SHIP_ROTATION, SL_MAX_VERSION),
};
inline const static SaveLoadCompatTable compat_description = _vehicle_ship_sl_compat;
void Save(Vehicle *v) const override
{
if (v->type != VEH_SHIP) return;
SlObject(v, this->GetDescription());
}
void Load(Vehicle *v) const override
{
if (v->type != VEH_SHIP) return;
SlObject(v, this->GetLoadDescription());
}
void FixPointers(Vehicle *v) const override
{
if (v->type != VEH_SHIP) return;
SlObject(v, this->GetDescription());
}
};
class SlVehicleAircraft : public DefaultSaveLoadHandler<SlVehicleAircraft, Vehicle> {
public:
inline static const SaveLoad description[] = {
SLEG_STRUCT("common", SlVehicleCommon),
SLE_VAR(Aircraft, crashed_counter, SLE_UINT16),
SLE_VAR(Aircraft, pos, SLE_UINT8),
SLE_CONDVAR(Aircraft, targetairport, SLE_FILE_U8 | SLE_VAR_U16, SL_MIN_VERSION, SLV_5),
SLE_CONDVAR(Aircraft, targetairport, SLE_UINT16, SLV_5, SL_MAX_VERSION),
SLE_VAR(Aircraft, state, SLE_UINT8),
SLE_CONDVAR(Aircraft, previous_pos, SLE_UINT8, SLV_2, SL_MAX_VERSION),
SLE_CONDVAR(Aircraft, last_direction, SLE_UINT8, SLV_2, SL_MAX_VERSION),
SLE_CONDVAR(Aircraft, number_consecutive_turns, SLE_UINT8, SLV_2, SL_MAX_VERSION),
SLE_CONDVAR(Aircraft, turn_counter, SLE_UINT8, SLV_136, SL_MAX_VERSION),
SLE_CONDVAR(Aircraft, flags, SLE_UINT8, SLV_167, SL_MAX_VERSION),
};
inline const static SaveLoadCompatTable compat_description = _vehicle_aircraft_sl_compat;
void Save(Vehicle *v) const override
{
if (v->type != VEH_AIRCRAFT) return;
SlObject(v, this->GetDescription());
}
void Load(Vehicle *v) const override
{
if (v->type != VEH_AIRCRAFT) return;
SlObject(v, this->GetLoadDescription());
}
void FixPointers(Vehicle *v) const override
{
if (v->type != VEH_AIRCRAFT) return;
SlObject(v, this->GetDescription());
}
};
class SlVehicleEffect : public DefaultSaveLoadHandler<SlVehicleEffect, Vehicle> {
public:
inline static const SaveLoad description[] = {
SLE_VAR(Vehicle, subtype, SLE_UINT8),
SLE_CONDVAR(Vehicle, tile, SLE_FILE_U16 | SLE_VAR_U32, SL_MIN_VERSION, SLV_6),
SLE_CONDVAR(Vehicle, tile, SLE_UINT32, SLV_6, SL_MAX_VERSION),
SLE_CONDVAR(Vehicle, x_pos, SLE_FILE_I16 | SLE_VAR_I32, SL_MIN_VERSION, SLV_6),
SLE_CONDVAR(Vehicle, x_pos, SLE_INT32, SLV_6, SL_MAX_VERSION),
SLE_CONDVAR(Vehicle, y_pos, SLE_FILE_I16 | SLE_VAR_I32, SL_MIN_VERSION, SLV_6),
SLE_CONDVAR(Vehicle, y_pos, SLE_INT32, SLV_6, SL_MAX_VERSION),
SLE_CONDVAR(Vehicle, z_pos, SLE_FILE_U8 | SLE_VAR_I32, SL_MIN_VERSION, SLV_164),
SLE_CONDVAR(Vehicle, z_pos, SLE_INT32, SLV_164, SL_MAX_VERSION),
SLE_VAR2(Vehicle, "sprite_cache.sprite_seq.seq[0].sprite", sprite_seq.seq[0].sprite, SLE_FILE_U16 | SLE_VAR_U32),
SLE_VAR(Vehicle, progress, SLE_UINT8),
SLE_VAR(Vehicle, vehstatus, SLE_UINT8),
SLE_VAR(EffectVehicle, animation_state, SLE_UINT16),
SLE_VAR(EffectVehicle, animation_substate, SLE_UINT8),
SLE_CONDVAR(Vehicle, spritenum, SLE_UINT8, SLV_2, SL_MAX_VERSION),
};
inline const static SaveLoadCompatTable compat_description = _vehicle_effect_sl_compat;
void Save(Vehicle *v) const override
{
if (v->type != VEH_EFFECT) return;
SlObject(v, this->GetDescription());
}
void Load(Vehicle *v) const override
{
if (v->type != VEH_EFFECT) return;
SlObject(v, this->GetLoadDescription());
}
void FixPointers(Vehicle *v) const override
{
if (v->type != VEH_EFFECT) return;
SlObject(v, this->GetDescription());
}
};
class SlVehicleDisaster : public DefaultSaveLoadHandler<SlVehicleDisaster, Vehicle> {
public:
#if defined(_MSC_VER) && (_MSC_VER == 1915 || _MSC_VER == 1916)
/* This table access private members of other classes; they have this
* class as friend. For MSVC CL 19.15 and 19.16 this doesn't work for
* "inline static const", so we are forced to wrap the table in a
* function. CL 19.16 is the latest for VS2017. */
inline static const SaveLoad description[] = {{}};
SaveLoadTable GetDescription() const override {
#else
inline
#endif
static const SaveLoad description[] = {
SLE_REF(Vehicle, next, REF_VEHICLE_OLD),
SLE_VAR(Vehicle, subtype, SLE_UINT8),
SLE_CONDVAR(Vehicle, tile, SLE_FILE_U16 | SLE_VAR_U32, SL_MIN_VERSION, SLV_6),
SLE_CONDVAR(Vehicle, tile, SLE_UINT32, SLV_6, SL_MAX_VERSION),
SLE_CONDVAR(Vehicle, dest_tile, SLE_FILE_U16 | SLE_VAR_U32, SL_MIN_VERSION, SLV_6),
SLE_CONDVAR(Vehicle, dest_tile, SLE_UINT32, SLV_6, SL_MAX_VERSION),
SLE_CONDVAR(Vehicle, x_pos, SLE_FILE_I16 | SLE_VAR_I32, SL_MIN_VERSION, SLV_6),
SLE_CONDVAR(Vehicle, x_pos, SLE_INT32, SLV_6, SL_MAX_VERSION),
SLE_CONDVAR(Vehicle, y_pos, SLE_FILE_I16 | SLE_VAR_I32, SL_MIN_VERSION, SLV_6),
SLE_CONDVAR(Vehicle, y_pos, SLE_INT32, SLV_6, SL_MAX_VERSION),
SLE_CONDVAR(Vehicle, z_pos, SLE_FILE_U8 | SLE_VAR_I32, SL_MIN_VERSION, SLV_164),
SLE_CONDVAR(Vehicle, z_pos, SLE_INT32, SLV_164, SL_MAX_VERSION),
SLE_VAR(Vehicle, direction, SLE_UINT8),
SLE_VAR(Vehicle, owner, SLE_UINT8),
SLE_VAR(Vehicle, vehstatus, SLE_UINT8),
SLE_CONDVAR(Vehicle, current_order.dest, SLE_FILE_U8 | SLE_VAR_U16, SL_MIN_VERSION, SLV_5),
SLE_CONDVAR(Vehicle, current_order.dest, SLE_UINT16, SLV_5, SL_MAX_VERSION),
SLE_VAR2(Vehicle, "sprite_cache.sprite_seq.seq[0].sprite", sprite_seq.seq[0].sprite, SLE_FILE_U16 | SLE_VAR_U32),
SLE_CONDVAR(Vehicle, age, SLE_FILE_U16 | SLE_VAR_I32, SL_MIN_VERSION, SLV_31),
SLE_CONDVAR(Vehicle, age, SLE_INT32, SLV_31, SL_MAX_VERSION),
SLE_VAR(Vehicle, tick_counter, SLE_UINT8),
SLE_CONDVAR(DisasterVehicle, image_override, SLE_FILE_U16 | SLE_VAR_U32, SL_MIN_VERSION, SLV_191),
SLE_CONDVAR(DisasterVehicle, image_override, SLE_UINT32, SLV_191, SL_MAX_VERSION),
SLE_CONDVAR(DisasterVehicle, big_ufo_destroyer_target, SLE_FILE_U16 | SLE_VAR_U32, SL_MIN_VERSION, SLV_191),
SLE_CONDVAR(DisasterVehicle, big_ufo_destroyer_target, SLE_UINT32, SLV_191, SL_MAX_VERSION),
SLE_CONDVAR(DisasterVehicle, flags, SLE_UINT8, SLV_194, SL_MAX_VERSION),
};
#if defined(_MSC_VER) && (_MSC_VER == 1915 || _MSC_VER == 1916)
return description;
}
#endif
inline const static SaveLoadCompatTable compat_description = _vehicle_disaster_sl_compat;
void Save(Vehicle *v) const override
{
if (v->type != VEH_DISASTER) return;
SlObject(v, this->GetDescription());
}
void Load(Vehicle *v) const override
{
if (v->type != VEH_DISASTER) return;
SlObject(v, this->GetLoadDescription());
}
void FixPointers(Vehicle *v) const override
{
if (v->type != VEH_DISASTER) return;
SlObject(v, this->GetDescription());
}
};
const static SaveLoad _vehicle_desc[] = {
SLE_SAVEBYTE(Vehicle, type),
SLEG_STRUCT("train", SlVehicleTrain),
SLEG_STRUCT("roadveh", SlVehicleRoadVeh),
SLEG_STRUCT("ship", SlVehicleShip),
SLEG_STRUCT("aircraft", SlVehicleAircraft),
SLEG_STRUCT("effect", SlVehicleEffect),
SLEG_STRUCT("disaster", SlVehicleDisaster),
};
struct VEHSChunkHandler : ChunkHandler {
VEHSChunkHandler() : ChunkHandler('VEHS', CH_SPARSE_TABLE) {}
void Save() const override
{
SlTableHeader(_vehicle_desc);
/* Write the vehicles */
for (Vehicle *v : Vehicle::Iterate()) {
SlSetArrayIndex(v->index);
SlObject(v, _vehicle_desc);
}
}
void Load() const override
{
const std::vector<SaveLoad> slt = SlCompatTableHeader(_vehicle_desc, _vehicle_sl_compat);
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: // Savegame shouldn't contain invalid vehicles
default: SlErrorCorrupt("Invalid vehicle type");
}
SlObject(v, slt);
if (_cargo_count != 0 && IsCompanyBuildableVehicleType(v) && CargoPacket::CanAllocateItem()) {
/* Don't construct the packet with station here, because that'll fail with old savegames */
CargoPacket *cp = new CargoPacket(_cargo_count, _cargo_days, _cargo_source, _cargo_source_xy, _cargo_loaded_at_xy, _cargo_feeder_share);
v->cargo.Append(cp);
}
#if 0
/* Old savegames used 'last_station_visited = 0xFF' */
if (IsSavegameVersionBefore(SLV_5) && v->last_station_visited == 0xFF) {
v->last_station_visited = INVALID_STATION;
}
if (IsSavegameVersionBefore(SLV_182)) v->last_loading_station = INVALID_STATION;
if (IsSavegameVersionBefore(SLV_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 (IsSavegameVersionBefore(SLV_60)) v->group_id = DEFAULT_GROUP;
#endif
}
}
void FixPointers() const override
{
for (Vehicle *v : Vehicle::Iterate()) {
SlObject(v, _vehicle_desc);
}
}
};
static const VEHSChunkHandler VEHS;
static const ChunkHandlerRef veh_chunk_handlers[] = {
VEHS,
};
extern const ChunkHandlerTable _veh_chunk_handlers(veh_chunk_handlers);
}

@ -84,6 +84,8 @@
#define HAS_TRUETYPE_FONT
#endif
#include "saveload/saveload.h"
#include "table/strings.h"
#include "table/settings.h"
@ -3028,3 +3030,8 @@ void SetupTimeSettings()
{
_settings_time = (_game_mode == GM_MENU || _settings_client.gui.override_time_settings) ? _settings_client.gui : _settings_game.game_time;
}
const SettingTable &GetSettingsTableInternal()
{
return _settings;
}

@ -10,7 +10,7 @@
#ifndef SETTINGS_INTERNAL_H
#define SETTINGS_INTERNAL_H
#include "saveload/saveload.h"
#include "saveload/saveload_types.h"
enum SettingFlag : uint32 {
SF_NONE = 0,

@ -27,7 +27,7 @@
#include "sortlist_type.h"
#include "saveload/saveload.h"
#include "saveload/saveload_common.h"
#include "zoom_func.h"

@ -25,7 +25,7 @@
#include "newgrf_cache_check.h"
#include "landscape.h"
#include "network/network.h"
#include "saveload/saveload.h"
#include "saveload/saveload_common.h"
#include <list>
#include <map>
#include <unordered_map>
@ -240,6 +240,11 @@ extern void FixOldVehicles();
struct GRFFile;
namespace upstream_sl {
class SlVehicleCommon;
class SlVehicleDisaster;
}
/** %Vehicle data structure. */
struct Vehicle : VehiclePool::PoolItem<&_vehicle_pool>, BaseVehicle, BaseConsist {
private:
@ -258,6 +263,9 @@ public:
friend void AfterLoadVehicles(bool part_of_load); ///< So we can set the #previous and #first pointers while loading
friend bool LoadOldVehicle(LoadgameState *ls, int num); ///< So we can set the proper next pointer while loading
friend upstream_sl::SlVehicleCommon;
friend upstream_sl::SlVehicleDisaster;
static void PreCleanPool();
TileIndex tile; ///< Current tile index

Loading…
Cancel
Save