summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPeter Nelson <peter1138@openttd.org>2019-02-03 23:50:50 +0000
committerCharles Pigott <charlespigott@googlemail.com>2019-02-04 20:43:14 +0000
commit64878320ccac0854b0712730e5f9dedcf0bb591d (patch)
treeab44ae11fa03b8a0e5a31175997bc3825bd24c7d /src
parent0b10678050c82604214136343673a5290f986cdb (diff)
downloadopenttd-64878320ccac0854b0712730e5f9dedcf0bb591d.tar.xz
Fix #6803: CargoMonitorID bit packing updated to handle 64 cargo types.
This requires a saveload bump to change the bitpacking on loading older saves.
Diffstat (limited to 'src')
-rw-r--r--src/cargomonitor.h11
-rw-r--r--src/saveload/cargomonitor_sl.cpp21
-rw-r--r--src/saveload/saveload.h1
3 files changed, 30 insertions, 3 deletions
diff --git a/src/cargomonitor.h b/src/cargomonitor.h
index 061a1821a..e74f717e0 100644
--- a/src/cargomonitor.h
+++ b/src/cargomonitor.h
@@ -45,11 +45,14 @@ enum CargoCompanyBits {
CCB_IS_INDUSTRY_BIT = 16, ///< Bit indicating the town/industry number is an industry.
CCB_IS_INDUSTRY_BIT_VALUE = 1ul << CCB_IS_INDUSTRY_BIT, ///< Value of the #CCB_IS_INDUSTRY_BIT bit.
CCB_CARGO_TYPE_START = 19, ///< Start bit of the cargo type field.
- CCB_CARGO_TYPE_LENGTH = 5, ///< Number of bits of the cargo type field.
- CCB_COMPANY_START = 24, ///< Start bit of the company field.
- CCB_COMPANY_LENGTH = 8, ///< Number of bits of the company field.
+ CCB_CARGO_TYPE_LENGTH = 6, ///< Number of bits of the cargo type field.
+ CCB_COMPANY_START = 25, ///< Start bit of the company field.
+ CCB_COMPANY_LENGTH = 4, ///< Number of bits of the company field.
};
+assert_compile(NUM_CARGO <= (1 << CCB_CARGO_TYPE_LENGTH));
+assert_compile(MAX_COMPANIES <= (1 << CCB_COMPANY_LENGTH));
+
/**
* Encode a cargo monitor for pickup or delivery at an industry.
@@ -61,6 +64,7 @@ enum CargoCompanyBits {
static inline CargoMonitorID EncodeCargoIndustryMonitor(CompanyID company, CargoID ctype, IndustryID ind)
{
assert(ctype < (1 << CCB_CARGO_TYPE_LENGTH));
+ assert(company < (1 << CCB_COMPANY_LENGTH));
uint32 ret = 0;
SB(ret, CCB_TOWN_IND_NUMBER_START, CCB_TOWN_IND_NUMBER_LENGTH, ind);
@@ -80,6 +84,7 @@ static inline CargoMonitorID EncodeCargoIndustryMonitor(CompanyID company, Cargo
static inline CargoMonitorID EncodeCargoTownMonitor(CompanyID company, CargoID ctype, TownID town)
{
assert(ctype < (1 << CCB_CARGO_TYPE_LENGTH));
+ assert(company < (1 << CCB_COMPANY_LENGTH));
uint32 ret = 0;
SB(ret, CCB_TOWN_IND_NUMBER_START, CCB_TOWN_IND_NUMBER_LENGTH, town);
diff --git a/src/saveload/cargomonitor_sl.cpp b/src/saveload/cargomonitor_sl.cpp
index 98ad95f09..9a313970f 100644
--- a/src/saveload/cargomonitor_sl.cpp
+++ b/src/saveload/cargomonitor_sl.cpp
@@ -29,6 +29,21 @@ static const SaveLoad _cargomonitor_pair_desc[] = {
SLE_END()
};
+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;
+}
+
/** Save the #_cargo_deliveries monitoring map. */
static void SaveDelivery()
{
@@ -52,12 +67,15 @@ static void SaveDelivery()
static void LoadDelivery()
{
TempStorage storage;
+ bool fix = IsSavegameVersionBefore(SLV_FIX_CARGO_MONITOR);
ClearCargoDeliveryMonitoring();
for (;;) {
if (SlIterateArray() < 0) break;
SlObject(&storage, _cargomonitor_pair_desc);
+ if (fix) storage.number = FixupCargoMonitor(storage.number);
+
std::pair<CargoMonitorID, uint32> p(storage.number, storage.amount);
_cargo_deliveries.insert(p);
}
@@ -87,12 +105,15 @@ static void SavePickup()
static void LoadPickup()
{
TempStorage storage;
+ bool fix = IsSavegameVersionBefore(SLV_FIX_CARGO_MONITOR);
ClearCargoPickupMonitoring();
for (;;) {
if (SlIterateArray() < 0) break;
SlObject(&storage, _cargomonitor_pair_desc);
+ if (fix) storage.number = FixupCargoMonitor(storage.number);
+
std::pair<CargoMonitorID, uint32> p(storage.number, storage.amount);
_cargo_pickups.insert(p);
}
diff --git a/src/saveload/saveload.h b/src/saveload/saveload.h
index 5c84abc21..e5e2e1fa2 100644
--- a/src/saveload/saveload.h
+++ b/src/saveload/saveload.h
@@ -290,6 +290,7 @@ enum SaveLoadVersion : uint16 {
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 Cargo monitor data packing fix to support 64 cargotypes.
SL_MAX_VERSION, ///< Highest possible saveload version
};