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.
pull/6/merge
Jonathan G Rennison 9 years ago
parent 3788228d8f
commit 919057a5e6

@ -28,6 +28,7 @@
#include "core/pool_type.hpp"
#include "game/game.hpp"
#include "linkgraph/linkgraphschedule.h"
#include "viewport_func.h"
#include "safeguards.h"
@ -59,6 +60,8 @@ void InitializeGame(uint size_x, uint size_y, bool reset_date, bool reset_settin
AllocateMap(size_x, size_y);
ViewportMapClearTunnelCache();
_pause_mode = PM_UNPAUSED;
_fast_forward = 0;
_tick_counter = 0;

@ -64,6 +64,7 @@
#include "gfx_layout.h"
#include "viewport_sprite_sorter.h"
#include "smallmap_gui.h"
#include "viewport_func.h"
#include "linkgraph/linkgraphschedule.h"
@ -312,6 +313,8 @@ static void ShutdownGame()
FioCloseAll();
UninitFreeType();
ViewportMapClearTunnelCache();
}
/**

@ -44,7 +44,6 @@ void BuildLinkStatsLegend();
struct TunnelBridgeToMap {
TileIndex from_tile;
TileIndex to_tile;
uint8 colour;
};
typedef SmallVector<TunnelBridgeToMap, 64> TunnelBridgeToMapVector;

@ -40,6 +40,7 @@
#include "object_base.h"
#include "water.h"
#include "company_gui.h"
#include "viewport_func.h"
#include "table/strings.h"
#include "table/bridge_land.h"
@ -866,6 +867,8 @@ static CommandCost DoClearTunnel(TileIndex tile, DoCommandFlag flags)
DoClearSquare(tile);
DoClearSquare(endtile);
}
ViewportMapInvalidateTunnelCacheByTile(tile);
ViewportMapInvalidateTunnelCacheByTile(endtile);
}
return CommandCost(EXPENSES_CONSTRUCTION, _price[PR_CLEAR_TUNNEL] * len);
}

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

@ -94,4 +94,7 @@ Point GetViewportStationMiddle(const ViewPort *vp, const Station *st);
void ShowTooltipForTile(Window *w, const TileIndex tile);
void ViewportMapClearTunnelCache();
void ViewportMapInvalidateTunnelCacheByTile(const TileIndex tile);
#endif /* VIEWPORT_FUNC_H */

Loading…
Cancel
Save