diff options
-rw-r--r-- | src/smallmap_gui.cpp | 47 | ||||
-rw-r--r-- | src/smallmap_gui.h | 1 | ||||
-rw-r--r-- | src/viewport.cpp | 28 | ||||
-rw-r--r-- | src/viewport_func.h | 1 |
4 files changed, 26 insertions, 51 deletions
diff --git a/src/smallmap_gui.cpp b/src/smallmap_gui.cpp index dea0caa39..b9bbe4e25 100644 --- a/src/smallmap_gui.cpp +++ b/src/smallmap_gui.cpp @@ -900,30 +900,6 @@ void SmallMapWindow::DrawTowns(const DrawPixelInfo *dpi) const } /** - * Convert a coordinate of the viewport to essentially a tile on the map, - * taking care of the different location due to height. - * @param viewport_coord The coordinate in the viewport. - * @return The tile location. - */ -Point SmallMapWindow::GetSmallMapCoordIncludingHeight(Point viewport_coord) const -{ - /* First find out which tile would be there if we ignore height */ - Point pt = InverseRemapCoords(viewport_coord.x, viewport_coord.y); - Point pt_without_height = {pt.x / TILE_SIZE, pt.y / TILE_SIZE}; - - /* Problem: There are mountains. So the tile actually displayed at the given position - * might be the high mountain of 30 tiles south. - * Unfortunately, there is no closed formula for finding such a tile. - * We call GetRowAtTile originally implemented for the viewport code, which performs - * a interval search. For details, see its documentation. */ - int row_without_height = pt_without_height.x + pt_without_height.y; - int row_with_height = GetRowAtTile(viewport_coord.y, pt_without_height, false); - int row_offset = row_with_height - row_without_height; - Point pt_with_height = {pt_without_height.x + row_offset / 2, pt_without_height.y + row_offset / 2}; - return pt_with_height; -} - -/** * Adds map indicators to the smallmap. */ void SmallMapWindow::DrawMapIndicators() const @@ -931,15 +907,13 @@ void SmallMapWindow::DrawMapIndicators() const /* Find main viewport. */ const ViewPort *vp = FindWindowById(WC_MAIN_WINDOW, 0)->viewport; - Point upper_left_viewport_coord = {vp->virtual_left, vp->virtual_top}; - Point upper_left_small_map_coord = GetSmallMapCoordIncludingHeight(upper_left_viewport_coord); - Point upper_left = this->RemapTile(upper_left_small_map_coord.x, upper_left_small_map_coord.y); + Point upper_left_smallmap_coord = TranslateXYToTileCoord(vp, vp->left, vp->top, false); + Point lower_right_smallmap_coord = TranslateXYToTileCoord(vp, vp->left + vp->width - 1, vp->top + vp->height - 1, false); + + Point upper_left = this->RemapTile(upper_left_smallmap_coord.x / (int)TILE_SIZE, upper_left_smallmap_coord.y / (int)TILE_SIZE); upper_left.x -= this->subscroll; - Point lower_right_viewport_coord = {vp->virtual_left + vp->virtual_width, vp->virtual_top + vp->virtual_height}; - Point lower_right_smallmap_coord = GetSmallMapCoordIncludingHeight(lower_right_viewport_coord); - Point lower_right = this->RemapTile(lower_right_smallmap_coord.x, lower_right_smallmap_coord.y); - /* why do we do this? in my tests subscroll was zero */ + Point lower_right = this->RemapTile(lower_right_smallmap_coord.x / (int)TILE_SIZE, lower_right_smallmap_coord.y / (int)TILE_SIZE); lower_right.x -= this->subscroll; SmallMapWindow::DrawVertMapIndicator(upper_left.x, upper_left.y, lower_right.y); @@ -1662,19 +1636,12 @@ void SmallMapWindow::SetNewScroll(int sx, int sy, int sub) */ void SmallMapWindow::SmallMapCenterOnCurrentPos() { - /* Goal: Given the viewport coordinates of the middle of the map window, find - * out which tile is displayed there. */ - - /* First find out which tile would be there if we ignore height */ const ViewPort *vp = FindWindowById(WC_MAIN_WINDOW, 0)->viewport; - Point viewport_center = {vp->virtual_left + vp->virtual_width / 2, vp->virtual_top + vp->virtual_height / 2}; - Point pt_with_height = GetSmallMapCoordIncludingHeight(viewport_center); - - /* And finally scroll to that position. */ + Point viewport_center = TranslateXYToTileCoord(vp, vp->left + vp->width / 2, vp->top + vp->height / 2); int sub; const NWidgetBase *wid = this->GetWidget<NWidgetBase>(WID_SM_MAP); - Point sxy = this->ComputeScroll(pt_with_height.x, pt_with_height.y, + Point sxy = this->ComputeScroll(viewport_center.x / (int)TILE_SIZE, viewport_center.y / (int)TILE_SIZE, max(0, (int)wid->current_x / 2 - 2), wid->current_y / 2, &sub); this->SetNewScroll(sxy.x, sxy.y, sub); this->SetDirty(); diff --git a/src/smallmap_gui.h b/src/smallmap_gui.h index 7a4805841..2903544a6 100644 --- a/src/smallmap_gui.h +++ b/src/smallmap_gui.h @@ -157,7 +157,6 @@ protected: void DrawSmallMapColumn(void *dst, uint xc, uint yc, int pitch, int reps, int start_pos, int end_pos, Blitter *blitter) const; void DrawVehicles(const DrawPixelInfo *dpi, Blitter *blitter) const; void DrawTowns(const DrawPixelInfo *dpi) const; - Point GetSmallMapCoordIncludingHeight(Point viewport_coord) const; void DrawSmallMap(DrawPixelInfo *dpi) const; Point RemapTile(int tile_x, int tile_y) const; diff --git a/src/viewport.cpp b/src/viewport.cpp index 796368114..3fc14fcc7 100644 --- a/src/viewport.cpp +++ b/src/viewport.cpp @@ -405,9 +405,10 @@ ViewPort *IsPtInWindowViewport(const Window *w, int x, int y) * @param vp Viewport that contains the (\a x, \a y) screen coordinate * @param x Screen x coordinate * @param y Screen y coordinate + * @param clamp_to_map Clamp the coordinate outside of the map to the closest tile within the map. * @return Tile coordinate */ -static Point TranslateXYToTileCoord(const ViewPort *vp, int x, int y) +Point TranslateXYToTileCoord(const ViewPort *vp, int x, int y, bool clamp_to_map) { Point pt; int a, b; @@ -425,13 +426,15 @@ static Point TranslateXYToTileCoord(const ViewPort *vp, int x, int y) a = y - x; b = y + x; - /* Bring the coordinates near to a valid range. This is mostly due to the - * tiles on the north side of the map possibly being drawn too high due to - * the extra height levels. So at the top we allow a number of extra tiles. - * This number is based on the tile height and pixels. */ - int extra_tiles = CeilDiv(_settings_game.construction.max_heightlevel * TILE_HEIGHT, TILE_PIXELS); - a = Clamp(a, -extra_tiles * TILE_SIZE, MapMaxX() * TILE_SIZE - 1); - b = Clamp(b, -extra_tiles * TILE_SIZE, MapMaxY() * TILE_SIZE - 1); + if (clamp_to_map) { + /* Bring the coordinates near to a valid range. This is mostly due to the + * tiles on the north side of the map possibly being drawn too high due to + * the extra height levels. So at the top we allow a number of extra tiles. + * This number is based on the tile height and pixels. */ + int extra_tiles = CeilDiv(_settings_game.construction.max_heightlevel * TILE_HEIGHT, TILE_PIXELS); + a = Clamp(a, -extra_tiles * TILE_SIZE, MapMaxX() * TILE_SIZE - 1); + b = Clamp(b, -extra_tiles * TILE_SIZE, MapMaxY() * TILE_SIZE - 1); + } /* (a, b) is the X/Y-world coordinate that belongs to (x,y) if the landscape would be completely flat on height 0. * Now find the Z-world coordinate by fix point iteration. @@ -448,8 +451,13 @@ static Point TranslateXYToTileCoord(const ViewPort *vp, int x, int y) for (int malus = 3; malus > 0; malus--) z = GetSlopePixelZ(Clamp(a + max(z, malus) - malus, min_coord, MapMaxX() * TILE_SIZE - 1), Clamp(b + max(z, malus) - malus, min_coord, MapMaxY() * TILE_SIZE - 1)) / 2; for (int i = 0; i < 5; i++) z = GetSlopePixelZ(Clamp(a + z, min_coord, MapMaxX() * TILE_SIZE - 1), Clamp(b + z, min_coord, MapMaxY() * TILE_SIZE - 1)) / 2; - pt.x = Clamp(a + z, min_coord, MapMaxX() * TILE_SIZE - 1); - pt.y = Clamp(b + z, min_coord, MapMaxY() * TILE_SIZE - 1); + if (clamp_to_map) { + pt.x = Clamp(a + z, min_coord, MapMaxX() * TILE_SIZE - 1); + pt.y = Clamp(b + z, min_coord, MapMaxY() * TILE_SIZE - 1); + } else { + pt.x = a + z; + pt.y = b + z; + } return pt; } diff --git a/src/viewport_func.h b/src/viewport_func.h index 8dbbc5945..3525fd6a2 100644 --- a/src/viewport_func.h +++ b/src/viewport_func.h @@ -25,6 +25,7 @@ void SetSelectionRed(bool); void DeleteWindowViewport(Window *w); void InitializeWindowViewport(Window *w, int x, int y, int width, int height, uint32 follow_flags, ZoomLevel zoom); ViewPort *IsPtInWindowViewport(const Window *w, int x, int y); +Point TranslateXYToTileCoord(const ViewPort *vp, int x, int y, bool clamp_to_map = true); Point GetTileBelowCursor(); void UpdateViewportPosition(Window *w); |