OpenTTD Source  20241121-master-g67a0fccfad
cargomonitor_sl.cpp
Go to the documentation of this file.
1 /*
2  * This file is part of OpenTTD.
3  * 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.
4  * 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.
5  * 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/>.
6  */
7 
10 #include "../stdafx.h"
11 
12 #include "saveload.h"
14 
15 #include "../cargomonitor.h"
16 
17 #include "../safeguards.h"
18 
20 struct TempStorage {
21  CargoMonitorID number;
22  uint32_t amount;
23 };
24 
27  SLE_VAR(TempStorage, number, SLE_UINT32),
28  SLE_VAR(TempStorage, amount, SLE_UINT32),
29 };
30 
31 static CargoMonitorID FixupCargoMonitor(CargoMonitorID number)
32 {
33  /* Between SLV_EXTEND_CARGOTYPES and SLV_FIX_CARGO_MONITOR, the
34  * CargoMonitorID structure had insufficient packing for more
35  * than 32 cargo types. Here we have to shuffle bits to account
36  * for the change.
37  * Company moved from bits 24-31 to 25-28.
38  * Cargo type increased from bits 19-23 to 19-24.
39  */
40  SB(number, 25, 4, GB(number, 24, 4));
41  SB(number, 29, 3, 0);
42  ClrBit(number, 24);
43  return number;
44 }
45 
48  CMDLChunkHandler() : ChunkHandler('CMDL', CH_TABLE) {}
49 
50  void Save() const override
51  {
53 
54  TempStorage storage;
55 
56  int i = 0;
57  CargoMonitorMap::const_iterator iter = _cargo_deliveries.begin();
58  while (iter != _cargo_deliveries.end()) {
59  storage.number = iter->first;
60  storage.amount = iter->second;
61 
62  SlSetArrayIndex(i);
64 
65  i++;
66  iter++;
67  }
68  }
69 
70  void Load() const override
71  {
73 
74  TempStorage storage;
76 
78  for (;;) {
79  if (SlIterateArray() < 0) break;
80  SlObject(&storage, slt);
81 
82  if (fix) storage.number = FixupCargoMonitor(storage.number);
83 
84  _cargo_deliveries.emplace(storage.number, storage.amount);
85  }
86  }
87 };
88 
91  CMPUChunkHandler() : ChunkHandler('CMPU', CH_TABLE) {}
92 
93  void Save() const override
94  {
96 
97  TempStorage storage;
98 
99  int i = 0;
100  CargoMonitorMap::const_iterator iter = _cargo_pickups.begin();
101  while (iter != _cargo_pickups.end()) {
102  storage.number = iter->first;
103  storage.amount = iter->second;
104 
105  SlSetArrayIndex(i);
107 
108  i++;
109  iter++;
110  }
111  }
112 
113  void Load() const override
114  {
116 
117  TempStorage storage;
119 
121  for (;;) {
122  if (SlIterateArray() < 0) break;
123  SlObject(&storage, slt);
124 
125  if (fix) storage.number = FixupCargoMonitor(storage.number);
126 
127  _cargo_pickups.emplace(storage.number, storage.amount);
128  }
129  }
130 };
131 
133 static const CMDLChunkHandler CMDL;
134 static const CMPUChunkHandler CMPU;
135 static const ChunkHandlerRef cargomonitor_chunk_handlers[] = {
136  CMDL,
137  CMPU,
138 };
139 
140 extern const ChunkHandlerTable _cargomonitor_chunk_handlers(cargomonitor_chunk_handlers);
constexpr T SB(T &x, const uint8_t s, const uint8_t n, const U d)
Set n bits in x starting at bit s to d.
constexpr static debug_inline uint GB(const T x, const uint8_t s, const uint8_t n)
Fetch n bits from x, started at bit s.
constexpr T ClrBit(T &x, const uint8_t y)
Clears a bit in a variable.
void ClearCargoDeliveryMonitoring(CompanyID company)
Clear all delivery cargo monitors.
CargoMonitorMap _cargo_deliveries
Map of monitored deliveries to the amount since last query/activation.
CargoMonitorMap _cargo_pickups
Map of monitored pick-ups to the amount since last query/activation.
void ClearCargoPickupMonitoring(CompanyID company)
Clear all pick-up cargo monitors.
uint32_t CargoMonitorID
Unique number for a company / cargo type / (town or industry).
Definition: cargomonitor.h:19
static const SaveLoad _cargomonitor_pair_desc[]
Description of the TempStorage structure for the purpose of load and save.
static const CMDLChunkHandler CMDL
Chunk definition of the cargomonitoring maps.
Loading for cargomonitor chunks before table headers were added.
const SaveLoadCompat _cargomonitor_pair_sl_compat[]
Original field order for _cargomonitor_pair_desc.
int SlIterateArray()
Iterate through the elements of an array and read the whole thing.
Definition: saveload.cpp:658
std::vector< SaveLoad > SlCompatTableHeader(const SaveLoadTable &slt, const SaveLoadCompatTable &slct)
Load a table header in a savegame compatible way.
Definition: saveload.cpp:1893
std::vector< SaveLoad > SlTableHeader(const SaveLoadTable &slt)
Save or Load a table header.
Definition: saveload.cpp:1755
void SlObject(void *object, const SaveLoadTable &slt)
Main SaveLoad function.
Definition: saveload.cpp:1702
Functions/types related to saving and loading games.
std::reference_wrapper< const ChunkHandler > ChunkHandlerRef
A reference to ChunkHandler.
Definition: saveload.h:507
std::span< const ChunkHandlerRef > ChunkHandlerTable
A table of ChunkHandler entries.
Definition: saveload.h:510
bool IsSavegameVersionBefore(SaveLoadVersion major, uint8_t minor=0)
Checks whether the savegame is below major.
Definition: saveload.h:1239
@ SLV_FIX_CARGO_MONITOR
207 PR#7175 v1.9 Cargo monitor data packing fix to support 64 cargotypes.
Definition: saveload.h:292
#define SLE_VAR(base, variable, type)
Storage of a variable in every version of a savegame.
Definition: saveload.h:987
_cargo_deliveries monitoring map.
void Save() const override
Save the chunk.
void Load() const override
Load the chunk.
_cargo_pickups monitoring map.
void Load() const override
Load the chunk.
void Save() const override
Save the chunk.
Handlers and description of chunk.
Definition: saveload.h:461
SaveLoad type struct.
Definition: saveload.h:713
Temporary storage of cargo monitoring data for loading or saving it.