Render an overlay of the measurement tool area in viewport map mode

See: #388
pull/390/head
Jonathan G Rennison 2 years ago
parent 981104e308
commit 6107aa9e5c

@ -3203,6 +3203,54 @@ static void ViewportMapDrawScrollingViewportBox(const Viewport * const vp)
}
}
static void ViewportMapDrawSelection(const Viewport * const vp)
{
DrawPixelInfo *old_dpi = _cur_dpi;
_cur_dpi = &_dpi_for_text;
auto draw_line = [&](Point from_pt, Point to_pt) {
GfxDrawLine(from_pt.x, from_pt.y, to_pt.x, to_pt.y, PC_WHITE, 2, 0);
};
Point start_coord = RemapCoords2(_thd.selstart.x, _thd.selstart.y);
Point end_coord = RemapCoords2(_thd.selend.x, _thd.selend.y);
Point start_effective = InverseRemapCoords(start_coord.x, start_coord.y);
Point end_effective = InverseRemapCoords(end_coord.x, end_coord.y);
auto get_corner = [&](int pos_x, int pos_y) -> Point {
Point pt = RemapCoords(pos_x, pos_y, 0);
return { UnScaleByZoom(pt.x, vp->zoom), UnScaleByZoom(pt.y, vp->zoom) };
};
Point start_pt = get_corner(start_effective.x, start_effective.y);
Point end_pt = get_corner(end_effective.x, end_effective.y);
Point mid1_pt = get_corner(start_effective.x, end_effective.y);
Point mid2_pt = get_corner(end_effective.x, start_effective.y);
draw_line(start_pt, mid1_pt);
draw_line(mid1_pt, end_pt);
draw_line(end_pt, mid2_pt);
draw_line(mid2_pt, start_pt);
if (BlitterFactory::GetCurrentBlitter()->GetScreenDepth() == 32) {
static std::vector<Point> points(4);
points[0] = start_pt;
points[1] = mid1_pt;
points[2] = end_pt;
points[3] = mid2_pt;
GfxFillPolygon(points, 0, FILLRECT_FUNCTOR, [](void *dst, int count) {
uint32 *buf = reinterpret_cast<uint32 *>(dst);
for (int i = 0; i < count; i++) {
PixelBlend(buf + i, 0x40FCFCFC);
}
});
} else {
draw_line(start_pt, end_pt);
}
_cur_dpi = old_dpi;
}
template <bool is_32bpp>
static void ViewportMapDrawBridgeTunnel(Viewport * const vp, const TunnelBridgeToMap * const tbtm, const int z,
const bool is_tunnel, const int w, const int h, Blitter * const blitter)
@ -3490,6 +3538,7 @@ void ViewportDoDraw(Viewport *vp, int left, int top, int right, int bottom)
}
ViewportMapDrawVehicles(&_vd.dpi, vp);
if (_scrolling_viewport && _settings_client.gui.show_scrolling_viewport_on_map) ViewportMapDrawScrollingViewportBox(vp);
if (unlikely(_thd.place_mode == (HT_SPECIAL | HT_MAP) && (_thd.drawstyle & HT_DRAG_MASK) == HT_RECT && _thd.select_proc == DDSP_MEASURE)) ViewportMapDrawSelection(vp);
if (vp->zoom < ZOOM_LVL_OUT_256X) ViewportAddKdtreeSigns(&_vd.dpi, true);
} else {
/* Classic rendering. */
@ -4143,14 +4192,16 @@ static void SetSelectionTilesDirty()
int bot_x = top_x; // coordinates of bottom dirty tile
int bot_y = top_y;
const bool conservative_mode = (_thd.place_mode & HT_MAP) && !_viewport_vehicle_map_redraw_rects.empty();
do {
/* topmost dirty point */
TileIndex top_tile = TileVirtXY(top_x, top_y);
Point top = RemapCoords(top_x, top_y, GetTileMaxPixelZ(top_tile));
Point top = RemapCoords(top_x, top_y, conservative_mode ? _settings_game.construction.map_height_limit * TILE_HEIGHT : GetTileMaxPixelZ(top_tile));
/* bottommost point */
TileIndex bottom_tile = TileVirtXY(bot_x, bot_y);
Point bot = RemapCoords(bot_x + TILE_SIZE, bot_y + TILE_SIZE, GetTilePixelZ(bottom_tile)); // bottommost point
Point bot = RemapCoords(bot_x + TILE_SIZE, bot_y + TILE_SIZE, conservative_mode ? 0 : GetTilePixelZ(bottom_tile)); // bottommost point
/* the 'x' coordinate of 'top' and 'bot' is the same (and always in the same distance from tile middle),
* tile height/slope affects only the 'y' on-screen coordinate! */
@ -4160,10 +4211,11 @@ static void SetSelectionTilesDirty()
int r = top.x + TILE_PIXELS * ZOOM_LVL_BASE; // 'x' coordinate of right side of the dirty rectangle
int b = bot.y; // 'y' coordinate of bottom side of the dirty rectangle
static const int OVERLAY_WIDTH = 4 * ZOOM_LVL_BASE; // part of selection sprites is drawn outside the selected area (in particular: terraforming)
static const int OVERLAY_WIDTH = conservative_mode ? 2 << ZOOM_LVL_END : 4 * ZOOM_LVL_BASE; // part of selection sprites is drawn outside the selected area (in particular: terraforming)
/* For halftile foundations on SLOPE_STEEP_S the sprite extents some more towards the top */
MarkAllViewportsDirty(l - OVERLAY_WIDTH, t - OVERLAY_WIDTH - TILE_HEIGHT * ZOOM_LVL_BASE, r + OVERLAY_WIDTH, b + OVERLAY_WIDTH, VMDF_NOT_MAP_MODE);
ViewportMarkDirtyFlags mode = (_thd.place_mode & HT_MAP) ? VMDF_NOT_LANDSCAPE : VMDF_NOT_MAP_MODE;
MarkAllViewportsDirty(l - OVERLAY_WIDTH, t - OVERLAY_WIDTH - TILE_HEIGHT * ZOOM_LVL_BASE, r + OVERLAY_WIDTH, b + OVERLAY_WIDTH, mode);
/* haven't we reached the topmost tile yet? */
if (top_x != x_start) {

Loading…
Cancel
Save