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