Cache tunnel info in viewport map mode, to prevent render flicker.
If we see a tunnel during the usual tile scan, keep it in the cache until it is explicitly evicted by a clear tunnel tile action, or the cache is cleared at game init/load/shutdown. Select colours at the drawing rather than the cache-building stage. Bridges and tunnels are now stored/handled separately. The process for bridges is mostly unchanged.
This commit is contained in:
100
src/viewport.cpp
100
src/viewport.cpp
@@ -174,7 +174,8 @@ struct ViewportDrawer {
|
||||
ParentSpriteToDrawVector parent_sprites_to_draw;
|
||||
ParentSpriteToSortVector parent_sprites_to_sort; ///< Parent sprite pointer array used for sorting
|
||||
ChildScreenSpriteToDrawVector child_screen_sprites_to_draw;
|
||||
TunnelBridgeToMapVector tunnel_bridge_to_map;
|
||||
TunnelBridgeToMapVector tunnel_to_map;
|
||||
TunnelBridgeToMapVector bridge_to_map;
|
||||
|
||||
int *last_child;
|
||||
|
||||
@@ -1535,7 +1536,7 @@ static void ViewportMapStoreBridgeTunnel(const ViewPort * const vp, const TileIn
|
||||
if (!_legend_land_owners[_company_to_list_pos[o]].show_on_map) return;
|
||||
|
||||
/* Check if already stored */
|
||||
TunnelBridgeToMapVector * const tbtmv = &_vd.tunnel_bridge_to_map;
|
||||
TunnelBridgeToMapVector * const tbtmv = tile_is_tunnel ? &_vd.tunnel_to_map : &_vd.bridge_to_map;
|
||||
TunnelBridgeToMap *tbtm = tbtmv->Begin();
|
||||
const TunnelBridgeToMap * const tbtm_end = tbtmv->End();
|
||||
while (tbtm != tbtm_end) {
|
||||
@@ -1555,12 +1556,22 @@ static void ViewportMapStoreBridgeTunnel(const ViewPort * const vp, const TileIn
|
||||
tbtm->from_tile = tile;
|
||||
tbtm->to_tile = other_end;
|
||||
}
|
||||
}
|
||||
|
||||
if (vp->map_type == VPMT_OWNER && _settings_client.gui.use_owner_colour_for_tunnelbridge && o < MAX_COMPANIES) {
|
||||
const uint8 colour = _legend_land_owners[_company_to_list_pos[o]].colour;
|
||||
tbtm->colour = tile_is_tunnel ? _darken_colour[colour] : _lighten_colour[colour];
|
||||
} else
|
||||
tbtm->colour = tile_is_tunnel ? PC_BLACK : PC_VERY_LIGHT_YELLOW;
|
||||
void ViewportMapClearTunnelCache()
|
||||
{
|
||||
_vd.tunnel_to_map.Clear();
|
||||
}
|
||||
|
||||
void ViewportMapInvalidateTunnelCacheByTile(const TileIndex tile)
|
||||
{
|
||||
TunnelBridgeToMapVector * const tbtmv = &_vd.tunnel_to_map;
|
||||
for (TunnelBridgeToMap *tbtm = tbtmv->Begin(); tbtm != tbtmv->End(); tbtm++) {
|
||||
if (tbtm->from_tile == tile || tbtm->to_tile == tile) {
|
||||
tbtmv->Erase(tbtm);
|
||||
tbtm--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2098,8 +2109,8 @@ static inline void ViewportMapStoreBridgeAboveTile(const ViewPort * const vp, co
|
||||
if (!_settings_client.gui.show_bridges_on_map) return;
|
||||
|
||||
/* Check existing stored bridges */
|
||||
TunnelBridgeToMap *tbtm = _vd.tunnel_bridge_to_map.Begin();
|
||||
TunnelBridgeToMap *tbtm_end = _vd.tunnel_bridge_to_map.End();
|
||||
TunnelBridgeToMap *tbtm = _vd.bridge_to_map.Begin();
|
||||
TunnelBridgeToMap *tbtm_end = _vd.bridge_to_map.End();
|
||||
for (; tbtm != tbtm_end; ++tbtm) {
|
||||
if (!IsBridge(tbtm->from_tile)) continue;
|
||||
|
||||
@@ -2277,6 +2288,35 @@ static void ViewportMapDrawScrollingViewportBox(const ViewPort * const vp)
|
||||
|
||||
uint32 *_vp_map_line; ///< Buffer for drawing the map of a viewport.
|
||||
|
||||
static void ViewportMapDrawBridgeTunnel(const ViewPort * const vp, const TunnelBridgeToMap * const tbtm, const int z,
|
||||
const bool is_tunnel, const int w, const int h, Blitter * const blitter)
|
||||
{
|
||||
extern LegendAndColour _legend_land_owners[NUM_NO_COMPANY_ENTRIES + MAX_COMPANIES + 1];
|
||||
extern uint _company_to_list_pos[MAX_COMPANIES];
|
||||
|
||||
TileIndex tile = tbtm->from_tile;
|
||||
const Owner o = GetTileOwner(tile);
|
||||
if (!_legend_land_owners[_company_to_list_pos[o]].show_on_map) return;
|
||||
|
||||
uint8 colour;
|
||||
if (vp->map_type == VPMT_OWNER && _settings_client.gui.use_owner_colour_for_tunnelbridge && o < MAX_COMPANIES) {
|
||||
colour = _legend_land_owners[_company_to_list_pos[o]].colour;
|
||||
colour = is_tunnel ? _darken_colour[colour] : _lighten_colour[colour];
|
||||
} else {
|
||||
colour = is_tunnel ? PC_BLACK : PC_VERY_LIGHT_YELLOW;
|
||||
}
|
||||
|
||||
TileIndexDiff delta = TileOffsByDiagDir(GetTunnelBridgeDirection(tile));
|
||||
for (; tile != tbtm->to_tile; tile += delta) { // For each tile
|
||||
const Point pt = RemapCoords(TileX(tile) * TILE_SIZE, TileY(tile) * TILE_SIZE, z);
|
||||
const int x = UnScaleByZoomLower(pt.x - _vd.dpi.left, _vd.dpi.zoom);
|
||||
if (IsInsideMM(x, 0, w)) {
|
||||
const int y = UnScaleByZoomLower(pt.y - _vd.dpi.top, _vd.dpi.zoom);
|
||||
if (IsInsideMM(y, 0, h)) blitter->SetPixel(_vd.dpi.dst_ptr, x, y, colour);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Draw the map on a viewport. */
|
||||
template <bool is_32bpp, bool show_slope>
|
||||
void ViewportMapDraw(const ViewPort * const vp)
|
||||
@@ -2333,21 +2373,31 @@ void ViewportMapDraw(const ViewPort * const vp)
|
||||
b += incr_b;
|
||||
} while (++j < h);
|
||||
|
||||
/* Render bridges and tunnels */
|
||||
if (_vd.tunnel_bridge_to_map.Length() != 0) {
|
||||
const TunnelBridgeToMap * const tbtm_end = _vd.tunnel_bridge_to_map.End();
|
||||
for (const TunnelBridgeToMap *tbtm = _vd.tunnel_bridge_to_map.Begin(); tbtm != tbtm_end; tbtm++) { // For each bridge or tunnel
|
||||
TileIndex tile = tbtm->from_tile;
|
||||
const int z = (IsBridge(tile) ? GetBridgeHeight(tile) - 1 : GetTileZ(tile)) * TILE_HEIGHT;
|
||||
TileIndexDiff delta = TileOffsByDiagDir(GetTunnelBridgeDirection(tile));
|
||||
for (; tile != tbtm->to_tile; tile += delta) { // For each tile
|
||||
const Point pt = RemapCoords(TileX(tile) * TILE_SIZE, TileY(tile) * TILE_SIZE, z);
|
||||
const int x = UnScaleByZoomLower(pt.x - _vd.dpi.left, _vd.dpi.zoom);
|
||||
if (IsInsideMM(x, 0, w)) {
|
||||
const int y = UnScaleByZoomLower(pt.y - _vd.dpi.top, _vd.dpi.zoom);
|
||||
if (IsInsideMM(y, 0, h)) blitter->SetPixel(_vd.dpi.dst_ptr, x, y, tbtm->colour);
|
||||
}
|
||||
}
|
||||
/* Render tunnels */
|
||||
if (_settings_client.gui.show_tunnels_on_map && _vd.tunnel_to_map.Length() != 0) {
|
||||
const TunnelBridgeToMap * const tbtm_end = _vd.tunnel_to_map.End();
|
||||
for (const TunnelBridgeToMap *tbtm = _vd.tunnel_to_map.Begin(); tbtm != tbtm_end; tbtm++) { // For each tunnel
|
||||
const int tunnel_z = GetTileZ(tbtm->from_tile) * TILE_HEIGHT;
|
||||
const Point pt_from = RemapCoords(TileX(tbtm->from_tile) * TILE_SIZE, TileY(tbtm->from_tile) * TILE_SIZE, tunnel_z);
|
||||
const Point pt_to = RemapCoords(TileX(tbtm->to_tile) * TILE_SIZE, TileY(tbtm->to_tile) * TILE_SIZE, tunnel_z);
|
||||
|
||||
/* check if tunnel is wholly outside redrawing area */
|
||||
const int x_from = UnScaleByZoomLower(pt_from.x - _vd.dpi.left, _vd.dpi.zoom);
|
||||
const int x_to = UnScaleByZoomLower(pt_to.x - _vd.dpi.left, _vd.dpi.zoom);
|
||||
if ((x_from < 0 && x_to < 0) || (x_from > w && x_to > w)) continue;
|
||||
const int y_from = UnScaleByZoomLower(pt_from.y - _vd.dpi.top, _vd.dpi.zoom);
|
||||
const int y_to = UnScaleByZoomLower(pt_to.y - _vd.dpi.top, _vd.dpi.zoom);
|
||||
if ((y_from < 0 && y_to < 0) || (y_from > h && y_to > h)) continue;
|
||||
|
||||
ViewportMapDrawBridgeTunnel(vp, tbtm, tunnel_z, true, w, h, blitter);
|
||||
}
|
||||
}
|
||||
|
||||
/* Render bridges */
|
||||
if (_settings_client.gui.show_bridges_on_map && _vd.bridge_to_map.Length() != 0) {
|
||||
const TunnelBridgeToMap * const tbtm_end = _vd.bridge_to_map.End();
|
||||
for (const TunnelBridgeToMap *tbtm = _vd.bridge_to_map.Begin(); tbtm != tbtm_end; tbtm++) { // For each bridge
|
||||
ViewportMapDrawBridgeTunnel(vp, tbtm, (GetBridgeHeight(tbtm->from_tile) - 1) * TILE_HEIGHT, false, w, h, blitter);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2445,7 +2495,7 @@ void ViewportDoDraw(const ViewPort *vp, int left, int top, int right, int bottom
|
||||
|
||||
_cur_dpi = old_dpi;
|
||||
|
||||
_vd.tunnel_bridge_to_map.Clear();
|
||||
_vd.bridge_to_map.Clear();
|
||||
_vd.string_sprites_to_draw.Clear();
|
||||
_vd.tile_sprites_to_draw.Clear();
|
||||
_vd.parent_sprites_to_draw.Clear();
|
||||
|
Reference in New Issue
Block a user