diff --git a/src/openrct2-ui/interface/ViewportInteraction.cpp b/src/openrct2-ui/interface/ViewportInteraction.cpp index e9287a21e4..7cd7bcddf1 100644 --- a/src/openrct2-ui/interface/ViewportInteraction.cpp +++ b/src/openrct2-ui/interface/ViewportInteraction.cpp @@ -693,8 +693,7 @@ static Peep* viewport_interaction_get_closest_peep(ScreenCoordsXY screenCoords, if (viewport == nullptr || viewport->zoom >= 2) return nullptr; - screenCoords.x = ((screenCoords.x - viewport->pos.x) * viewport->zoom) + viewport->viewPos.x; - screenCoords.y = ((screenCoords.y - viewport->pos.y) * viewport->zoom) + viewport->viewPos.y; + auto viewportCoords = viewport->ScreenToViewportCoord(screenCoords); Peep* closestPeep = nullptr; auto closestDistance = std::numeric_limits::max(); @@ -703,8 +702,8 @@ static Peep* viewport_interaction_get_closest_peep(ScreenCoordsXY screenCoords, if (peep->sprite_left == LOCATION_NULL) continue; - auto distance = abs(((peep->sprite_left + peep->sprite_right) / 2) - screenCoords.x) - + abs(((peep->sprite_top + peep->sprite_bottom) / 2) - screenCoords.y); + auto distance = abs(((peep->sprite_left + peep->sprite_right) / 2) - viewportCoords.x) + + abs(((peep->sprite_top + peep->sprite_bottom) / 2) - viewportCoords.y); if (distance > maxDistance) continue; @@ -748,7 +747,7 @@ CoordsXY sub_68A15E(const ScreenCoordsXY& screenCoords) waterHeight = info.Element->AsSurface()->GetWaterHeight(); } - auto initialVPPos = screen_coord_to_viewport_coord(viewport, screenCoords); + auto initialVPPos = viewport->ScreenToViewportCoord(screenCoords); CoordsXY mapPos = initialPos + CoordsXY{ 16, 16 }; for (int32_t i = 0; i < 5; i++) diff --git a/src/openrct2/audio/Audio.cpp b/src/openrct2/audio/Audio.cpp index 317aafb9b5..e7651a8422 100644 --- a/src/openrct2/audio/Audio.cpp +++ b/src/openrct2/audio/Audio.cpp @@ -223,12 +223,11 @@ namespace OpenRCT2::Audio if (viewport->flags & VIEWPORT_FLAG_SOUND_ON) { int16_t vx = pos2.x - viewport->viewPos.x; - int16_t vy = pos2.y - viewport->viewPos.y; params.pan = viewport->pos.x + (vx / viewport->zoom); params.volume = SoundVolumeAdjust[static_cast(soundId)] + ((-1024 * viewport->zoom - 1) * (1 << volumeDown)) + 1; - if (vy < 0 || vy >= viewport->view_height || vx < 0 || vx >= viewport->view_width || params.volume < -10000) + if (!viewport->Contains(pos2) || params.volume < -10000) { params.in_range = false; return params; diff --git a/src/openrct2/interface/Viewport.cpp b/src/openrct2/interface/Viewport.cpp index 15a431c001..5214ec53a3 100644 --- a/src/openrct2/interface/Viewport.cpp +++ b/src/openrct2/interface/Viewport.cpp @@ -1079,11 +1079,11 @@ std::optional screen_pos_to_map_pos(const ScreenCoordsXY& screenCoords return { mapCoords->ToTileStart() }; } -ScreenCoordsXY screen_coord_to_viewport_coord(rct_viewport* viewport, const ScreenCoordsXY& screenCoords) +[[nodiscard]] ScreenCoordsXY rct_viewport::ScreenToViewportCoord(const ScreenCoordsXY& screenCoords) const { ScreenCoordsXY ret; - ret.x = ((screenCoords.x - viewport->pos.x) * viewport->zoom) + viewport->viewPos.x; - ret.y = ((screenCoords.y - viewport->pos.y) * viewport->zoom) + viewport->viewPos.y; + ret.x = ((screenCoords.x - pos.x) * zoom) + viewPos.x; + ret.y = ((screenCoords.y - pos.y) * zoom) + viewPos.y; return ret; } @@ -1746,12 +1746,10 @@ static rct_viewport* viewport_find_from_point(const ScreenCoordsXY& screenCoords if (viewport == nullptr) return nullptr; - if (screenCoords.x < viewport->pos.x || screenCoords.y < viewport->pos.y) - return nullptr; - if (screenCoords.x >= viewport->pos.x + viewport->width || screenCoords.y >= viewport->pos.y + viewport->height) - return nullptr; + if (viewport->ContainsScreen(screenCoords)) + return viewport; - return viewport; + return nullptr; } /** @@ -1781,7 +1779,7 @@ std::optional screen_get_map_xy(const ScreenCoordsXY& screenCoords, rc return std::nullopt; } - auto start_vp_pos = screen_coord_to_viewport_coord(myViewport, screenCoords); + auto start_vp_pos = myViewport->ScreenToViewportCoord(screenCoords); CoordsXY cursorMapPos = info.Loc.ToTileCentre(); // Iterates the cursor location to work out exactly where on the tile it is @@ -1811,7 +1809,7 @@ std::optional screen_get_map_xy_with_z(const ScreenCoordsXY& screenCoo return std::nullopt; } - auto vpCoords = screen_coord_to_viewport_coord(viewport, screenCoords); + auto vpCoords = viewport->ScreenToViewportCoord(screenCoords); auto mapPosition = viewport_coord_to_map_coord(vpCoords, z); if (!map_is_location_valid(mapPosition)) { diff --git a/src/openrct2/interface/Viewport.h b/src/openrct2/interface/Viewport.h index 55d6db150e..b40a81930f 100644 --- a/src/openrct2/interface/Viewport.h +++ b/src/openrct2/interface/Viewport.h @@ -136,7 +136,6 @@ void viewport_paint( CoordsXYZ viewport_adjust_for_map_height(const ScreenCoordsXY& startCoords); -ScreenCoordsXY screen_coord_to_viewport_coord(rct_viewport* viewport, const ScreenCoordsXY& screenCoords); CoordsXY viewport_coord_to_map_coord(const ScreenCoordsXY& coords, int32_t z); std::optional screen_pos_to_map_pos(const ScreenCoordsXY& screenCoords, int32_t* direction); diff --git a/src/openrct2/interface/Window.cpp b/src/openrct2/interface/Window.cpp index ff9ee63739..94b7f30cd8 100644 --- a/src/openrct2/interface/Window.cpp +++ b/src/openrct2/interface/Window.cpp @@ -948,7 +948,7 @@ void window_viewport_get_map_coords_by_cursor( auto mouseCoords = context_get_cursor_position_scaled(); // Compute map coordinate by mouse position. - auto viewportPos = screen_coord_to_viewport_coord(w->viewport, mouseCoords); + auto viewportPos = w->viewport->ScreenToViewportCoord(mouseCoords); auto coordsXYZ = viewport_adjust_for_map_height(viewportPos); auto mapCoords = viewport_coord_to_map_coord(viewportPos, coordsXYZ.z); *map_x = mapCoords.x; diff --git a/src/openrct2/interface/Window.h b/src/openrct2/interface/Window.h index e040aff8d5..772e32e160 100644 --- a/src/openrct2/interface/Window.h +++ b/src/openrct2/interface/Window.h @@ -147,6 +147,22 @@ struct rct_viewport ZoomLevel zoom; uint8_t var_11; VisibilityCache visibility; + + // Use this function on coordinates that are relative to the viewport zoom i.e. a peeps x, y position after transforming + // from its x, y, z + [[nodiscard]] constexpr bool Contains(const ScreenCoordsXY& vpos) const + { + return ( + vpos.y >= viewPos.y && vpos.y < viewPos.y + view_height && vpos.x >= viewPos.x && vpos.x < viewPos.x + view_width); + } + + // Use this function on coordinates that are relative to the screen that is been drawn i.e. the cursor position + [[nodiscard]] constexpr bool ContainsScreen(const ScreenCoordsXY& sPos) const + { + return (sPos.x >= pos.x && sPos.x < pos.x + width && sPos.y >= pos.y && sPos.y < pos.y + height); + } + + [[nodiscard]] ScreenCoordsXY ScreenToViewportCoord(const ScreenCoordsXY& screenCoord) const; }; /** diff --git a/src/openrct2/world/Footpath.cpp b/src/openrct2/world/Footpath.cpp index c956f40f14..842ce8091b 100644 --- a/src/openrct2/world/Footpath.cpp +++ b/src/openrct2/world/Footpath.cpp @@ -283,7 +283,7 @@ CoordsXY footpath_get_coordinates_from_pos(const ScreenCoordsXY& screenCoords, i } } - auto start_vp_pos = screen_coord_to_viewport_coord(viewport, screenCoords); + auto start_vp_pos = viewport->ScreenToViewportCoord(screenCoords); for (int32_t i = 0; i < 5; i++) {