diff --git a/src/openrct2-ui/windows/EditorMain.cpp b/src/openrct2-ui/windows/EditorMain.cpp index b87bbfec46..fdd0411203 100644 --- a/src/openrct2-ui/windows/EditorMain.cpp +++ b/src/openrct2-ui/windows/EditorMain.cpp @@ -62,5 +62,5 @@ rct_window* window_editor_main_open() */ static void window_editor_main_paint(rct_window* w, rct_drawpixelinfo* dpi) { - viewport_render(dpi, w->viewport, dpi->x, dpi->y, dpi->x + dpi->width, dpi->y + dpi->height); + viewport_render(dpi, w->viewport, { { dpi->x, dpi->y }, { dpi->x + dpi->width, dpi->y + dpi->height } }); } diff --git a/src/openrct2-ui/windows/Main.cpp b/src/openrct2-ui/windows/Main.cpp index 30e6fe8c8a..564cf4f21c 100644 --- a/src/openrct2-ui/windows/Main.cpp +++ b/src/openrct2-ui/windows/Main.cpp @@ -60,5 +60,5 @@ rct_window* window_main_open() */ void window_main_paint(rct_window* w, rct_drawpixelinfo* dpi) { - viewport_render(dpi, w->viewport, dpi->x, dpi->y, dpi->x + dpi->width, dpi->y + dpi->height); + viewport_render(dpi, w->viewport, { { dpi->x, dpi->y }, { dpi->x + dpi->width, dpi->y + dpi->height } }); } diff --git a/src/openrct2/cmdline/BenchSpriteSort.cpp b/src/openrct2/cmdline/BenchSpriteSort.cpp index c7dcd8f0da..65c03e3f90 100644 --- a/src/openrct2/cmdline/BenchSpriteSort.cpp +++ b/src/openrct2/cmdline/BenchSpriteSort.cpp @@ -126,7 +126,7 @@ static std::vector extract_paint_session(std::string_view dpi.bits = static_cast(malloc(dpi.width * dpi.height)); log_info("Obtaining sprite data..."); - viewport_render(&dpi, &viewport, 0, 0, viewport.width, viewport.height, &sessions); + viewport_render(&dpi, &viewport, { { 0, 0 }, { viewport.width, viewport.height } }, &sessions); free(dpi.bits); drawing_engine_dispose(); diff --git a/src/openrct2/interface/Screenshot.cpp b/src/openrct2/interface/Screenshot.cpp index 8d784d4fd9..b0f5c3a5b2 100644 --- a/src/openrct2/interface/Screenshot.cpp +++ b/src/openrct2/interface/Screenshot.cpp @@ -373,7 +373,7 @@ static void RenderViewport(IDrawingEngine* drawingEngine, const rct_viewport& vi drawingEngine = tempDrawingEngine.get(); } dpi.DrawingEngine = drawingEngine; - viewport_render(&dpi, &viewport, 0, 0, viewport.width, viewport.height); + viewport_render(&dpi, &viewport, { { 0, 0 }, { viewport.width, viewport.height } }); } void screenshot_giant() diff --git a/src/openrct2/interface/Viewport.cpp b/src/openrct2/interface/Viewport.cpp index 17b610dcba..3b494b8a72 100644 --- a/src/openrct2/interface/Viewport.cpp +++ b/src/openrct2/interface/Viewport.cpp @@ -217,13 +217,13 @@ void viewport_remove(rct_viewport* viewport) _viewports.erase(it); } -void viewports_invalidate(int32_t left, int32_t top, int32_t right, int32_t bottom, int32_t maxZoom) +void viewports_invalidate(const ScreenRect& screenRect, int32_t maxZoom) { for (auto& vp : _viewports) { if (maxZoom == -1 || vp.zoom <= maxZoom) { - viewport_invalidate(&vp, left, top, right, bottom); + viewport_invalidate(&vp, screenRect); } } } @@ -792,45 +792,43 @@ void viewport_update_smart_vehicle_follow(rct_window* window) * ebp: bottom */ void viewport_render( - rct_drawpixelinfo* dpi, const rct_viewport* viewport, int32_t left, int32_t top, int32_t right, int32_t bottom, + rct_drawpixelinfo* dpi, const rct_viewport* viewport, const ScreenRect& screenRect, std::vector* sessions) { - if (right <= viewport->pos.x) + auto [topLeft, bottomRight] = screenRect; + + if (bottomRight.x <= viewport->pos.x) return; - if (bottom <= viewport->pos.y) + if (bottomRight.y <= viewport->pos.y) return; - if (left >= viewport->pos.x + viewport->width) + if (topLeft.x >= viewport->pos.x + viewport->width) return; - if (top >= viewport->pos.y + viewport->height) + if (topLeft.y >= viewport->pos.y + viewport->height) return; #ifdef DEBUG_SHOW_DIRTY_BOX - int32_t l = left, t = top, r = right, b = bottom; + const auto dirtyBoxTopLeft = topLeft; + const auto dirtyBoxTopRight = bottomRight - ScreenCoordsXY{ 1, 1 }; #endif - left = std::max(left - viewport->pos.x, 0); - right = std::min(right - viewport->pos.x, viewport->width); - top = std::max(top - viewport->pos.y, 0); - bottom = std::min(bottom - viewport->pos.y, viewport->height); + topLeft -= viewport->pos; + topLeft = ScreenCoordsXY{ + std::max(topLeft.x, 0) * viewport->zoom, + std::max(topLeft.y, 0) * viewport->zoom, + } + viewport->viewPos; - left = left * viewport->zoom; - right = right * viewport->zoom; - top = top * viewport->zoom; - bottom = bottom * viewport->zoom; + bottomRight -= viewport->pos; + bottomRight = ScreenCoordsXY{ + std::min(bottomRight.x, viewport->width) * viewport->zoom, + std::min(bottomRight.y, viewport->height) * viewport->zoom, + } + viewport->viewPos; - left += viewport->viewPos.x; - right += viewport->viewPos.x; - top += viewport->viewPos.y; - bottom += viewport->viewPos.y; - - viewport_paint(viewport, dpi, left, top, right, bottom, sessions); + viewport_paint(viewport, dpi, { topLeft, bottomRight }, sessions); #ifdef DEBUG_SHOW_DIRTY_BOX + // FIXME g_viewport_list doesn't exist anymore if (viewport != g_viewport_list) - { - gfx_fill_rect_inset(dpi, l, t, r - 1, b - 1, 0x2, INSET_RECT_F_30); - return; - } + gfx_fill_rect_inset(dpi, { dirtyBoxTopLeft, dirtyBoxTopRight }, 0x2, INSET_RECT_F_30); #endif } @@ -945,32 +943,33 @@ static void viewport_paint_column(paint_session* session) * ebp: bottom */ void viewport_paint( - const rct_viewport* viewport, rct_drawpixelinfo* dpi, int32_t left, int32_t top, int32_t right, int32_t bottom, + const rct_viewport* viewport, rct_drawpixelinfo* dpi, const ScreenRect& screenRect, std::vector* recorded_sessions) { uint32_t viewFlags = viewport->flags; - uint32_t width = right - left; - uint32_t height = bottom - top; + uint32_t width = screenRect.GetWidth(); + uint32_t height = screenRect.GetHeight(); uint32_t bitmask = viewport->zoom >= 0 ? 0xFFFFFFFF & (0xFFFFFFFF * viewport->zoom) : 0xFFFFFFFF; + ScreenCoordsXY topLeft = screenRect.Point1; width &= bitmask; height &= bitmask; - left &= bitmask; - top &= bitmask; + topLeft.x &= bitmask; + topLeft.y &= bitmask; - auto x = left - static_cast(viewport->viewPos.x & bitmask); + auto x = topLeft.x - static_cast(viewport->viewPos.x & bitmask); x = x / viewport->zoom; x += viewport->pos.x; - auto y = top - static_cast(viewport->viewPos.y & bitmask); + auto y = topLeft.y - static_cast(viewport->viewPos.y & bitmask); y = y / viewport->zoom; y += viewport->pos.y; rct_drawpixelinfo dpi1; dpi1.DrawingEngine = dpi->DrawingEngine; dpi1.bits = dpi->bits + (x - dpi->x) + ((y - dpi->y) * (dpi->width + dpi->pitch)); - dpi1.x = left; - dpi1.y = top; + dpi1.x = topLeft.x; + dpi1.y = topLeft.y; dpi1.width = width; dpi1.height = height; dpi1.pitch = (dpi->width + dpi->pitch) - (width / viewport->zoom); @@ -1150,7 +1149,7 @@ std::optional screen_pos_to_map_pos(const ScreenCoordsXY& screenCoords void rct_viewport::Invalidate() const { - viewport_invalidate(this, viewPos.x, viewPos.y, viewPos.x + view_width, viewPos.y + view_height); + viewport_invalidate(this, { viewPos, viewPos + ScreenCoordsXY{ view_width, view_height } }); } CoordsXY viewport_coord_to_map_coord(const ScreenCoordsXY& coords, int32_t z) @@ -1742,9 +1741,9 @@ InteractionInfo get_map_coordinates_from_pos_window(rct_window* window, const Sc } /** - * Left, top, right and bottom represent 2D map coordinates at zoom 0. + * screenRect represents 2D map coordinates at zoom 0. */ -void viewport_invalidate(const rct_viewport* viewport, int32_t left, int32_t top, int32_t right, int32_t bottom) +void viewport_invalidate(const rct_viewport* viewport, const ScreenRect& screenRect) { // if unknown viewport visibility, use the containing window to discover the status if (viewport->visibility == VisibilityCache::Unknown) @@ -1764,31 +1763,23 @@ void viewport_invalidate(const rct_viewport* viewport, int32_t left, int32_t top if (viewport->visibility == VisibilityCache::Covered) return; - int32_t viewportLeft = viewport->viewPos.x; - int32_t viewportTop = viewport->viewPos.y; - int32_t viewportRight = viewport->viewPos.x + viewport->view_width; - int32_t viewportBottom = viewport->viewPos.y + viewport->view_height; - if (right > viewportLeft && bottom > viewportTop) + auto [topLeft, bottomRight] = screenRect; + const auto [viewportRight, viewportBottom] = viewport->viewPos + + ScreenCoordsXY{ viewport->view_width, viewport->view_height }; + + if (bottomRight.x > viewport->viewPos.x && bottomRight.y > viewport->viewPos.y) { - left = std::max(left, viewportLeft); - top = std::max(top, viewportTop); - right = std::min(right, viewportRight); - bottom = std::min(bottom, viewportBottom); + topLeft = { std::max(topLeft.x, viewport->viewPos.x), std::max(topLeft.y, viewport->viewPos.y) }; + topLeft -= viewport->viewPos; + topLeft = { topLeft.x / viewport->zoom, topLeft.y / viewport->zoom }; + topLeft += viewport->pos; - left -= viewportLeft; - top -= viewportTop; - right -= viewportLeft; - bottom -= viewportTop; - left = left / viewport->zoom; - top = top / viewport->zoom; - right = right / viewport->zoom; - bottom = bottom / viewport->zoom; - left += viewport->pos.x; - top += viewport->pos.y; - right += viewport->pos.x; - bottom += viewport->pos.y; + bottomRight = { std::max(bottomRight.x, viewportRight), std::max(bottomRight.y, viewportBottom) }; + bottomRight -= viewport->viewPos; + bottomRight = { bottomRight.x / viewport->zoom, bottomRight.y / viewport->zoom }; + bottomRight += viewport->pos; - gfx_set_dirty_blocks({ { left, top }, { right, bottom } }); + gfx_set_dirty_blocks({ topLeft, bottomRight }); } } diff --git a/src/openrct2/interface/Viewport.h b/src/openrct2/interface/Viewport.h index 697eb65510..d97b8a544f 100644 --- a/src/openrct2/interface/Viewport.h +++ b/src/openrct2/interface/Viewport.h @@ -106,7 +106,7 @@ void viewport_init_all(); std::optional centre_2d_coordinates(const CoordsXYZ& loc, rct_viewport* viewport); void viewport_create(rct_window* w, const ScreenCoordsXY& screenCoords, int32_t width, int32_t height, const Focus& focus); void viewport_remove(rct_viewport* viewport); -void viewports_invalidate(int32_t left, int32_t top, int32_t right, int32_t bottom, int32_t maxZoom = -1); +void viewports_invalidate(const ScreenRect& screenRect, int32_t maxZoom = -1); void viewport_update_position(rct_window* window); void viewport_update_sprite_follow(rct_window* window); void viewport_update_smart_sprite_follow(rct_window* window); @@ -114,10 +114,10 @@ void viewport_update_smart_guest_follow(rct_window* window, const Guest* peep); void viewport_update_smart_staff_follow(rct_window* window, const Staff* peep); void viewport_update_smart_vehicle_follow(rct_window* window); void viewport_render( - rct_drawpixelinfo* dpi, const rct_viewport* viewport, int32_t left, int32_t top, int32_t right, int32_t bottom, + rct_drawpixelinfo* dpi, const rct_viewport* viewport, const ScreenRect& screenRect, std::vector* sessions = nullptr); void viewport_paint( - const rct_viewport* viewport, rct_drawpixelinfo* dpi, int32_t left, int32_t top, int32_t right, int32_t bottom, + const rct_viewport* viewport, rct_drawpixelinfo* dpi, const ScreenRect& screenRect, std::vector* sessions = nullptr); CoordsXYZ viewport_adjust_for_map_height(const ScreenCoordsXY& startCoords); @@ -146,7 +146,7 @@ bool ViewportInteractionRightClick(const ScreenCoordsXY& screenCoords); CoordsXY ViewportInteractionGetTileStartAtCursor(const ScreenCoordsXY& screenCoords); -void viewport_invalidate(const rct_viewport* viewport, int32_t left, int32_t top, int32_t right, int32_t bottom); +void viewport_invalidate(const rct_viewport* viewport, const ScreenRect& screenRect); std::optional screen_get_map_xy(const ScreenCoordsXY& screenCoords, rct_viewport** viewport); std::optional screen_get_map_xy_with_z(const ScreenCoordsXY& screenCoords, int32_t z); diff --git a/src/openrct2/interface/Window.cpp b/src/openrct2/interface/Window.cpp index 663fcec783..9d7d5420f5 100644 --- a/src/openrct2/interface/Window.cpp +++ b/src/openrct2/interface/Window.cpp @@ -1246,7 +1246,7 @@ static void window_draw_single(rct_drawpixelinfo* dpi, rct_window* w, int32_t le */ void window_draw_viewport(rct_drawpixelinfo* dpi, rct_window* w) { - viewport_render(dpi, w->viewport, dpi->x, dpi->y, dpi->x + dpi->width, dpi->y + dpi->height); + viewport_render(dpi, w->viewport, { { dpi->x, dpi->y }, { dpi->x + dpi->width, dpi->y + dpi->height } }); } void window_set_position(rct_window* w, const ScreenCoordsXY& screenCoords) diff --git a/src/openrct2/ride/TrackDesign.cpp b/src/openrct2/ride/TrackDesign.cpp index 5c33e6bd00..4e7bef98d2 100644 --- a/src/openrct2/ride/TrackDesign.cpp +++ b/src/openrct2/ride/TrackDesign.cpp @@ -2147,22 +2147,13 @@ void track_design_draw_preview(TrackDesign* td6, uint8_t* pixels) auto drawingEngine = std::make_unique(GetContext()->GetUiContext()); dpi.DrawingEngine = drawingEngine.get(); - CoordsXY offset = { size_x / 2, size_y / 2 }; + const ScreenCoordsXY offset = { size_x / 2, size_y / 2 }; for (uint8_t i = 0; i < 4; i++) { gCurrentRotation = i; - auto screenCoords = translate_3d_to_2d_with_z(i, centre); - screenCoords.x -= offset.x; - screenCoords.y -= offset.y; - - int32_t left = screenCoords.x; - int32_t top = screenCoords.y; - int32_t right = left + size_x; - int32_t bottom = top + size_y; - - view.viewPos = { left, top }; - viewport_paint(&view, &dpi, left, top, right, bottom); + view.viewPos = translate_3d_to_2d_with_z(i, centre) - offset; + viewport_paint(&view, &dpi, { view.viewPos, view.viewPos + ScreenCoordsXY{ size_x, size_y } }); dpi.bits += TRACK_PREVIEW_IMAGE_SIZE; } diff --git a/src/openrct2/world/Map.cpp b/src/openrct2/world/Map.cpp index b50ed72521..87f6fe8f71 100644 --- a/src/openrct2/world/Map.cpp +++ b/src/openrct2/world/Map.cpp @@ -1161,7 +1161,7 @@ void map_invalidate_selection_rect() bottom += 32; top -= 32 + 2080; - viewports_invalidate(left, top, right, bottom); + viewports_invalidate({ { left, top }, { right, bottom } }); } static size_t CountElementsOnTile(const CoordsXY& loc) @@ -1813,7 +1813,7 @@ static void map_invalidate_tile_under_zoom(int32_t x, int32_t y, int32_t z0, int x2 = screenCoord.x + 32; y2 = screenCoord.y + 32 - z0; - viewports_invalidate(x1, y1, x2, y2, maxZoom); + viewports_invalidate({ { x1, y1 }, { x2, y2 } }, maxZoom); } /** @@ -1874,7 +1874,7 @@ void map_invalidate_region(const CoordsXY& mins, const CoordsXY& maxs) bottom += 32; top -= 32 + 2080; - viewports_invalidate(left, top, right, bottom); + viewports_invalidate({ { left, top }, { right, bottom } }); } int32_t map_get_tile_side(const CoordsXY& mapPos) diff --git a/src/openrct2/world/Sprite.cpp b/src/openrct2/world/Sprite.cpp index 15fa2f1e8d..4454cbbea0 100644 --- a/src/openrct2/world/Sprite.cpp +++ b/src/openrct2/world/Sprite.cpp @@ -191,7 +191,7 @@ void EntityBase::Invalidate() break; } - viewports_invalidate(SpriteRect.GetLeft(), SpriteRect.GetTop(), SpriteRect.GetRight(), SpriteRect.GetBottom(), maxZoom); + viewports_invalidate(SpriteRect, maxZoom); } static void ResetEntityLists()