- diff --git a/src/cargo_type.h b/src/cargo_type.h
- index 402e81c1b..c84f1f490 100644
- --- a/src/cargo_type.h
- +++ b/src/cargo_type.h
- @@ -63,14 +63,14 @@ enum CargoType {
- CT_PLASTIC = 10,
- CT_FIZZY_DRINKS = 11,
- - NUM_CARGO = 32, ///< Maximal number of cargo types in a game.
- + NUM_CARGO = 64, ///< Maximal number of cargo types in a game.
- CT_AUTO_REFIT = 0xFD, ///< Automatically choose cargo type when doing auto refitting.
- CT_NO_REFIT = 0xFE, ///< Do not refit cargo of a vehicle (used in vehicle orders and auto-replace/auto-new).
- CT_INVALID = 0xFF, ///< Invalid cargo type.
- };
- -typedef uint32 CargoTypes;
- +typedef uint64 CargoTypes;
- static const CargoTypes ALL_CARGOTYPES = (CargoTypes)UINT32_MAX;
- diff --git a/src/core/bitmath_func.hpp b/src/core/bitmath_func.hpp
- index 31e679b00..72026fa6a 100644
- --- a/src/core/bitmath_func.hpp
- +++ b/src/core/bitmath_func.hpp
- @@ -12,6 +12,8 @@
- #ifndef BITMATH_FUNC_HPP
- #define BITMATH_FUNC_HPP
- +#include <bitset>
- +
- /**
- * Fetch \a n bits from \a x, started at bit \a s.
- *
- @@ -108,6 +110,22 @@ static inline bool HasBit(const T x, const uint8 y)
- }
- /**
- + * Checks if a bit in a std::bitset is set.
- + *
- + * This function is a wrapper for std::bitset.test().
- + *
- + * @param x The value to check
- + * @param y The position of the bit to check, started from the LSB
- + * @pre y < N
- + * @return True if the bit is set, false else.
- + */
- +template <size_t N>
- +static inline bool HasBit(const std::bitset<N> x, const uint8 y)
- +{
- + return x.test(y);
- +}
- +
- +/**
- * Set a bit in a variable.
- *
- * This function sets a bit in a variable. The variable is changed
- @@ -126,6 +144,22 @@ static inline T SetBit(T &x, const uint8 y)
- }
- /**
- + * Set a bit in a std::bitset.
- + *
- + * This function is a wrapper for std::bitset.set().
- + *
- + * @param x The variable to set a bit
- + * @param y The bit position to set
- + * @pre y < N
- + * @return The new value of the old value with the bit set
- + */
- +template <size_t N>
- +static inline std::bitset<N> SetBit(const std::bitset<N> &x, const uint8 y)
- +{
- + return x.set(y);
- +}
- +
- +/**
- * Sets several bits in a variable.
- *
- * This macro sets several bits in a variable. The bits to set are provided
- @@ -156,6 +190,22 @@ static inline T ClrBit(T &x, const uint8 y)
- }
- /**
- + * Clears a bit in a std::bitset.
- + *
- + * This function is a wrapper for std::bitset.clear().
- + *
- + * @param x The variable to clear the bit
- + * @param y The bit position to clear
- + * @pre y < N
- + * @return The new value of the old value with the bit cleared
- + */
- +template <size_t N>
- +static inline std::bitset<N> ClrBit(const std::bitset<N> &x, const uint8 y)
- +{
- + return x.reset(y);
- +}
- +
- +/**
- * Clears several bits in a variable.
- *
- * This macro clears several bits in a variable. The bits to clear are
- @@ -185,6 +235,21 @@ static inline T ToggleBit(T &x, const uint8 y)
- return x = (T)(x ^ ((T)1U << y));
- }
- +/**
- + * Toggles a bit in a std::bitset.
- + *
- + * This function is a wrapper for std::bitset.flip().
- + *
- + * @param x The variable to toggle the bit
- + * @param y The bit position to toggle
- + * @pre y < N
- + * @return The new value of the old value with the bit toggled
- + */
- +template <size_t N>
- +static inline std::bitset<N> ToggleBit(const std::bitset<N> &x, const uint8 y)
- +{
- + return x.flip(y);
- +}
- /** Lookup table to check which bit is set in a 6 bit variable */
- extern const uint8 _ffb_64[64];
- @@ -267,6 +332,20 @@ static inline uint CountBits(T value)
- }
- /**
- + * Counts the number of set bits in a std::bitset.
- + *
- + * This function is a wrapper for std::bitset.count().
- + *
- + * @param value the value to count the number of bits in.
- + * @return the number of bits.
- + */
- +template <size_t N>
- +static inline uint CountBits(const std::bitset<N> value)
- +{
- + return (uint)value.count();
- +}
- +
- +/**
- * Test whether \a value has exactly 1 bit set
- *
- * @param value the value to test.
- @@ -279,6 +358,18 @@ static inline bool HasExactlyOneBit(T value)
- }
- /**
- + * Test whether \a std::bitset has exactly 1 bit set.
- + *
- + * @param value the value to test.
- + * @return does \a value have exactly 1 bit set?
- + */
- +template <size_t N>
- +static inline bool HasExactlyOneBit(const std::bitset<N> value)
- +{
- + return value.count() == 1;
- +}
- +
- +/**
- * Test whether \a value has at most 1 bit set
- *
- * @param value the value to test.
- diff --git a/src/graph_gui.cpp b/src/graph_gui.cpp
- index c12c6ace4..b119fbffd 100644
- --- a/src/graph_gui.cpp
- +++ b/src/graph_gui.cpp
- @@ -33,8 +33,8 @@
- #include "safeguards.h"
- /* Bitmasks of company and cargo indices that shouldn't be drawn. */
- -static uint _legend_excluded_companies;
- -static uint _legend_excluded_cargo;
- +static CompanyMask _legend_excluded_companies;
- +static CargoTypes _legend_excluded_cargo;
- /* Apparently these don't play well with enums. */
- static const OverflowSafeInt64 INVALID_DATAPOINT(INT64_MAX); // Value used for a datapoint that shouldn't be drawn.
- @@ -166,14 +166,14 @@ struct ValuesInterval {
- struct BaseGraphWindow : Window {
- protected:
- - static const int GRAPH_MAX_DATASETS = 32;
- + static const int GRAPH_MAX_DATASETS = 64;
- static const int GRAPH_AXIS_LINE_COLOUR = PC_BLACK;
- static const int GRAPH_NUM_MONTHS = 24; ///< Number of months displayed in the graph.
- static const int MIN_GRAPH_NUM_LINES_Y = 9; ///< Minimal number of horizontal lines to draw.
- static const int MIN_GRID_PIXEL_SIZE = 20; ///< Minimum distance between graph lines.
- - uint excluded_data; ///< bitmask of the datasets that shouldn't be displayed.
- + std::bitset<GRAPH_MAX_DATASETS> excluded_data; ///< bitmask of the datasets that shouldn't be displayed.
- byte num_dataset;
- byte num_on_x_axis;
- byte num_vert_lines;
- @@ -561,7 +561,7 @@ public:
- */
- void UpdateStatistics(bool initialize)
- {
- - uint excluded_companies = _legend_excluded_companies;
- + CompanyMask excluded_companies = _legend_excluded_companies;
- /* Exclude the companies which aren't valid */
- for (CompanyID c = COMPANY_FIRST; c < MAX_COMPANIES; c++) {
- @@ -902,7 +902,7 @@ struct PaymentRatesGraphWindow : BaseGraphWindow {
- void UpdateExcludedData()
- {
- - this->excluded_data = 0;
- + this->excluded_data.reset();
- int i = 0;
- const CargoSpec *cs;
- @@ -967,7 +967,7 @@ struct PaymentRatesGraphWindow : BaseGraphWindow {
- case WID_CPR_ENABLE_CARGOES:
- /* Remove all cargoes from the excluded lists. */
- _legend_excluded_cargo = 0;
- - this->excluded_data = 0;
- + this->excluded_data.reset();
- this->UpdateLoweredWidgets();
- this->SetDirty();
- break;
- diff --git a/src/saveload/company_sl.cpp b/src/saveload/company_sl.cpp
- index 9a9056061..07d685e92 100644
- --- a/src/saveload/company_sl.cpp
- +++ b/src/saveload/company_sl.cpp
- @@ -350,7 +350,8 @@ static const SaveLoad _company_economy_desc[] = {
- SLE_CONDVAR(CompanyEconomyEntry, company_value, SLE_INT64, 2, SL_MAX_VERSION),
- SLE_CONDVAR(CompanyEconomyEntry, delivered_cargo[NUM_CARGO - 1], SLE_INT32, 0, 169),
- - SLE_CONDARR(CompanyEconomyEntry, delivered_cargo, SLE_UINT32, NUM_CARGO, 170, SL_MAX_VERSION),
- + SLE_CONDARR(CompanyEconomyEntry, delivered_cargo, SLE_UINT32, 32, 170, 198),
- + SLE_CONDARR(CompanyEconomyEntry, delivered_cargo, SLE_UINT32, NUM_CARGO, 199, SL_MAX_VERSION),
- SLE_VAR(CompanyEconomyEntry, performance_history, SLE_INT32),
- SLE_END()
- diff --git a/src/saveload/economy_sl.cpp b/src/saveload/economy_sl.cpp
- index dabf120fc..0effb5b2f 100644
- --- a/src/saveload/economy_sl.cpp
- +++ b/src/saveload/economy_sl.cpp
- @@ -29,7 +29,7 @@ static void Load_PRIC()
- /** Cargo payment rates in pre 126 savegames */
- static void Load_CAPR()
- {
- - uint num_cargo = IsSavegameVersionBefore(55) ? 12 : NUM_CARGO;
- + uint num_cargo = IsSavegameVersionBefore(55) ? 12 : IsSavegameVersionBefore(199) ? 32 : NUM_CARGO;
- int vt = IsSavegameVersionBefore(65) ? SLE_FILE_I32 : SLE_FILE_I64;
- SlArray(NULL, num_cargo, vt | SLE_VAR_NULL);
- SlArray(NULL, num_cargo, SLE_FILE_U16 | SLE_VAR_NULL);
- diff --git a/src/saveload/saveload.cpp b/src/saveload/saveload.cpp
- index d06214e23..692f73cf2 100644
- --- a/src/saveload/saveload.cpp
- +++ b/src/saveload/saveload.cpp
- @@ -266,8 +266,9 @@
- * 196 27778 1.7.x
- * 197 27978 1.8.x
- * 198
- + * 199
- */
- -extern const uint16 SAVEGAME_VERSION = 198; ///< Current savegame version of OpenTTD.
- +extern const uint16 SAVEGAME_VERSION = 199; ///< Current savegame version of OpenTTD.
- SavegameType _savegame_type; ///< type of savegame we are loading
- FileToSaveLoad _file_to_saveload; ///< File to save or load in the openttd loop.
- diff --git a/src/saveload/station_sl.cpp b/src/saveload/station_sl.cpp
- index 391ba30a8..f01123da0 100644
- --- a/src/saveload/station_sl.cpp
- +++ b/src/saveload/station_sl.cpp
- @@ -329,6 +329,7 @@ static void Load_STNS()
- _cargo_days = 0;
- _cargo_feeder_share = 0;
- + uint num_cargo = IsSavegameVersionBefore(55) ? 12 : IsSavegameVersionBefore(199) ? 32 : NUM_CARGO;
- int index;
- while ((index = SlIterateArray()) != -1) {
- Station *st = new (index) Station();
- @@ -337,7 +338,6 @@ static void Load_STNS()
- _waiting_acceptance = 0;
- - uint num_cargo = IsSavegameVersionBefore(55) ? 12 : NUM_CARGO;
- for (CargoID i = 0; i < num_cargo; i++) {
- GoodsEntry *ge = &st->goods[i];
- SlObject(ge, GetGoodsDesc());
- @@ -377,10 +377,11 @@ static void Ptrs_STNS()
- /* Don't run when savegame version is higher than or equal to 123. */
- if (!IsSavegameVersionBefore(123)) return;
- + uint num_cargo = IsSavegameVersionBefore(199) ? 32 : NUM_CARGO;
- Station *st;
- FOR_ALL_STATIONS(st) {
- if (!IsSavegameVersionBefore(68)) {
- - for (CargoID i = 0; i < NUM_CARGO; i++) {
- + for (CargoID i = 0; i < num_cargo; i++) {
- GoodsEntry *ge = &st->goods[i];
- SwapPackets(ge);
- SlObject(ge, GetGoodsDesc());
- @@ -440,7 +441,8 @@ static const SaveLoad _station_desc[] = {
- SLE_VAR(Station, last_vehicle_type, SLE_UINT8),
- SLE_VAR(Station, had_vehicle_of_type, SLE_UINT8),
- SLE_LST(Station, loading_vehicles, REF_VEHICLE),
- - SLE_CONDVAR(Station, always_accepted, SLE_UINT32, 127, SL_MAX_VERSION),
- + SLE_CONDVAR(Station, always_accepted, SLE_FILE_U32 | SLE_VAR_U64, 127, 198),
- + SLE_CONDVAR(Station, always_accepted, SLE_UINT64, 199, SL_MAX_VERSION),
- SLE_END()
- };
- @@ -520,6 +522,7 @@ static void Load_STNN()
- {
- _num_flows = 0;
- + uint num_cargo = IsSavegameVersionBefore(199) ? 32 : NUM_CARGO;
- int index;
- while ((index = SlIterateArray()) != -1) {
- bool waypoint = (SlReadByte() & FACIL_WAYPOINT) != 0;
- @@ -538,7 +541,7 @@ static void Load_STNN()
- memcpy(st->airport.psa->storage, _old_st_persistent_storage.storage, sizeof(st->airport.psa->storage));
- }
- - for (CargoID i = 0; i < NUM_CARGO; i++) {
- + for (CargoID i = 0; i < num_cargo; i++) {
- SlObject(&st->goods[i], GetGoodsDesc());
- FlowSaveLoad flow;
- FlowStat *fs = NULL;
- @@ -580,9 +583,10 @@ static void Ptrs_STNN()
- /* Don't run when savegame version lower than 123. */
- if (IsSavegameVersionBefore(123)) return;
- + uint num_cargo = IsSavegameVersionBefore(199) ? 32 : NUM_CARGO;
- Station *st;
- FOR_ALL_STATIONS(st) {
- - for (CargoID i = 0; i < NUM_CARGO; i++) {
- + for (CargoID i = 0; i < num_cargo; i++) {
- GoodsEntry *ge = &st->goods[i];
- if (IsSavegameVersionBefore(183)) {
- SwapPackets(ge);
- diff --git a/src/saveload/town_sl.cpp b/src/saveload/town_sl.cpp
- index 41ac70165..13438d85b 100644
- --- a/src/saveload/town_sl.cpp
- +++ b/src/saveload/town_sl.cpp
- @@ -192,7 +192,8 @@ static const SaveLoad _town_desc[] = {
- SLE_CONDLST(Town, psa_list, REF_STORAGE, 161, SL_MAX_VERSION),
- - SLE_CONDVAR(Town, cargo_produced, SLE_UINT32, 166, SL_MAX_VERSION),
- + SLE_CONDVAR(Town, cargo_produced, SLE_FILE_U32 | SLE_VAR_U64, 166, 198),
- + SLE_CONDVAR(Town, cargo_produced, SLE_UINT64, 199, SL_MAX_VERSION),
- /* reserve extra space in savegame here. (currently 30 bytes) */
- SLE_CONDNULL(30, 2, SL_MAX_VERSION),
- @@ -274,12 +275,13 @@ static void Save_TOWN()
- static void Load_TOWN()
- {
- int index;
- + uint num_cargo = IsSavegameVersionBefore(199) ? 32 : NUM_CARGO;
- while ((index = SlIterateArray()) != -1) {
- Town *t = new (index) Town();
- SlObject(t, _town_desc);
- - for (CargoID i = 0; i < NUM_CARGO; i++) {
- + for (CargoID i = 0; i < num_cargo; i++) {
- SlObject(&t->supplied[i], _town_supplied_desc);
- }
- for (int i = TE_BEGIN; i < TE_END; i++) {
- diff --git a/src/strings.cpp b/src/strings.cpp
- index fd45e6a0b..63d8e69d4 100644
- --- a/src/strings.cpp
- +++ b/src/strings.cpp
- @@ -1147,7 +1147,7 @@ static char *FormatString(char *buff, const char *str_arg, StringParameters *arg
- }
- case SCC_CARGO_LIST: { // {CARGO_LIST}
- - CargoTypes cmask = args->GetInt32(SCC_CARGO_LIST);
- + CargoTypes cmask = args->GetInt64(SCC_CARGO_LIST);
- bool first = true;
- const CargoSpec *cs;
- diff --git a/src/window.cpp b/src/window.cpp
- index e2ce84542..f17fccf93 100644
- --- a/src/window.cpp
- +++ b/src/window.cpp
- @@ -2457,20 +2457,20 @@ static EventState HandleViewportScroll()
- }
- Point delta;
- + if (_settings_client.gui.scroll_mode != VSM_VIEWPORT_RMB_FIXED) {
- + delta.x = -_cursor.delta.x;
- + delta.y = -_cursor.delta.y;
- + } else {
- + delta.x = _cursor.delta.x;
- + delta.y = _cursor.delta.y;
- + }
- +
- if (scrollwheel_scrolling) {
- /* We are using scrollwheels for scrolling */
- delta.x = _cursor.h_wheel;
- delta.y = _cursor.v_wheel;
- _cursor.v_wheel = 0;
- _cursor.h_wheel = 0;
- - } else {
- - if (_settings_client.gui.scroll_mode != VSM_VIEWPORT_RMB_FIXED) {
- - delta.x = -_cursor.delta.x;
- - delta.y = -_cursor.delta.y;
- - } else {
- - delta.x = _cursor.delta.x;
- - delta.y = _cursor.delta.y;
- - }
- }
- /* Create a scroll-event and send it to the window */
- @@ -2866,12 +2866,7 @@ static void MouseLoop(MouseClick click, int mousewheel)
- }
- if (vp != NULL) {
- - if (scrollwheel_scrolling && !(w->flags & WF_DISABLE_VP_SCROLL)) {
- - _scrolling_viewport = true;
- - _cursor.fix_at = true;
- - return;
- - }
- -
- + if (scrollwheel_scrolling) click = MC_RIGHT; // we are using the scrollwheel in a viewport, so we emulate right mouse button
- switch (click) {
- case MC_DOUBLE_LEFT:
- case MC_LEFT:
- @@ -2890,6 +2885,10 @@ static void MouseLoop(MouseClick click, int mousewheel)
- _scrolling_viewport = true;
- _cursor.fix_at = (_settings_client.gui.scroll_mode == VSM_VIEWPORT_RMB_FIXED ||
- _settings_client.gui.scroll_mode == VSM_MAP_RMB_FIXED);
- +
- + /* clear 2D scrolling caches before we start a 2D scroll */
- + _cursor.h_wheel = 0;
- + _cursor.v_wheel = 0;
- return;
- }
- break;
- @@ -2904,7 +2903,7 @@ static void MouseLoop(MouseClick click, int mousewheel)
- case MC_LEFT:
- case MC_DOUBLE_LEFT:
- DispatchLeftClickEvent(w, x - w->left, y - w->top, click == MC_DOUBLE_LEFT ? 2 : 1);
- - return;
- + break;
- default:
- if (!scrollwheel_scrolling || w == NULL || w->window_class != WC_SMALLMAP) break;
- @@ -2912,19 +2911,11 @@ static void MouseLoop(MouseClick click, int mousewheel)
- * Simulate a right button click so we can get started. */
- FALLTHROUGH;
- - case MC_RIGHT:
- - DispatchRightClickEvent(w, x - w->left, y - w->top);
- - return;
- + case MC_RIGHT: DispatchRightClickEvent(w, x - w->left, y - w->top); break;
- - case MC_HOVER:
- - DispatchHoverEvent(w, x - w->left, y - w->top);
- - break;
- + case MC_HOVER: DispatchHoverEvent(w, x - w->left, y - w->top); break;
- }
- }
- -
- - /* We're not doing anything with 2D scrolling, so reset the value. */
- - _cursor.h_wheel = 0;
- - _cursor.v_wheel = 0;
- }
- /**