diff --git a/src/autoreplace_cmd.cpp b/src/autoreplace_cmd.cpp index 85fc7c0c1b..668360f6e7 100644 --- a/src/autoreplace_cmd.cpp +++ b/src/autoreplace_cmd.cpp @@ -71,7 +71,7 @@ bool CheckAutoreplaceValidity(EngineID from, EngineID to, CompanyID company) switch (type) { case VEH_TRAIN: { /* make sure the railtypes are compatible */ - if ((GetRailTypeInfo(e_from->u.rail.railtype)->compatible_railtypes & GetRailTypeInfo(e_to->u.rail.railtype)->compatible_railtypes) == 0) return false; + if (!GetRailTypeInfo(e_from->u.rail.railtype)->compatible_railtypes.Any(GetRailTypeInfo(e_to->u.rail.railtype)->compatible_railtypes)) return false; /* make sure we do not replace wagons with engines or vice versa */ if ((e_from->u.rail.railveh_type == RAILVEH_WAGON) != (e_to->u.rail.railveh_type == RAILVEH_WAGON)) return false; diff --git a/src/company_gui.cpp b/src/company_gui.cpp index 3e2cfce077..479dfcd0e4 100644 --- a/src/company_gui.cpp +++ b/src/company_gui.cpp @@ -1780,19 +1780,19 @@ struct CompanyInfrastructureWindow : Window void UpdateRailRoadTypes() { - this->railtypes = RAILTYPES_NONE; + this->railtypes = {}; this->roadtypes = {}; /* Find the used railtypes. */ for (const Engine *e : Engine::IterateType(VEH_TRAIN)) { if (!e->info.climates.Test(_settings_game.game_creation.landscape)) continue; - this->railtypes |= GetRailTypeInfo(e->u.rail.railtype)->introduces_railtypes; + this->railtypes.Set(GetRailTypeInfo(e->u.rail.railtype)->introduces_railtypes); } /* Get the date introduced railtypes as well. */ this->railtypes = AddDateIntroducedRailTypes(this->railtypes, CalendarTime::MAX_DATE); - this->railtypes &= ~_railtypes_hidden_mask; + this->railtypes.Reset(_railtypes_hidden_mask); /* Find the used roadtypes. */ for (const Engine *e : Engine::IterateType(VEH_ROAD)) { @@ -1814,7 +1814,7 @@ struct CompanyInfrastructureWindow : Window uint32_t rail_total = c->infrastructure.GetRailTotal(); for (RailType rt = RAILTYPE_BEGIN; rt != RAILTYPE_END; rt++) { - if (HasBit(this->railtypes, rt)) total += RailMaintenanceCost(rt, c->infrastructure.rail[rt], rail_total); + if (this->railtypes.Test(rt)) total += RailMaintenanceCost(rt, c->infrastructure.rail[rt], rail_total); } total += SignalMaintenanceCost(c->infrastructure.signal); @@ -1853,12 +1853,12 @@ struct CompanyInfrastructureWindow : Window size.width = std::max(size.width, GetStringBoundingBox(STR_COMPANY_INFRASTRUCTURE_VIEW_RAIL_SECT).width + padding.width); for (const auto &rt : _sorted_railtypes) { - if (HasBit(this->railtypes, rt)) { + if (this->railtypes.Test(rt)) { lines++; size.width = std::max(size.width, GetStringBoundingBox(GetRailTypeInfo(rt)->strings.name).width + padding.width + WidgetDimensions::scaled.hsep_indent); } } - if (this->railtypes != RAILTYPES_NONE) { + if (this->railtypes.Any()) { lines++; size.width = std::max(size.width, GetStringBoundingBox(STR_COMPANY_INFRASTRUCTURE_VIEW_SIGNALS).width + padding.width + WidgetDimensions::scaled.hsep_indent); } @@ -1978,10 +1978,10 @@ struct CompanyInfrastructureWindow : Window case WID_CI_RAIL_DESC: DrawString(r.left, r.right, y, STR_COMPANY_INFRASTRUCTURE_VIEW_RAIL_SECT); - if (this->railtypes != RAILTYPES_NONE) { + if (this->railtypes.Any()) { /* Draw name of each valid railtype. */ for (const auto &rt : _sorted_railtypes) { - if (HasBit(this->railtypes, rt)) { + if (this->railtypes.Test(rt)) { DrawString(ir.left, ir.right, y += GetCharacterHeight(FS_NORMAL), GetRailTypeInfo(rt)->strings.name, TC_WHITE); } } @@ -1997,11 +1997,11 @@ struct CompanyInfrastructureWindow : Window /* Draw infrastructure count for each valid railtype. */ uint32_t rail_total = c->infrastructure.GetRailTotal(); for (const auto &rt : _sorted_railtypes) { - if (HasBit(this->railtypes, rt)) { + if (this->railtypes.Test(rt)) { this->DrawCountLine(r, y, c->infrastructure.rail[rt], RailMaintenanceCost(rt, c->infrastructure.rail[rt], rail_total)); } } - if (this->railtypes != RAILTYPES_NONE) { + if (this->railtypes.Any()) { this->DrawCountLine(r, y, c->infrastructure.signal, SignalMaintenanceCost(c->infrastructure.signal)); } break; diff --git a/src/elrail.cpp b/src/elrail.cpp index a7912abb0f..4159ea815a 100644 --- a/src/elrail.cpp +++ b/src/elrail.cpp @@ -622,7 +622,7 @@ void UpdateDisableElrailSettingState(bool disable, bool update_vehicles) if (t->railtype == RAILTYPE_ELECTRIC) { /* this railroad vehicle is now compatible only with elrail, * so add there also normal rail compatibility */ - t->compatible_railtypes |= RAILTYPES_RAIL; + t->compatible_railtypes.Set(RAILTYPE_RAIL); t->railtype = RAILTYPE_RAIL; SetBit(t->flags, VRF_EL_ENGINE_ALLOWED_NORMAL_RAIL); } diff --git a/src/engine.cpp b/src/engine.cpp index fdd87afd34..102a284c63 100644 --- a/src/engine.cpp +++ b/src/engine.cpp @@ -1276,7 +1276,7 @@ bool IsEngineBuildable(EngineID engine, VehicleType type, CompanyID company) if (type == VEH_TRAIN && company != OWNER_DEITY) { /* Check if the rail type is available to this company */ const Company *c = Company::Get(company); - if (((GetRailTypeInfo(e->u.rail.railtype))->compatible_railtypes & c->avail_railtypes) == 0) return false; + if (!GetRailTypeInfo(e->u.rail.railtype)->compatible_railtypes.Any(c->avail_railtypes)) return false; } if (type == VEH_ROAD && company != OWNER_DEITY) { /* Check if the road type is available to this company */ diff --git a/src/newgrf/newgrf_act0_railtypes.cpp b/src/newgrf/newgrf_act0_railtypes.cpp index b847611ace..18ed679f8f 100644 --- a/src/newgrf/newgrf_act0_railtypes.cpp +++ b/src/newgrf/newgrf_act0_railtypes.cpp @@ -86,10 +86,10 @@ static ChangeInfoResult RailTypeChangeInfo(uint first, uint last, int prop, Byte RailType resolved_rt = GetRailTypeByLabel(std::byteswap(label), false); if (resolved_rt != INVALID_RAILTYPE) { switch (prop) { - case 0x0F: SetBit(rti->powered_railtypes, resolved_rt); [[fallthrough]]; // Powered implies compatible. - case 0x0E: SetBit(rti->compatible_railtypes, resolved_rt); break; - case 0x18: SetBit(rti->introduction_required_railtypes, resolved_rt); break; - case 0x19: SetBit(rti->introduces_railtypes, resolved_rt); break; + case 0x0F: rti->powered_railtypes.Set(resolved_rt); [[fallthrough]]; // Powered implies compatible. + case 0x0E: rti->compatible_railtypes.Set(resolved_rt); break; + case 0x18: rti->introduction_required_railtypes.Set(resolved_rt); break; + case 0x19: rti->introduces_railtypes.Set(resolved_rt); break; } } } diff --git a/src/pathfinder/follow_track.hpp b/src/pathfinder/follow_track.hpp index df8c6e7da9..4e10328512 100644 --- a/src/pathfinder/follow_track.hpp +++ b/src/pathfinder/follow_track.hpp @@ -333,7 +333,7 @@ protected: /* rail transport is possible only on compatible rail types */ if (IsRailTT()) { RailType rail_type = GetTileRailType(this->new_tile); - if (!HasBit(this->railtypes, rail_type)) { + if (!this->railtypes.Test(rail_type)) { /* incompatible rail type */ this->err = EC_RAIL_ROAD_TYPE; return false; diff --git a/src/pathfinder/yapf/yapf_destrail.hpp b/src/pathfinder/yapf/yapf_destrail.hpp index 754cb2b710..1133a66eec 100644 --- a/src/pathfinder/yapf/yapf_destrail.hpp +++ b/src/pathfinder/yapf/yapf_destrail.hpp @@ -22,12 +22,12 @@ public: void SetDestination(const Train *v, bool override_rail_type = false) { this->compatible_railtypes = v->compatible_railtypes; - if (override_rail_type) this->compatible_railtypes |= GetRailTypeInfo(v->railtype)->compatible_railtypes; + if (override_rail_type) this->compatible_railtypes.Set(GetRailTypeInfo(v->railtype)->compatible_railtypes); } bool IsCompatibleRailType(RailType rt) { - return HasBit(this->compatible_railtypes, rt); + return this->compatible_railtypes.Test(rt); } RailTypes GetCompatibleRailTypes() const diff --git a/src/rail.cpp b/src/rail.cpp index e68a376365..c5e0d7a6cb 100644 --- a/src/rail.cpp +++ b/src/rail.cpp @@ -185,7 +185,7 @@ RailType GetTileRailType(Tile tile) */ bool HasRailTypeAvail(const CompanyID company, const RailType railtype) { - return !HasBit(_railtypes_hidden_mask, railtype) && HasBit(Company::Get(company)->avail_railtypes, railtype); + return !_railtypes_hidden_mask.Test(railtype) && Company::Get(company)->avail_railtypes.Test(railtype); } /** @@ -195,7 +195,9 @@ bool HasRailTypeAvail(const CompanyID company, const RailType railtype) */ bool HasAnyRailTypesAvail(const CompanyID company) { - return (Company::Get(company)->avail_railtypes & ~_railtypes_hidden_mask) != 0; + RailTypes avail = Company::Get(company)->avail_railtypes; + avail.Reset(_railtypes_hidden_mask); + return avail.Any(); } /** @@ -234,7 +236,7 @@ RailTypes AddDateIntroducedRailTypes(RailTypes current, TimerGameCalendar::Date RailTypes required = rti->introduction_required_railtypes; if ((rts & required) != required) continue; - rts |= rti->introduces_railtypes; + rts.Set(rti->introduces_railtypes); } /* When we added railtypes we need to run this method again; the added @@ -250,7 +252,7 @@ RailTypes AddDateIntroducedRailTypes(RailTypes current, TimerGameCalendar::Date */ RailTypes GetCompanyRailTypes(CompanyID company, bool introduces) { - RailTypes rts = RAILTYPES_NONE; + RailTypes rts{}; for (const Engine *e : Engine::IterateType(VEH_TRAIN)) { const EngineInfo *ei = &e->info; @@ -262,9 +264,9 @@ RailTypes GetCompanyRailTypes(CompanyID company, bool introduces) if (rvi->railveh_type != RAILVEH_WAGON) { assert(rvi->railtype < RAILTYPE_END); if (introduces) { - rts |= GetRailTypeInfo(rvi->railtype)->introduces_railtypes; + rts.Set(GetRailTypeInfo(rvi->railtype)->introduces_railtypes); } else { - SetBit(rts, rvi->railtype); + rts.Set(rvi->railtype); } } } @@ -281,7 +283,7 @@ RailTypes GetCompanyRailTypes(CompanyID company, bool introduces) */ RailTypes GetRailTypes(bool introduces) { - RailTypes rts = RAILTYPES_NONE; + RailTypes rts{}; for (const Engine *e : Engine::IterateType(VEH_TRAIN)) { const EngineInfo *ei = &e->info; @@ -291,9 +293,9 @@ RailTypes GetRailTypes(bool introduces) if (rvi->railveh_type != RAILVEH_WAGON) { assert(rvi->railtype < RAILTYPE_END); if (introduces) { - rts |= GetRailTypeInfo(rvi->railtype)->introduces_railtypes; + rts.Set(GetRailTypeInfo(rvi->railtype)->introduces_railtypes); } else { - SetBit(rts, rvi->railtype); + rts.Set(rvi->railtype); } } } diff --git a/src/rail.h b/src/rail.h index 20ca41f7a6..5b896f8e9f 100644 --- a/src/rail.h +++ b/src/rail.h @@ -314,7 +314,7 @@ inline const RailTypeInfo *GetRailTypeInfo(RailType railtype) */ inline bool IsCompatibleRail(RailType enginetype, RailType tiletype) { - return HasBit(GetRailTypeInfo(enginetype)->compatible_railtypes, tiletype); + return GetRailTypeInfo(enginetype)->compatible_railtypes.Test(tiletype); } /** @@ -327,7 +327,7 @@ inline bool IsCompatibleRail(RailType enginetype, RailType tiletype) */ inline bool HasPowerOnRail(RailType enginetype, RailType tiletype) { - return HasBit(GetRailTypeInfo(enginetype)->powered_railtypes, tiletype); + return GetRailTypeInfo(enginetype)->powered_railtypes.Test(tiletype); } /** diff --git a/src/rail_cmd.cpp b/src/rail_cmd.cpp index d879103f80..d15a4ec64e 100644 --- a/src/rail_cmd.cpp +++ b/src/rail_cmd.cpp @@ -64,12 +64,12 @@ enum SignalOffsets { */ void ResetRailTypes() { - static_assert(lengthof(_original_railtypes) <= lengthof(_railtypes)); + static_assert(std::size(_original_railtypes) <= std::size(_railtypes)); auto insert = std::copy(std::begin(_original_railtypes), std::end(_original_railtypes), std::begin(_railtypes)); std::fill(insert, std::end(_railtypes), RailTypeInfo{}); - _railtypes_hidden_mask = RAILTYPES_NONE; + _railtypes_hidden_mask = {}; } void ResolveRailTypeGUISprites(RailTypeInfo *rti) @@ -132,7 +132,7 @@ void InitRailTypes() for (RailType rt = RAILTYPE_BEGIN; rt != RAILTYPE_END; rt++) { RailTypeInfo *rti = &_railtypes[rt]; ResolveRailTypeGUISprites(rti); - if (rti->flags.Test(RailTypeFlag::Hidden)) SetBit(_railtypes_hidden_mask, rt); + if (rti->flags.Test(RailTypeFlag::Hidden)) _railtypes_hidden_mask.Set(rt); } _sorted_railtypes.clear(); @@ -158,11 +158,11 @@ RailType AllocateRailType(RailTypeLabel label) rti->alternate_labels.clear(); /* Make us compatible with ourself. */ - rti->powered_railtypes = (RailTypes)(1LL << rt); - rti->compatible_railtypes = (RailTypes)(1LL << rt); + rti->powered_railtypes = rt; + rti->compatible_railtypes = rt; /* We also introduce ourself. */ - rti->introduces_railtypes = (RailTypes)(1LL << rt); + rti->introduces_railtypes = rt; /* Default sort order; order of allocation, but with some * offsets so it's easier for NewGRF to pick a spot without diff --git a/src/rail_gui.cpp b/src/rail_gui.cpp index 579466812e..09c551a344 100644 --- a/src/rail_gui.cpp +++ b/src/rail_gui.cpp @@ -2052,9 +2052,9 @@ DropDownList GetRailTypeDropDownList(bool for_replacement, bool all_option) Dimension d = { 0, 0 }; /* Get largest icon size, to ensure text is aligned on each menu item. */ if (!for_replacement) { - used_railtypes &= ~_railtypes_hidden_mask; + used_railtypes.Reset(_railtypes_hidden_mask); for (const auto &rt : _sorted_railtypes) { - if (!HasBit(used_railtypes, rt)) continue; + if (!used_railtypes.Test(rt)) continue; const RailTypeInfo *rti = GetRailTypeInfo(rt); d = maxdim(d, GetSpriteSize(rti->gui_sprites.build_x_rail)); } @@ -2065,17 +2065,17 @@ DropDownList GetRailTypeDropDownList(bool for_replacement, bool all_option) for (const auto &rt : _sorted_railtypes) { /* If it's not used ever, don't show it to the user. */ - if (!HasBit(used_railtypes, rt)) continue; + if (!used_railtypes.Test(rt)) continue; const RailTypeInfo *rti = GetRailTypeInfo(rt); if (for_replacement) { - list.push_back(MakeDropDownListBadgeItem(badge_class_list, rti->badges, GSF_RAILTYPES, rti->introduction_date, GetString(rti->strings.replace_text), rt, !HasBit(avail_railtypes, rt))); + list.push_back(MakeDropDownListBadgeItem(badge_class_list, rti->badges, GSF_RAILTYPES, rti->introduction_date, GetString(rti->strings.replace_text), rt, !avail_railtypes.Test(rt))); } else { std::string str = rti->max_speed > 0 ? GetString(STR_TOOLBAR_RAILTYPE_VELOCITY, rti->strings.menu_text, rti->max_speed) : GetString(rti->strings.menu_text); - list.push_back(MakeDropDownListBadgeIconItem(badge_class_list, rti->badges, GSF_RAILTYPES, rti->introduction_date, d, rti->gui_sprites.build_x_rail, PAL_NONE, std::move(str), rt, !HasBit(avail_railtypes, rt))); + list.push_back(MakeDropDownListBadgeIconItem(badge_class_list, rti->badges, GSF_RAILTYPES, rti->introduction_date, d, rti->gui_sprites.build_x_rail, PAL_NONE, std::move(str), rt, !avail_railtypes.Test(rt))); } } diff --git a/src/rail_type.h b/src/rail_type.h index 1d7c244d2a..cb12a09e37 100644 --- a/src/rail_type.h +++ b/src/rail_type.h @@ -21,8 +21,6 @@ static const RailTypeLabel RAILTYPE_LABEL_MAGLEV = 'MGLV'; /** * Enumeration for all possible railtypes. - * - * This enumeration defines all 4 possible railtypes. */ enum RailType : uint8_t { RAILTYPE_BEGIN = 0, ///< Used for iterations @@ -37,18 +35,8 @@ enum RailType : uint8_t { /** Allow incrementing of Track variables */ DECLARE_INCREMENT_DECREMENT_OPERATORS(RailType) -/** - * The different railtypes we support, but then a bitmask of them. - * @note Must be treated as a uint64_t type, narrowing it causes bit membership tests to give wrong results, as in bug #6951. - */ -enum RailTypes : uint64_t { - RAILTYPES_NONE = 0, ///< No rail types - RAILTYPES_RAIL = 1 << RAILTYPE_RAIL, ///< Non-electrified rails - RAILTYPES_ELECTRIC = 1 << RAILTYPE_ELECTRIC, ///< Electrified rails - RAILTYPES_MONO = 1 << RAILTYPE_MONO, ///< Monorail! - RAILTYPES_MAGLEV = 1 << RAILTYPE_MAGLEV, ///< Ever fast maglev - INVALID_RAILTYPES = UINT64_MAX, ///< Invalid railtypes -}; -DECLARE_ENUM_AS_BIT_SET(RailTypes) +using RailTypes = EnumBitSet; + +static constexpr RailTypes INVALID_RAILTYPES{UINT64_MAX}; #endif /* RAIL_TYPE_H */ diff --git a/src/table/railtypes.h b/src/table/railtypes.h index a4f80ca302..99e9b76ef4 100644 --- a/src/table/railtypes.h +++ b/src/table/railtypes.h @@ -60,10 +60,10 @@ static const RailTypeInfo _original_railtypes[] = { SPR_RAIL_SNOW_OFFSET, /* Powered railtypes */ - RAILTYPES_RAIL | RAILTYPES_ELECTRIC, + {RAILTYPE_RAIL, RAILTYPE_ELECTRIC}, /* Compatible railtypes */ - RAILTYPES_RAIL | RAILTYPES_ELECTRIC, + {RAILTYPE_RAIL, RAILTYPE_ELECTRIC}, /* bridge offset */ 0, @@ -102,10 +102,10 @@ static const RailTypeInfo _original_railtypes[] = { CalendarTime::INVALID_DATE, /* railtypes required for this to be introduced */ - RAILTYPES_NONE, + {}, /* introduction rail types */ - RAILTYPES_RAIL, + {RAILTYPE_RAIL}, /* sort order */ 0 << 4 | 7, @@ -162,10 +162,10 @@ static const RailTypeInfo _original_railtypes[] = { SPR_RAIL_SNOW_OFFSET, /* Powered railtypes */ - RAILTYPES_ELECTRIC, + {RAILTYPE_ELECTRIC}, /* Compatible railtypes */ - RAILTYPES_ELECTRIC | RAILTYPES_RAIL, + {RAILTYPE_RAIL, RAILTYPE_ELECTRIC}, /* bridge offset */ 0, @@ -204,10 +204,10 @@ static const RailTypeInfo _original_railtypes[] = { CalendarTime::INVALID_DATE, /* railtypes required for this to be introduced */ - RAILTYPES_NONE, + {}, /* introduction rail types */ - RAILTYPES_ELECTRIC, + {RAILTYPE_ELECTRIC}, /* sort order */ 1 << 4 | 7, @@ -260,10 +260,10 @@ static const RailTypeInfo _original_railtypes[] = { SPR_MONO_SNOW_OFFSET, /* Powered railtypes */ - RAILTYPES_MONO, + {RAILTYPE_MONO}, /* Compatible Railtypes */ - RAILTYPES_MONO, + {RAILTYPE_MONO}, /* bridge offset */ 16, @@ -302,10 +302,10 @@ static const RailTypeInfo _original_railtypes[] = { CalendarTime::INVALID_DATE, /* railtypes required for this to be introduced */ - RAILTYPES_NONE, + {}, /* introduction rail types */ - RAILTYPES_MONO, + {RAILTYPE_MONO}, /* sort order */ 2 << 4 | 7, @@ -358,10 +358,10 @@ static const RailTypeInfo _original_railtypes[] = { SPR_MGLV_SNOW_OFFSET, /* Powered railtypes */ - RAILTYPES_MAGLEV, + {RAILTYPE_MAGLEV}, /* Compatible Railtypes */ - RAILTYPES_MAGLEV, + {RAILTYPE_MAGLEV}, /* bridge offset */ 24, @@ -400,10 +400,10 @@ static const RailTypeInfo _original_railtypes[] = { CalendarTime::INVALID_DATE, /* railtypes required for this to be introduced */ - RAILTYPES_NONE, + {}, /* introduction rail types */ - RAILTYPES_MAGLEV, + {RAILTYPE_MAGLEV}, /* sort order */ 3 << 4 | 7, diff --git a/src/train_cmd.cpp b/src/train_cmd.cpp index b84cde5b5a..f5782006a3 100644 --- a/src/train_cmd.cpp +++ b/src/train_cmd.cpp @@ -114,7 +114,7 @@ void Train::ConsistChanged(ConsistChangeFlags allowed_changes) const RailVehicleInfo *rvi_v = RailVehInfo(this->engine_type); EngineID first_engine = this->IsFrontEngine() ? this->engine_type : EngineID::Invalid(); this->gcache.cached_total_length = 0; - this->compatible_railtypes = RAILTYPES_NONE; + this->compatible_railtypes = {}; bool train_can_tilt = true; int16_t min_curve_speed_mod = INT16_MAX; @@ -172,14 +172,14 @@ void Train::ConsistChanged(ConsistChangeFlags allowed_changes) /* Do not count powered wagons for the compatible railtypes, as wagons always have railtype normal */ if (rvi_u->power > 0) { - this->compatible_railtypes |= GetRailTypeInfo(u->railtype)->powered_railtypes; + this->compatible_railtypes.Set(GetRailTypeInfo(u->railtype)->powered_railtypes); } /* Some electric engines can be allowed to run on normal rail. It happens to all * existing electric engines when elrails are disabled and then re-enabled */ if (HasBit(u->flags, VRF_EL_ENGINE_ALLOWED_NORMAL_RAIL)) { u->railtype = RAILTYPE_RAIL; - u->compatible_railtypes |= RAILTYPES_RAIL; + u->compatible_railtypes.Set(RAILTYPE_RAIL); } /* max speed is the minimum of the speed limits of all vehicles in the consist */ @@ -3031,7 +3031,7 @@ static void TrainEnterStation(Train *v, StationID station) static inline bool CheckCompatibleRail(const Train *v, TileIndex tile) { return IsTileOwner(tile, v->owner) && - (!v->IsFrontEngine() || HasBit(v->compatible_railtypes, GetRailType(tile))); + (!v->IsFrontEngine() || v->compatible_railtypes.Test(GetRailType(tile))); } /** Data structure for storing engine speed changes of an acceleration type. */