From 7055ea0aee8ffb48d481873324507a0b03977570 Mon Sep 17 00:00:00 2001 From: frosch Date: Sat, 3 May 2025 20:03:39 +0200 Subject: [PATCH] Codechange: Define sequential operators for ZoomLevel. --- src/core/enum_type.hpp | 49 ++++++++++++++++++++++++++++++++++++++ src/core/math_func.hpp | 6 +++++ src/gfx.cpp | 2 +- src/newgrf_debug_gui.cpp | 16 ++++++------- src/saveload/afterload.cpp | 2 +- src/spritecache.cpp | 7 +++--- src/video/opengl.h | 2 +- src/viewport.cpp | 4 ++-- src/zoom_func.h | 4 ++-- src/zoom_type.h | 2 +- 10 files changed, 75 insertions(+), 19 deletions(-) diff --git a/src/core/enum_type.hpp b/src/core/enum_type.hpp index 61f1e19767..6c30f7a39b 100644 --- a/src/core/enum_type.hpp +++ b/src/core/enum_type.hpp @@ -65,6 +65,55 @@ inline constexpr enum_type operator --(enum_type &e, int) static const bool value = true; \ }; +/** Trait to enable prefix/postfix incrementing operators. */ +template +struct is_enum_sequential { + static constexpr bool value = false; +}; + +template +constexpr bool is_enum_sequential_v = is_enum_sequential::value; + +/** Add integer. */ +template , bool> = true> +inline constexpr enum_type operator+(enum_type e, int offset) +{ + return static_cast(to_underlying(e) + offset); +} + +template , bool> = true> +inline constexpr enum_type &operator+=(enum_type &e, int offset) +{ + e = e + offset; + return e; +} + +/** Sub integer. */ +template , bool> = true> +inline constexpr enum_type operator-(enum_type e, int offset) +{ + return static_cast(to_underlying(e) - offset); +} + +template , bool> = true> +inline constexpr enum_type &operator-=(enum_type &e, int offset) +{ + e = e - offset; + return e; +} + +/** Distance */ +template , bool> = true> +inline constexpr auto operator-(enum_type a, enum_type b) +{ + return to_underlying(a) - to_underlying(b); +} + +/** For some enums it is useful to add/sub more than 1 */ +#define DECLARE_ENUM_AS_SEQUENTIAL(enum_type) \ + template <> struct is_enum_sequential { \ + static const bool value = true; \ + }; /** Operators to allow to work with enum as with type safe bit set in C++ */ #define DECLARE_ENUM_AS_BIT_SET(enum_type) \ diff --git a/src/core/math_func.hpp b/src/core/math_func.hpp index 7207cf3baf..3b9b406e02 100644 --- a/src/core/math_func.hpp +++ b/src/core/math_func.hpp @@ -271,6 +271,12 @@ constexpr bool IsInsideMM(const size_t x, const size_t min, const size_t max) no constexpr bool IsInsideMM(const ConvertibleThroughBase auto x, const size_t min, const size_t max) noexcept { return IsInsideMM(x.base(), min, max); } +template , bool> = true> +constexpr bool IsInsideMM(enum_type x, enum_type min, enum_type max) noexcept +{ + return IsInsideMM(to_underlying(x), to_underlying(min), to_underlying(max)); +} + /** * Converts a "fract" value 0..255 to "percent" value 0..100 * @param i value to convert, range 0..255 diff --git a/src/gfx.cpp b/src/gfx.cpp index 364e9955b5..c781b8b8d7 100644 --- a/src/gfx.cpp +++ b/src/gfx.cpp @@ -1827,7 +1827,7 @@ bool AdjustGUIZoom(bool automatic) w->top = (w->top * _gui_scale) / old_scale; } if (w->viewport != nullptr) { - w->viewport->zoom = static_cast(Clamp(w->viewport->zoom - zoom_shift, _settings_client.gui.zoom_min, _settings_client.gui.zoom_max)); + w->viewport->zoom = Clamp(w->viewport->zoom - zoom_shift, _settings_client.gui.zoom_min, _settings_client.gui.zoom_max); } } diff --git a/src/newgrf_debug_gui.cpp b/src/newgrf_debug_gui.cpp index 58db6b765a..cf2fcb7b07 100644 --- a/src/newgrf_debug_gui.cpp +++ b/src/newgrf_debug_gui.cpp @@ -1110,8 +1110,8 @@ struct SpriteAlignerWindow : Window { SpriteAlignerWindow::zoom = Clamp(SpriteAlignerWindow::zoom, _settings_client.gui.zoom_min, _settings_client.gui.zoom_max); for (ZoomLevel z = ZOOM_LVL_BEGIN; z < ZOOM_LVL_END; z++) { - this->SetWidgetsDisabledState(z < _settings_client.gui.zoom_min || z > _settings_client.gui.zoom_max, WID_SA_ZOOM + z); - this->SetWidgetsLoweredState(SpriteAlignerWindow::zoom == z, WID_SA_ZOOM + z); + this->SetWidgetsDisabledState(z < _settings_client.gui.zoom_min || z > _settings_client.gui.zoom_max, WID_SA_ZOOM + to_underlying(z)); + this->SetWidgetsLoweredState(SpriteAlignerWindow::zoom == z, WID_SA_ZOOM + to_underlying(z)); } } @@ -1191,12 +1191,12 @@ static constexpr NWidgetPart _nested_sprite_aligner_widgets[] = { NWidget(NWID_VSCROLLBAR, COLOUR_GREY, WID_SA_SCROLLBAR), EndContainer(), NWidget(NWID_VERTICAL), - NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_SA_ZOOM + ZOOM_LVL_IN_4X), SetStringTip(STR_CONFIG_SETTING_ZOOM_LVL_MIN), SetFill(1, 0), - NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_SA_ZOOM + ZOOM_LVL_IN_2X), SetStringTip(STR_CONFIG_SETTING_ZOOM_LVL_IN_2X), SetFill(1, 0), - NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_SA_ZOOM + ZOOM_LVL_NORMAL), SetStringTip(STR_CONFIG_SETTING_ZOOM_LVL_NORMAL), SetFill(1, 0), - NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_SA_ZOOM + ZOOM_LVL_OUT_2X), SetStringTip(STR_CONFIG_SETTING_ZOOM_LVL_OUT_2X), SetFill(1, 0), - NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_SA_ZOOM + ZOOM_LVL_OUT_4X), SetStringTip(STR_CONFIG_SETTING_ZOOM_LVL_OUT_4X), SetFill(1, 0), - NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_SA_ZOOM + ZOOM_LVL_OUT_8X), SetStringTip(STR_CONFIG_SETTING_ZOOM_LVL_OUT_8X), SetFill(1, 0), + NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_SA_ZOOM + to_underlying(ZOOM_LVL_IN_4X)), SetStringTip(STR_CONFIG_SETTING_ZOOM_LVL_MIN), SetFill(1, 0), + NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_SA_ZOOM + to_underlying(ZOOM_LVL_IN_2X)), SetStringTip(STR_CONFIG_SETTING_ZOOM_LVL_IN_2X), SetFill(1, 0), + NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_SA_ZOOM + to_underlying(ZOOM_LVL_NORMAL)), SetStringTip(STR_CONFIG_SETTING_ZOOM_LVL_NORMAL), SetFill(1, 0), + NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_SA_ZOOM + to_underlying(ZOOM_LVL_OUT_2X)), SetStringTip(STR_CONFIG_SETTING_ZOOM_LVL_OUT_2X), SetFill(1, 0), + NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_SA_ZOOM + to_underlying(ZOOM_LVL_OUT_4X)), SetStringTip(STR_CONFIG_SETTING_ZOOM_LVL_OUT_4X), SetFill(1, 0), + NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_SA_ZOOM + to_underlying(ZOOM_LVL_OUT_8X)), SetStringTip(STR_CONFIG_SETTING_ZOOM_LVL_OUT_8X), SetFill(1, 0), EndContainer(), EndContainer(), EndContainer(), diff --git a/src/saveload/afterload.cpp b/src/saveload/afterload.cpp index 487b7eaf93..ae2c63b6ab 100644 --- a/src/saveload/afterload.cpp +++ b/src/saveload/afterload.cpp @@ -2898,7 +2898,7 @@ bool AfterLoadGame() if (IsSavegameVersionBefore(SLV_165)) { /* Adjust zoom level to account for new levels */ - _saved_scrollpos_zoom = static_cast(_saved_scrollpos_zoom + ZOOM_BASE_SHIFT); + _saved_scrollpos_zoom += ZOOM_BASE_SHIFT; _saved_scrollpos_x *= ZOOM_BASE; _saved_scrollpos_y *= ZOOM_BASE; } diff --git a/src/spritecache.cpp b/src/spritecache.cpp index 7034392daa..4d82164b87 100644 --- a/src/spritecache.cpp +++ b/src/spritecache.cpp @@ -221,7 +221,7 @@ SpriteID GetMaxSpriteID() static bool ResizeSpriteIn(SpriteLoader::SpriteCollection &sprite, ZoomLevel src, ZoomLevel tgt) { - uint8_t scaled_1 = ScaleByZoom(1, (ZoomLevel)(src - tgt)); + uint8_t scaled_1 = AdjustByZoom(1, src - tgt); const auto &src_sprite = sprite[src]; auto &dest_sprite = sprite[tgt]; @@ -419,8 +419,9 @@ static bool ResizeSprites(SpriteLoader::SpriteCollection &sprite, ZoomLevels spr /* Upscale to desired sprite_min_zoom if provided sprite only had zoomed in versions. */ if (first_avail < _settings_client.gui.sprite_zoom_min) { - if (_settings_client.gui.sprite_zoom_min >= ZOOM_LVL_NORMAL) ResizeSpriteIn(sprite, ZOOM_LVL_NORMAL, ZOOM_LVL_IN_2X); - if (_settings_client.gui.sprite_zoom_min >= ZOOM_LVL_IN_2X) ResizeSpriteIn(sprite, ZOOM_LVL_IN_2X, ZOOM_LVL_IN_4X); + for (ZoomLevel zoom = std::min(ZOOM_LVL_NORMAL, _settings_client.gui.sprite_zoom_min); zoom > ZOOM_LVL_MIN; --zoom) { + ResizeSpriteIn(sprite, zoom, zoom - 1); + } } return true; diff --git a/src/video/opengl.h b/src/video/opengl.h index 84f2a6efcf..0b0532683d 100644 --- a/src/video/opengl.h +++ b/src/video/opengl.h @@ -105,7 +105,7 @@ public: /* SpriteEncoder */ bool Is32BppSupported() override { return true; } - uint GetSpriteAlignment() override { return 1u << (ZOOM_LVL_END - 1); } + uint GetSpriteAlignment() override { return 1u << ZOOM_LVL_MAX; } Sprite *Encode(SpriteType sprite_type, const SpriteLoader::SpriteCollection &sprite, SpriteAllocator &allocator) override; }; diff --git a/src/viewport.cpp b/src/viewport.cpp index 7950b7d4a2..879339ba0e 100644 --- a/src/viewport.cpp +++ b/src/viewport.cpp @@ -227,7 +227,7 @@ void InitializeWindowViewport(Window *w, int x, int y, vp->width = width; vp->height = height; - vp->zoom = static_cast(Clamp(zoom, _settings_client.gui.zoom_min, _settings_client.gui.zoom_max)); + vp->zoom = Clamp(zoom, _settings_client.gui.zoom_min, _settings_client.gui.zoom_max); vp->virtual_width = ScaleByZoom(width, zoom); vp->virtual_height = ScaleByZoom(height, zoom); @@ -2081,7 +2081,7 @@ void ConstrainAllViewportsZoom() for (Window *w : Window::Iterate()) { if (w->viewport == nullptr) continue; - ZoomLevel zoom = static_cast(Clamp(w->viewport->zoom, _settings_client.gui.zoom_min, _settings_client.gui.zoom_max)); + ZoomLevel zoom = Clamp(w->viewport->zoom, _settings_client.gui.zoom_min, _settings_client.gui.zoom_max); if (zoom != w->viewport->zoom) { while (w->viewport->zoom < zoom) DoZoomInOutWindow(ZOOM_OUT, w); while (w->viewport->zoom > zoom) DoZoomInOutWindow(ZOOM_IN, w); diff --git a/src/zoom_func.h b/src/zoom_func.h index 4b998839f0..2bc4eb3ac2 100644 --- a/src/zoom_func.h +++ b/src/zoom_func.h @@ -86,7 +86,7 @@ inline int UnScaleGUI(int value) */ inline ZoomLevel ScaleZoomGUI(ZoomLevel value) { - return std::clamp(ZoomLevel(value + (ZOOM_LVL_GUI - ZOOM_LVL_NORMAL)), ZOOM_LVL_MIN, ZOOM_LVL_MAX); + return std::clamp(value + (ZOOM_LVL_GUI - ZOOM_LVL_NORMAL), ZOOM_LVL_MIN, ZOOM_LVL_MAX); } /** @@ -96,7 +96,7 @@ inline ZoomLevel ScaleZoomGUI(ZoomLevel value) */ inline ZoomLevel UnScaleZoomGUI(ZoomLevel value) { - return std::clamp(ZoomLevel(value - (ZOOM_LVL_GUI - ZOOM_LVL_NORMAL)), ZOOM_LVL_MIN, ZOOM_LVL_MAX); + return std::clamp(value - (ZOOM_LVL_GUI - ZOOM_LVL_NORMAL), ZOOM_LVL_MIN, ZOOM_LVL_MAX); } /** diff --git a/src/zoom_type.h b/src/zoom_type.h index 304d13e874..8ee8a8f99e 100644 --- a/src/zoom_type.h +++ b/src/zoom_type.h @@ -42,7 +42,7 @@ enum ZoomLevel : uint8_t { ZOOM_LVL_MAX = ZOOM_LVL_OUT_8X, ///< Maximum zoom level. }; DECLARE_INCREMENT_DECREMENT_OPERATORS(ZoomLevel) -DECLARE_ENUM_AS_ADDABLE(ZoomLevel) +DECLARE_ENUM_AS_SEQUENTIAL(ZoomLevel) using ZoomLevels = EnumBitSet; static uint const ZOOM_BASE_SHIFT = static_cast(ZOOM_LVL_NORMAL);