diff --git a/src/rail.h b/src/rail.h index 92614427c0..c06f2930fc 100644 --- a/src/rail.h +++ b/src/rail.h @@ -147,7 +147,7 @@ public: SpriteID build_depot; ///< button for building depots SpriteID build_tunnel; ///< button for building a tunnel SpriteID convert_rail; ///< button for converting rail - SpriteID signals[SIGTYPE_END][2][2]; ///< signal GUI sprites (type, variant, state) + EnumIndexArray, SignalVariant, SIG_END>, SignalType, SIGTYPE_END> signals; ///< signal GUI sprites (type, variant, state) } gui_sprites; struct { diff --git a/src/rail_cmd.cpp b/src/rail_cmd.cpp index d9db192f6c..509c7cb07d 100644 --- a/src/rail_cmd.cpp +++ b/src/rail_cmd.cpp @@ -95,20 +95,20 @@ void ResolveRailTypeGUISprites(RailTypeInfo *rti) } /* Array of default GUI signal sprite numbers. */ - const SpriteID _signal_lookup[2][SIGTYPE_END] = { + const EnumIndexArray, SignalVariant, SIG_END> _signal_lookup{{{ {SPR_IMG_SIGNAL_ELECTRIC_NORM, SPR_IMG_SIGNAL_ELECTRIC_ENTRY, SPR_IMG_SIGNAL_ELECTRIC_EXIT, SPR_IMG_SIGNAL_ELECTRIC_COMBO, SPR_IMG_SIGNAL_ELECTRIC_PBS, SPR_IMG_SIGNAL_ELECTRIC_PBS_OWAY}, {SPR_IMG_SIGNAL_SEMAPHORE_NORM, SPR_IMG_SIGNAL_SEMAPHORE_ENTRY, SPR_IMG_SIGNAL_SEMAPHORE_EXIT, SPR_IMG_SIGNAL_SEMAPHORE_COMBO, SPR_IMG_SIGNAL_SEMAPHORE_PBS, SPR_IMG_SIGNAL_SEMAPHORE_PBS_OWAY}, - }; + }}}; - for (SignalType type = SIGTYPE_BLOCK; type < SIGTYPE_END; type = (SignalType)(type + 1)) { - for (SignalVariant var = SIG_ELECTRIC; var <= SIG_SEMAPHORE; var = (SignalVariant)(var + 1)) { - SpriteID red = GetCustomSignalSprite(rti, INVALID_TILE, type, var, SIGNAL_STATE_RED, true); + for (SignalType type = SIGTYPE_BLOCK; type < SIGTYPE_END; type = static_cast(to_underlying(type) + 1)) { + for (SignalVariant var : {SIG_ELECTRIC, SIG_SEMAPHORE}) { + SpriteID red = GetCustomSignalSprite(rti, INVALID_TILE, type, var, SIGNAL_STATE_RED, true); SpriteID green = GetCustomSignalSprite(rti, INVALID_TILE, type, var, SIGNAL_STATE_GREEN, true); - rti->gui_sprites.signals[type][var][0] = (red != 0) ? red + SIGNAL_TO_SOUTH : _signal_lookup[var][type]; - rti->gui_sprites.signals[type][var][1] = (green != 0) ? green + SIGNAL_TO_SOUTH : _signal_lookup[var][type] + 1; + rti->gui_sprites.signals[type][var][SIGNAL_STATE_RED] = (red != 0) ? red + SIGNAL_TO_SOUTH : _signal_lookup[var][type]; + rti->gui_sprites.signals[type][var][SIGNAL_STATE_GREEN] = (green != 0) ? green + SIGNAL_TO_SOUTH : _signal_lookup[var][type] + 1; } } } @@ -2838,7 +2838,7 @@ static void GetTileDesc_Rail(TileIndex tile, TileDesc &td) break; case RailTileType::Signals: { - static const StringID signal_type[6][6] = { + static constexpr EnumIndexArray, SignalType, SIGTYPE_END> signal_type{{{ { STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_NORMAL_SIGNALS, STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_NORMAL_PRESIGNALS, @@ -2886,8 +2886,8 @@ static void GetTileDesc_Rail(TileIndex tile, TileDesc &td) STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_COMBO_NOENTRYSIGNALS, STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_PBS_NOENTRYSIGNALS, STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_NOENTRYSIGNALS - } - }; + }, + }}}; SignalType primary_signal; SignalType secondary_signal; diff --git a/src/rail_gui.cpp b/src/rail_gui.cpp index 6bdd607784..b8a5a5add3 100644 --- a/src/rail_gui.cpp +++ b/src/rail_gui.cpp @@ -1554,11 +1554,11 @@ public: this->sig_sprite_size.height = 0; this->sig_sprite_bottom_offset = 0; const RailTypeInfo *rti = GetRailTypeInfo(_cur_railtype); - for (uint type = SIGTYPE_BLOCK; type < SIGTYPE_END; type++) { - for (uint variant = SIG_ELECTRIC; variant <= SIG_SEMAPHORE; variant++) { - for (uint lowered = 0; lowered < 2; lowered++) { + for (SignalType type = SIGTYPE_BLOCK; type < SIGTYPE_END; type = static_cast(to_underlying(type) + 1)) { + for (SignalVariant variant : {SIG_ELECTRIC, SIG_SEMAPHORE}) { + for (SignalState state : {SIGNAL_STATE_RED, SIGNAL_STATE_GREEN}) { Point offset; - Dimension sprite_size = GetSpriteSize(rti->gui_sprites.signals[type][variant][lowered], &offset); + Dimension sprite_size = GetSpriteSize(rti->gui_sprites.signals[type][variant][state], &offset); this->sig_sprite_bottom_offset = std::max(this->sig_sprite_bottom_offset, sprite_size.height); this->sig_sprite_size.width = std::max(this->sig_sprite_size.width, sprite_size.width - offset.x); this->sig_sprite_size.height = std::max(this->sig_sprite_size.height, sprite_size.height - offset.y); @@ -1593,9 +1593,9 @@ public: { if (IsInsideMM(widget, WID_BS_SEMAPHORE_NORM, WID_BS_ELECTRIC_PBS_OWAY + 1)) { /* Extract signal from widget number. */ - int type = (widget - WID_BS_SEMAPHORE_NORM) % SIGTYPE_END; - int var = SIG_SEMAPHORE - (widget - WID_BS_SEMAPHORE_NORM) / SIGTYPE_END; // SignalVariant order is reversed compared to the widgets. - SpriteID sprite = GetRailTypeInfo(_cur_railtype)->gui_sprites.signals[type][var][this->IsWidgetLowered(widget)]; + SignalType type = static_cast((widget - WID_BS_SEMAPHORE_NORM) % SIGTYPE_END); + SignalVariant var = static_cast(SIG_SEMAPHORE - (widget - WID_BS_SEMAPHORE_NORM) / SIGTYPE_END); // SignalVariant order is reversed compared to the widgets. + SpriteID sprite = GetRailTypeInfo(_cur_railtype)->gui_sprites.signals[type][var][static_cast(this->IsWidgetLowered(widget))]; this->DrawSignalSprite(r, sprite); } diff --git a/src/signal_type.h b/src/signal_type.h index 1704ffeb39..b42081fc7e 100644 --- a/src/signal_type.h +++ b/src/signal_type.h @@ -16,6 +16,7 @@ enum SignalVariant : uint8_t { SIG_ELECTRIC = 0, ///< Light signal SIG_SEMAPHORE = 1, ///< Old-fashioned semaphore signal + SIG_END, ///< End marker. }; @@ -28,7 +29,7 @@ enum SignalType : uint8_t { SIGTYPE_PBS = 4, ///< normal pbs signal SIGTYPE_PBS_ONEWAY = 5, ///< no-entry signal - SIGTYPE_END, + SIGTYPE_END, /// End marker. SIGTYPE_LAST = SIGTYPE_PBS_ONEWAY, SIGTYPE_LAST_NOPBS = SIGTYPE_COMBO, }; @@ -42,6 +43,7 @@ DECLARE_ENUM_AS_ADDABLE(SignalType) enum SignalState : uint8_t { SIGNAL_STATE_RED = 0, ///< The signal is red SIGNAL_STATE_GREEN = 1, ///< The signal is green + SIGNAL_STATE_END, ///< End marker. }; #endif /* SIGNAL_TYPE_H */