diff --git a/src/openrct2-ui/UiContext.cpp b/src/openrct2-ui/UiContext.cpp index ba44bfa577..0f662eb9bf 100644 --- a/src/openrct2-ui/UiContext.cpp +++ b/src/openrct2-ui/UiContext.cpp @@ -273,6 +273,20 @@ public: return std::make_shared(); } + void DrawRainAnimation(IRainDrawer* rainDrawer, rct_drawpixelinfo* dpi, DrawRainFunc drawFunc) override + { + sint32 left = dpi->x; + sint32 right = left + dpi->width; + sint32 top = dpi->y; + sint32 bottom = top + dpi->height; + + rct_window * newWindow = gWindowNextSlot; + for (rct_window * w = g_window_list; w < newWindow; w++) + { + DrawRainWindow(rainDrawer, w, left, right, top, bottom, drawFunc); + } + } + // Text input bool IsTextInputActive() override { @@ -756,6 +770,89 @@ private: { return SDL_GetWindowFlags(_window); } + + static void DrawRainWindow( + IRainDrawer * rainDrawer, + rct_window * original_w, + sint16 left, + sint16 right, + sint16 top, + sint16 bottom, + DrawRainFunc drawFunc) + { + rct_window * newWindow = gWindowNextSlot; + rct_window * w = original_w + 1; // Start from second window + for (; ; w++) + { + if (w >= newWindow) + { + // Loop ended, draw rain for original_w + auto vp = original_w->viewport; + if (vp != nullptr) + { + left = std::max(left, vp->x); + right = std::min(right, vp->x + vp->width); + top = std::max(top, vp->y); + bottom = std::min(bottom, vp->y + vp->height); + if (left < right && top < bottom) + { + auto width = right - left; + auto height = bottom - top; + drawFunc(rainDrawer, left, top, width, height); + } + } + return; + } + + if (right <= w->x || bottom <= w->y) + { + continue; + } + + if (RCT_WINDOW_RIGHT(w) <= left || RCT_WINDOW_BOTTOM(w) <= top) + { + continue; + } + + if (left >= w->x) + { + break; + } + + DrawRainWindow(rainDrawer, original_w, left, w->x, top, bottom, drawFunc); + + left = w->x; + DrawRainWindow(rainDrawer, original_w, left, right, top, bottom, drawFunc); + return; + } + + sint16 w_right = RCT_WINDOW_RIGHT(w); + if (right > w_right) { + DrawRainWindow(rainDrawer, original_w, left, w_right, top, bottom, drawFunc); + + left = w_right; + DrawRainWindow(rainDrawer, original_w, left, right, top, bottom, drawFunc); + return; + } + + if (top < w->y) { + DrawRainWindow(rainDrawer, original_w, left, right, top, w->y, drawFunc); + + top = w->y; + DrawRainWindow(rainDrawer, original_w, left, right, top, bottom, drawFunc); + return; + } + + sint16 w_bottom = RCT_WINDOW_BOTTOM(w); + if (bottom > w_bottom) + { + DrawRainWindow(rainDrawer, original_w, left, right, top, w_bottom, drawFunc); + + top = w_bottom; + DrawRainWindow(rainDrawer, original_w, left, right, top, bottom, drawFunc); + return; + } + } }; std::unique_ptr OpenRCT2::Ui::CreateUiContext(const std::shared_ptr& env) diff --git a/src/openrct2/drawing/Rain.cpp b/src/openrct2/drawing/Rain.cpp index bf84de4b2e..a968967dff 100644 --- a/src/openrct2/drawing/Rain.cpp +++ b/src/openrct2/drawing/Rain.cpp @@ -14,23 +14,19 @@ *****************************************************************************/ #pragma endregion -#include "../interface/Window.h" -#include "../interface/Window_internal.h" -#include "../world/Climate.h" -#include "Drawing.h" #include "../config/Config.h" #include "../interface/Viewport.h" #include "../ride/TrackDesign.h" #include "../scenario/Scenario.h" - +#include "../ui/UiContext.h" +#include "../world/Climate.h" +#include "Drawing.h" #include "IDrawingEngine.h" #include "Rain.h" -#include "../core/Math.hpp" +using namespace OpenRCT2; using namespace OpenRCT2::Drawing; -using DrawRainFunc = void (*)(IRainDrawer * rainDrawer, sint32 left, sint32 top, sint32 width, sint32 height); - static void DrawLightRain(IRainDrawer * rainDrawer, sint32 left, sint32 top, sint32 width, sint32 height); static void DrawHeavyRain(IRainDrawer * rainDrawer, sint32 left, sint32 top, sint32 width, sint32 height); @@ -45,144 +41,22 @@ const DrawRainFunc DrawRainFunctions[] = &DrawHeavyRain }; -/** - * - * rct2: 0x00684383 - */ -static void CallDrawRainFunc(IRainDrawer * rainDrawer, - rct_window * w, - sint16 left, - sint16 right, - sint16 top, - sint16 bottom, - uint32 rainType) -{ - rct_viewport * vp = w->viewport; - if (vp == nullptr) - { - return; - } - - left = Math::Max(left, vp->x); - right = Math::Min(right, vp->x + vp->width); - top = Math::Max(top, vp->y); - bottom = Math::Min(bottom, vp->y + vp->height); - if (left >= right || top >= bottom) - { - return; - } - - sint32 width = right - left; - sint32 height = bottom - top; - DrawRainFunctions[rainType](rainDrawer, left, top, width, height); -} - -/** - * - * rct2: 0x006842AF - * From 0x00684383 on: split into call_draw_rain_func - */ -static void DrawRainWindow(IRainDrawer * rainDrawer, - rct_window * original_w, - sint16 left, - sint16 right, - sint16 top, - sint16 bottom, - uint32 rainType) -{ - if (!gConfigGeneral.render_weather_effects) - return; - - rct_window * newWindow = gWindowNextSlot; - rct_window * w = original_w + 1; // Start from second window - for (; ; w++) - { - if (w >= newWindow) - { - // Loop ended, draw rain for original_w - CallDrawRainFunc(rainDrawer, original_w, left, right, top, bottom, rainType); - return; - } - - if (right <= w->x || bottom <= w->y) - { - continue; - } - - if (RCT_WINDOW_RIGHT(w) <= left || RCT_WINDOW_BOTTOM(w) <= top) - { - continue; - } - - if (left >= w->x) - { - break; - } - - DrawRainWindow(rainDrawer, original_w, left, w->x, top, bottom, rainType); - - left = w->x; - DrawRainWindow(rainDrawer, original_w, left, right, top, bottom, rainType); - return; - } - - sint16 w_right = RCT_WINDOW_RIGHT(w); - if (right > w_right) { - DrawRainWindow(rainDrawer, original_w, left, w_right, top, bottom, rainType); - - left = w_right; - DrawRainWindow(rainDrawer, original_w, left, right, top, bottom, rainType); - return; - } - - if (top < w->y) { - DrawRainWindow(rainDrawer, original_w, left, right, top, w->y, rainType); - - top = w->y; - DrawRainWindow(rainDrawer, original_w, left, right, top, bottom, rainType); - return; - } - - sint16 w_bottom = RCT_WINDOW_BOTTOM(w); - if (bottom > w_bottom) - { - DrawRainWindow(rainDrawer, original_w, left, right, top, w_bottom, rainType); - - top = w_bottom; - DrawRainWindow(rainDrawer, original_w, left, right, top, bottom, rainType); - return; - } -} - -/** - * - * rct2: 0x00684266 - */ -static void DrawRainAnimation(rct_drawpixelinfo * dpi, IRainDrawer * rainDrawer, uint32 rainType) -{ - sint32 left = dpi->x; - sint32 right = left + dpi->width; - sint32 top = dpi->y; - sint32 bottom = top + dpi->height; - - rct_window * newWindow = gWindowNextSlot; - for (rct_window * w = g_window_list; w < newWindow; w++) - { - DrawRainWindow(rainDrawer, w, left, right, top, bottom, rainType); - } -} - /** * * rct2: 0x00684218 */ void DrawRain(rct_drawpixelinfo * dpi, IRainDrawer * rainDrawer) { - // Get rain draw function and draw rain - uint32 rainType = gClimateCurrent.RainLevel; - if (rainType != RAIN_LEVEL_NONE && !gTrackDesignSaveMode && !(gCurrentViewportFlags & VIEWPORT_FLAG_HIGHLIGHT_PATH_ISSUES)) + if (gConfigGeneral.render_weather_effects) { - DrawRainAnimation(dpi, rainDrawer, rainType); + // Get rain draw function and draw rain + uint32 rainType = gClimateCurrent.RainLevel; + if (rainType != RAIN_LEVEL_NONE && !gTrackDesignSaveMode && !(gCurrentViewportFlags & VIEWPORT_FLAG_HIGHLIGHT_PATH_ISSUES)) + { + auto drawFunc = DrawRainFunctions[rainType]; + auto uiContext = GetContext()->GetUiContext(); + uiContext->DrawRainAnimation(rainDrawer, dpi, drawFunc); + } } } diff --git a/src/openrct2/ui/DummyUiContext.cpp b/src/openrct2/ui/DummyUiContext.cpp index f541bb93ba..68965078c3 100644 --- a/src/openrct2/ui/DummyUiContext.cpp +++ b/src/openrct2/ui/DummyUiContext.cpp @@ -80,6 +80,7 @@ namespace OpenRCT2::Ui { return std::make_shared(); } + void DrawRainAnimation(IRainDrawer* rainDrawer, rct_drawpixelinfo* dpi, DrawRainFunc drawFunc) override { } // Text input bool IsTextInputActive() override { return false; } diff --git a/src/openrct2/ui/UiContext.h b/src/openrct2/ui/UiContext.h index 9fa89eaaac..4b0f9dca71 100644 --- a/src/openrct2/ui/UiContext.h +++ b/src/openrct2/ui/UiContext.h @@ -31,6 +31,8 @@ namespace OpenRCT2 namespace Drawing { interface IDrawingEngineFactory; + interface IRainDrawer; + using DrawRainFunc = void(*)(OpenRCT2::Drawing::IRainDrawer * rainDrawer, sint32 left, sint32 top, sint32 width, sint32 height); } // namespace Drawing namespace Ui @@ -132,6 +134,7 @@ namespace OpenRCT2 // Drawing virtual std::shared_ptr GetDrawingEngineFactory() abstract; + virtual void DrawRainAnimation(OpenRCT2::Drawing::IRainDrawer* rainDrawer, rct_drawpixelinfo* dpi, OpenRCT2::Drawing::DrawRainFunc drawFunc) abstract; // Text input virtual bool IsTextInputActive() abstract;