Refactor Viewport.cpp to use ScreenRect (#15790)

This commit is contained in:
Sijmen 2021-10-27 05:13:38 +02:00 committed by GitHub
parent ea3463399f
commit cec8447c6f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 67 additions and 85 deletions

View File

@ -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 } });
}

View File

@ -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 } });
}

View File

@ -126,7 +126,7 @@ static std::vector<RecordedPaintSession> extract_paint_session(std::string_view
dpi.bits = static_cast<uint8_t*>(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();

View File

@ -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()

View File

@ -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<RecordedPaintSession>* 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<int32_t>(left - viewport->pos.x, 0);
right = std::min<int32_t>(right - viewport->pos.x, viewport->width);
top = std::max<int32_t>(top - viewport->pos.y, 0);
bottom = std::min<int32_t>(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<RecordedPaintSession>* 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<int32_t>(viewport->viewPos.x & bitmask);
auto x = topLeft.x - static_cast<int32_t>(viewport->viewPos.x & bitmask);
x = x / viewport->zoom;
x += viewport->pos.x;
auto y = top - static_cast<int32_t>(viewport->viewPos.y & bitmask);
auto y = topLeft.y - static_cast<int32_t>(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<CoordsXY> 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 });
}
}

View File

@ -106,7 +106,7 @@ void viewport_init_all();
std::optional<ScreenCoordsXY> 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<RecordedPaintSession>* 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<RecordedPaintSession>* 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<CoordsXY> screen_get_map_xy(const ScreenCoordsXY& screenCoords, rct_viewport** viewport);
std::optional<CoordsXY> screen_get_map_xy_with_z(const ScreenCoordsXY& screenCoords, int32_t z);

View File

@ -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)

View File

@ -2147,22 +2147,13 @@ void track_design_draw_preview(TrackDesign* td6, uint8_t* pixels)
auto drawingEngine = std::make_unique<X8DrawingEngine>(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;
}

View File

@ -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)

View File

@ -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()