Viewport: Cache landscape pixels in map mode

Avoid invalidating landscape pixels for non-landscape updates
(vehicles, overlays, etc.)
This commit is contained in:
Jonathan G Rennison
2020-10-01 23:11:15 +01:00
parent 8071976b0e
commit a474e71243
23 changed files with 268 additions and 143 deletions

View File

@@ -376,47 +376,58 @@ void Blitter_32bppAnim::DrawLine(void *video, int x, int y, int x2, int y2, int
} }
} }
void Blitter_32bppAnim::SetLine(void *video, int x, int y, uint8 *colours, uint width) void Blitter_32bppAnim::SetRect(void *video, int x, int y, const uint8 *colours, uint lines, uint width, uint pitch)
{ {
Colour *dst = (Colour *)video + x + y * _screen.pitch; Colour *dst = (Colour *)video + x + y * _screen.pitch;
if (_screen_disable_anim) { if (_screen_disable_anim) {
do {
uint w = width;
do { do {
*dst = LookupColourInPalette(*colours); *dst = LookupColourInPalette(*colours);
dst++; dst++;
colours++; colours++;
} while (--width); } while (--w);
dst += _screen.pitch - width;
colours += pitch - width;
} while (--lines);
} else { } else {
uint16 *dstanim = (uint16 *)(&this->anim_buf[this->ScreenToAnimOffset((uint32 *)video) + x + y * this->anim_buf_pitch]); uint16 *dstanim = (uint16 *)(&this->anim_buf[this->ScreenToAnimOffset((uint32 *)video) + x + y * this->anim_buf_pitch]);
do {
uint w = width;
do { do {
*dstanim = *colours | (DEFAULT_BRIGHTNESS << 8); *dstanim = *colours | (DEFAULT_BRIGHTNESS << 8);
*dst = LookupColourInPalette(*colours); *dst = LookupColourInPalette(*colours);
dst++; dst++;
dstanim++; dstanim++;
colours++; colours++;
} while (--width); } while (--w);
dst += _screen.pitch - width;
dstanim += this->anim_buf_pitch - width;
colours += pitch - width;
} while (--lines);
} }
} }
void Blitter_32bppAnim::SetLine32(void *video, int x, int y, uint32 *colours, uint width) void Blitter_32bppAnim::SetRect32(void *video, int x, int y, const uint32 *colours, uint lines, uint width, uint pitch)
{ {
Colour *dst = (Colour *)video + x + y * _screen.pitch; uint32 *dst = (uint32 *)video + x + y * _screen.pitch;
if (_screen_disable_anim) { if (_screen_disable_anim) {
do { do {
*dst = *colours; memcpy(dst, colours, width * sizeof(uint32));
dst++; dst += _screen.pitch;
colours++; colours += pitch;
} while (--width); } while (--lines);
} else { } else {
uint16 *dstanim = (uint16 *)(&this->anim_buf[this->ScreenToAnimOffset((uint32 *)video) + x + y * this->anim_buf_pitch]); uint16 *dstanim = (uint16 *)(&this->anim_buf[this->ScreenToAnimOffset((uint32 *)video) + x + y * this->anim_buf_pitch]);
do { do {
*dstanim = 0; memcpy(dst, colours, width * sizeof(uint32));
*dst = *colours; memset(dstanim, 0, width * sizeof(uint16));
dst++; dst += _screen.pitch;
dstanim++; dstanim += this->anim_buf_pitch;
colours++; colours += pitch;
} while (--width); } while (--lines);
} }
} }

View File

@@ -39,8 +39,8 @@ public:
void DrawColourMappingRect(void *dst, int width, int height, PaletteID pal) override; void DrawColourMappingRect(void *dst, int width, int height, PaletteID pal) override;
void SetPixel(void *video, int x, int y, uint8 colour) override; void SetPixel(void *video, int x, int y, uint8 colour) override;
void DrawLine(void *video, int x, int y, int x2, int y2, int screen_width, int screen_height, uint8 colour, int width, int dash) override; void DrawLine(void *video, int x, int y, int x2, int y2, int screen_width, int screen_height, uint8 colour, int width, int dash) override;
void SetLine(void *video, int x, int y, uint8 *colours, uint width) override; void SetRect(void *video, int x, int y, const uint8 *colours, uint lines, uint width, uint pitch) override;
void SetLine32(void *video, int x, int y, uint32 *colours, uint width) override; void SetRect32(void *video, int x, int y, const uint32 *colours, uint lines, uint width, uint pitch) override;
void DrawRect(void *video, int width, int height, uint8 colour) override; void DrawRect(void *video, int width, int height, uint8 colour) override;
void CopyFromBuffer(void *video, const void *src, int width, int height) override; void CopyFromBuffer(void *video, const void *src, int width, int height) override;
void CopyToBuffer(const void *video, void *dst, int width, int height) override; void CopyToBuffer(const void *video, void *dst, int width, int height) override;

View File

@@ -31,24 +31,29 @@ void Blitter_32bppBase::DrawLine(void *video, int x, int y, int x2, int y2, int
}); });
} }
void Blitter_32bppBase::SetLine(void *video, int x, int y, uint8 *colours, uint width) void Blitter_32bppBase::SetRect(void *video, int x, int y, const uint8 *colours, uint lines, uint width, uint pitch)
{ {
Colour *dst = (Colour *)video + x + y * _screen.pitch; Colour *dst = (Colour *)video + x + y * _screen.pitch;
do {
uint w = width;
do { do {
*dst = LookupColourInPalette(*colours); *dst = LookupColourInPalette(*colours);
dst++; dst++;
colours++; colours++;
} while (--width); } while (--w);
dst += _screen.pitch - width;
colours += pitch - width;
} while (--lines);
} }
void Blitter_32bppBase::SetLine32(void *video, int x, int y, uint32 *colours, uint width) void Blitter_32bppBase::SetRect32(void *video, int x, int y, const uint32 *colours, uint lines, uint width, uint pitch)
{ {
Colour *dst = (Colour *)video + x + y * _screen.pitch; uint32 *dst = (uint32 *)video + x + y * _screen.pitch;
do { do {
*dst = *colours; memcpy(dst, colours, width * sizeof(uint32));
dst++; dst += _screen.pitch;
colours++; colours += pitch;
} while (--width); } while (--lines);
} }
void Blitter_32bppBase::DrawRect(void *video, int width, int height, uint8 colour) void Blitter_32bppBase::DrawRect(void *video, int width, int height, uint8 colour)

View File

@@ -22,8 +22,8 @@ public:
void *MoveTo(void *video, int x, int y) override; void *MoveTo(void *video, int x, int y) override;
void SetPixel(void *video, int x, int y, uint8 colour) override; void SetPixel(void *video, int x, int y, uint8 colour) override;
void DrawLine(void *video, int x, int y, int x2, int y2, int screen_width, int screen_height, uint8 colour, int width, int dash) override; void DrawLine(void *video, int x, int y, int x2, int y2, int screen_width, int screen_height, uint8 colour, int width, int dash) override;
void SetLine(void *video, int x, int y, uint8 *colours, uint width) override; void SetRect(void *video, int x, int y, const uint8 *colours, uint lines, uint width, uint pitch) override;
void SetLine32(void *video, int x, int y, uint32 *colours, uint width) override; void SetRect32(void *video, int x, int y, const uint32 *colours, uint lines, uint width, uint pitch) override;
void DrawRect(void *video, int width, int height, uint8 colour) override; void DrawRect(void *video, int width, int height, uint8 colour) override;
void CopyFromBuffer(void *video, const void *src, int width, int height) override; void CopyFromBuffer(void *video, const void *src, int width, int height) override;
void CopyToBuffer(const void *video, void *dst, int width, int height) override; void CopyToBuffer(const void *video, void *dst, int width, int height) override;

View File

@@ -41,9 +41,14 @@ void Blitter_8bppBase::DrawLine(void *video, int x, int y, int x2, int y2, int s
}); });
} }
void Blitter_8bppBase::SetLine(void *video, int x, int y, uint8 *colours, uint width) void Blitter_8bppBase::SetRect(void *video, int x, int y, const uint8 *colours, uint lines, uint width, uint pitch)
{ {
memcpy((uint8 *)video + x + y * _screen.pitch, colours, width * sizeof(uint8)); uint8 *dst = (uint8 *)video + x + y * _screen.pitch;
do {
memcpy(dst, colours, width * sizeof(uint8));
dst += _screen.pitch;
colours += pitch;
} while (--lines);
} }
void Blitter_8bppBase::DrawRect(void *video, int width, int height, uint8 colour) void Blitter_8bppBase::DrawRect(void *video, int width, int height, uint8 colour)

View File

@@ -20,7 +20,7 @@ public:
void *MoveTo(void *video, int x, int y) override; void *MoveTo(void *video, int x, int y) override;
void SetPixel(void *video, int x, int y, uint8 colour) override; void SetPixel(void *video, int x, int y, uint8 colour) override;
void DrawLine(void *video, int x, int y, int x2, int y2, int screen_width, int screen_height, uint8 colour, int width, int dash) override; void DrawLine(void *video, int x, int y, int x2, int y2, int screen_width, int screen_height, uint8 colour, int width, int dash) override;
void SetLine(void *video, int x, int y, uint8 *colours, uint width) override; void SetRect(void *video, int x, int y, const uint8 *colours, uint lines, uint width, uint pitch) override;
void DrawRect(void *video, int width, int height, uint8 colour) override; void DrawRect(void *video, int width, int height, uint8 colour) override;
void CopyFromBuffer(void *video, const void *src, int width, int height) override; void CopyFromBuffer(void *video, const void *src, int width, int height) override;
void CopyToBuffer(const void *video, void *dst, int width, int height) override; void CopyToBuffer(const void *video, void *dst, int width, int height) override;

View File

@@ -115,24 +115,28 @@ public:
virtual void SetPixel(void *video, int x, int y, uint8 colour) = 0; virtual void SetPixel(void *video, int x, int y, uint8 colour) = 0;
/** /**
* Draw a sequence of pixels on the video-buffer. * Draw a rectangle of pixels on the video-buffer.
* @param video The destination pointer (video-buffer). * @param video The destination pointer (video-buffer).
* @param x The x position within video-buffer. * @param x The x position within video-buffer.
* @param y The y position within video-buffer. * @param y The y position within video-buffer.
* @param colours A 8bpp colour mapping buffer. * @param colours A 8bpp colour mapping buffer.
* @param width The length of the line. * @param lines The number of lines.
* @param width The length of the lines.
* @param pitch The pitch of the colours buffer
*/ */
virtual void SetLine(void *video, int x, int y, uint8 *colours, uint width) = 0; virtual void SetRect(void *video, int x, int y, const uint8 *colours, uint lines, uint width, uint pitch) = 0;
/** /**
* Draw a sequence of pixels on the video-buffer (no LookupColourInPalette). * Draw a rectangle of pixels on the video-buffer (no LookupColourInPalette).
* @param video The destination pointer (video-buffer). * @param video The destination pointer (video-buffer).
* @param x The x position within video-buffer. * @param x The x position within video-buffer.
* @param y The y position within video-buffer. * @param y The y position within video-buffer.
* @param colours A 32bpp colour buffer. * @param colours A 32bpp colour buffer.
* @param width The length of the line. * @param lines The number of lines.
* @param width The length of the lines.
* @param pitch The pitch of the colours buffer.
*/ */
virtual void SetLine32(void *video, int x, int y, uint32 *colours, uint width) { NOT_REACHED(); }; virtual void SetRect32(void *video, int x, int y, const uint32 *colours, uint lines, uint width, uint pitch) { NOT_REACHED(); };
/** /**
* Make a single horizontal line in a single colour on the video-buffer. * Make a single horizontal line in a single colour on the video-buffer.

View File

@@ -23,8 +23,8 @@ public:
void SetPixel(void *video, int x, int y, uint8 colour) override {}; void SetPixel(void *video, int x, int y, uint8 colour) override {};
void DrawRect(void *video, int width, int height, uint8 colour) override {}; void DrawRect(void *video, int width, int height, uint8 colour) override {};
void DrawLine(void *video, int x, int y, int x2, int y2, int screen_width, int screen_height, uint8 colour, int width, int dash) override {}; void DrawLine(void *video, int x, int y, int x2, int y2, int screen_width, int screen_height, uint8 colour, int width, int dash) override {};
void SetLine(void *video, int x, int y, uint8 *colours, uint width) override {}; void SetRect(void *video, int x, int y, const uint8 *colours, uint lines, uint width, uint pitch) override {};
void SetLine32(void *video, int x, int y, uint32 *colours, uint width) override {}; void SetRect32(void *video, int x, int y, const uint32 *colours, uint lines, uint width, uint pitch) override {};
void CopyFromBuffer(void *video, const void *src, int width, int height) override {}; void CopyFromBuffer(void *video, const void *src, int width, int height) override {};
void CopyToBuffer(const void *video, void *dst, int width, int height) override {}; void CopyToBuffer(const void *video, void *dst, int width, int height) override {};
void CopyImageToBuffer(const void *video, void *dst, int width, int height, int dst_pitch) override {}; void CopyImageToBuffer(const void *video, void *dst, int width, int height, int dst_pitch) override {};

View File

@@ -1328,9 +1328,6 @@ void ScreenSizeChanged()
{ {
MarkWholeScreenDirty(); MarkWholeScreenDirty();
extern uint32 *_vp_map_line;
_vp_map_line = ReallocT<uint32>(_vp_map_line, _screen.width);
/* screen size changed and the old bitmap is invalid now, so we don't want to undraw it */ /* screen size changed and the old bitmap is invalid now, so we don't want to undraw it */
_cursor.visible = false; _cursor.visible = false;
} }

View File

@@ -88,18 +88,18 @@ void LinkGraphOverlay::MarkStationViewportLinksDirty(const Station *st)
Viewport *vp = this->window->viewport; Viewport *vp = this->window->viewport;
const Point pt = RemapCoords2(TileX(st->xy) * TILE_SIZE, TileY(st->xy) * TILE_SIZE); const Point pt = RemapCoords2(TileX(st->xy) * TILE_SIZE, TileY(st->xy) * TILE_SIZE);
const int padding = ScaleByZoom(3 * this->scale, vp->zoom); const int padding = ScaleByZoom(3 * this->scale, vp->zoom);
MarkViewportDirty(vp, pt.x - padding, pt.y - padding, pt.x + padding, pt.y - padding, VMDF_NONE); MarkViewportDirty(vp, pt.x - padding, pt.y - padding, pt.x + padding, pt.y - padding, VMDF_NOT_LANDSCAPE);
const int block_radius = ScaleByZoom(10, vp->zoom); const int block_radius = ScaleByZoom(10, vp->zoom);
for (LinkList::iterator i(this->cached_links.begin()); i != this->cached_links.end(); ++i) { for (LinkList::iterator i(this->cached_links.begin()); i != this->cached_links.end(); ++i) {
if (i->from_id == st->index) { if (i->from_id == st->index) {
const Station *stb = Station::GetIfValid(i->to_id); const Station *stb = Station::GetIfValid(i->to_id);
if (stb == nullptr) continue; if (stb == nullptr) continue;
MarkViewportLineDirty(vp, pt, RemapCoords2(TileX(stb->xy) * TILE_SIZE, TileY(stb->xy) * TILE_SIZE), block_radius, VMDF_NONE); MarkViewportLineDirty(vp, pt, RemapCoords2(TileX(stb->xy) * TILE_SIZE, TileY(stb->xy) * TILE_SIZE), block_radius, VMDF_NOT_LANDSCAPE);
} else if (i->to_id == st->index) { } else if (i->to_id == st->index) {
const Station *sta = Station::GetIfValid(i->from_id); const Station *sta = Station::GetIfValid(i->from_id);
if (sta == nullptr) continue; if (sta == nullptr) continue;
MarkViewportLineDirty(vp, RemapCoords2(TileX(sta->xy) * TILE_SIZE, TileY(sta->xy) * TILE_SIZE), pt, block_radius, VMDF_NONE); MarkViewportLineDirty(vp, RemapCoords2(TileX(sta->xy) * TILE_SIZE, TileY(sta->xy) * TILE_SIZE), pt, block_radius, VMDF_NOT_LANDSCAPE);
} }
} }
} }

View File

@@ -416,19 +416,19 @@ struct MainWindow : Window
case GHK_CHANGE_MAP_MODE_PREV: case GHK_CHANGE_MAP_MODE_PREV:
if (_focused_window && _focused_window->viewport && _focused_window->viewport->zoom >= ZOOM_LVL_DRAW_MAP) { if (_focused_window && _focused_window->viewport && _focused_window->viewport->zoom >= ZOOM_LVL_DRAW_MAP) {
_focused_window->viewport->map_type = ChangeRenderMode(_focused_window->viewport, true); ChangeRenderMode(_focused_window->viewport, true);
_focused_window->SetDirty(); _focused_window->SetDirty();
} else if (this->viewport->zoom >= ZOOM_LVL_DRAW_MAP) { } else if (this->viewport->zoom >= ZOOM_LVL_DRAW_MAP) {
this->viewport->map_type = ChangeRenderMode(this->viewport, true); ChangeRenderMode(this->viewport, true);
this->SetDirty(); this->SetDirty();
} }
break; break;
case GHK_CHANGE_MAP_MODE_NEXT: case GHK_CHANGE_MAP_MODE_NEXT:
if (_focused_window && _focused_window->viewport && _focused_window->viewport->zoom >= ZOOM_LVL_DRAW_MAP) { if (_focused_window && _focused_window->viewport && _focused_window->viewport->zoom >= ZOOM_LVL_DRAW_MAP) {
_focused_window->viewport->map_type = ChangeRenderMode(_focused_window->viewport, false); ChangeRenderMode(_focused_window->viewport, false);
_focused_window->SetDirty(); _focused_window->SetDirty();
} else if (this->viewport->zoom >= ZOOM_LVL_DRAW_MAP) { } else if (this->viewport->zoom >= ZOOM_LVL_DRAW_MAP) {
this->viewport->map_type = ChangeRenderMode(this->viewport, false); ChangeRenderMode(this->viewport, false);
this->SetDirty(); this->SetDirty();
} }
break; break;
@@ -451,7 +451,7 @@ struct MainWindow : Window
{ {
if (_ctrl_pressed) { if (_ctrl_pressed) {
/* Cycle through the drawing modes */ /* Cycle through the drawing modes */
this->viewport->map_type = ChangeRenderMode(this->viewport, wheel < 0); ChangeRenderMode(this->viewport, wheel < 0);
this->SetDirty(); this->SetDirty();
} else if (_settings_client.gui.scrollwheel_scrolling != 2) { } else if (_settings_client.gui.scrollwheel_scrolling != 2) {
ZoomInOrOutToCursorWindow(wheel < 0, this); ZoomInOrOutToCursorWindow(wheel < 0, this);

View File

@@ -56,7 +56,7 @@ struct PlanLine {
if (cnt > 0) { if (cnt > 0) {
const TileIndex last_tile = this->tiles[cnt - 1]; const TileIndex last_tile = this->tiles[cnt - 1];
if (last_tile == tile) return false; if (last_tile == tile) return false;
MarkTileLineDirty(last_tile, tile); MarkTileLineDirty(last_tile, tile, VMDF_NOT_LANDSCAPE);
if (cnt > 1) { if (cnt > 1) {
const TileIndex t0 = this->tiles[cnt - 2]; const TileIndex t0 = this->tiles[cnt - 2];
@@ -72,7 +72,7 @@ struct PlanLine {
if (abs(x2 - x1) <= abs(x2 - x0) && abs(y2 - y1) <= abs(y2 - y0)) { // Tile i+1 is between i and i+2. if (abs(x2 - x1) <= abs(x2 - x0) && abs(y2 - y1) <= abs(y2 - y0)) { // Tile i+1 is between i and i+2.
/* The new tile is in the continuity, just update the last tile. */ /* The new tile is in the continuity, just update the last tile. */
this->tiles[cnt - 1] = tile; this->tiles[cnt - 1] = tile;
MarkTileLineDirty(t1, tile); MarkTileLineDirty(t1, tile, VMDF_NOT_LANDSCAPE);
return true; return true;
} }
} }
@@ -107,7 +107,7 @@ struct PlanLine {
{ {
const uint sz = (uint) this->tiles.size(); const uint sz = (uint) this->tiles.size();
for (uint i = 1; i < sz; i++) { for (uint i = 1; i < sz; i++) {
MarkTileLineDirty(this->tiles[i-1], this->tiles[i]); MarkTileLineDirty(this->tiles[i-1], this->tiles[i], VMDF_NOT_LANDSCAPE);
} }
} }

View File

@@ -1343,7 +1343,19 @@ static bool ViewportMapShowTunnelModeChanged(int32 p1)
{ {
extern void ViewportMapBuildTunnelCache(); extern void ViewportMapBuildTunnelCache();
ViewportMapBuildTunnelCache(); ViewportMapBuildTunnelCache();
return RedrawScreen(p1);
extern void MarkAllViewportMapLandscapesDirty();
MarkAllViewportMapLandscapesDirty();
return true;
}
static bool ViewportMapLandscapeModeChanged(int32 p1)
{
extern void MarkAllViewportMapLandscapesDirty();
MarkAllViewportMapLandscapesDirty();
return true;
} }
static bool UpdateLinkgraphColours(int32 p1) static bool UpdateLinkgraphColours(int32 p1)

View File

@@ -54,6 +54,7 @@ static bool SimulatedWormholeSignalsChanged(int32 p1);
static bool EnableSingleVehSharedOrderGuiChanged(int32 p1); static bool EnableSingleVehSharedOrderGuiChanged(int32 p1);
static bool CheckYapfRailSignalPenalties(int32 p1); static bool CheckYapfRailSignalPenalties(int32 p1);
static bool ViewportMapShowTunnelModeChanged(int32 p1); static bool ViewportMapShowTunnelModeChanged(int32 p1);
static bool ViewportMapLandscapeModeChanged(int32 p1);
static bool UpdateLinkgraphColours(int32 p1); static bool UpdateLinkgraphColours(int32 p1);
static bool UpdateClientName(int32 p1); static bool UpdateClientName(int32 p1);
@@ -4137,21 +4138,21 @@ var = gui.viewport_map_scan_surroundings
flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC
def = true def = true
str = STR_CONFIG_SETTING_VIEWPORT_MAP_SCAN_SURROUNDINGS str = STR_CONFIG_SETTING_VIEWPORT_MAP_SCAN_SURROUNDINGS
proc = RedrawScreen proc = ViewportMapLandscapeModeChanged
[SDTC_BOOL] [SDTC_BOOL]
var = gui.show_slopes_on_viewport_map var = gui.show_slopes_on_viewport_map
flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC
def = true def = true
str = STR_CONFIG_SETTING_VIEWPORT_MAP_SHOW_SLOPES str = STR_CONFIG_SETTING_VIEWPORT_MAP_SHOW_SLOPES
proc = RedrawScreen proc = ViewportMapLandscapeModeChanged
[SDTC_BOOL] [SDTC_BOOL]
var = gui.show_bridges_on_map var = gui.show_bridges_on_map
flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC
def = true def = true
str = STR_CONFIG_SETTING_VIEWPORT_MAP_SHOW_BRIDGES str = STR_CONFIG_SETTING_VIEWPORT_MAP_SHOW_BRIDGES
proc = RedrawScreen proc = ViewportMapLandscapeModeChanged
[SDTC_BOOL] [SDTC_BOOL]
var = gui.show_tunnels_on_map var = gui.show_tunnels_on_map
@@ -4192,7 +4193,7 @@ var = gui.use_owner_colour_for_tunnelbridge
flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC
def = false def = false
str = STR_CONFIG_SETTING_VIEWPORT_MAP_USE_OWNER_COLOUR_BRIDGE_TUNNEL str = STR_CONFIG_SETTING_VIEWPORT_MAP_USE_OWNER_COLOUR_BRIDGE_TUNNEL
proc = RedrawScreen proc = ViewportMapLandscapeModeChanged
[SDTC_VAR] [SDTC_VAR]
var = gui.show_scrolling_viewport_on_map var = gui.show_scrolling_viewport_on_map

View File

@@ -275,7 +275,7 @@ public:
this->town->show_zone = new_show_state; this->town->show_zone = new_show_state;
this->SetWidgetLoweredState(widget, new_show_state); this->SetWidgetLoweredState(widget, new_show_state);
MarkWholeScreenDirty(); MarkWholeNonMapViewportsDirty();
break; break;
} }

View File

@@ -2303,7 +2303,7 @@ void ReverseTrainDirection(Train *v)
if (IsTunnelBridgeWithSignalSimulation(v->tile) && IsTunnelBridgeSignalSimulationEntrance(v->tile)) { if (IsTunnelBridgeWithSignalSimulation(v->tile) && IsTunnelBridgeSignalSimulationEntrance(v->tile)) {
/* Flip signal on tunnel entrance tile red. */ /* Flip signal on tunnel entrance tile red. */
SetTunnelBridgeEntranceSignalState(v->tile, SIGNAL_STATE_RED); SetTunnelBridgeEntranceSignalState(v->tile, SIGNAL_STATE_RED);
MarkTileDirtyByTile(v->tile); MarkTileDirtyByTile(v->tile, VMDF_NOT_MAP_MODE);
/* Clear counters. */ /* Clear counters. */
v->wait_counter = 0; v->wait_counter = 0;
v->tunnel_bridge_signal_num = 0; v->tunnel_bridge_signal_num = 0;
@@ -2750,9 +2750,9 @@ static void HandleLastTunnelBridgeSignals(TileIndex tile, TileIndex end, DiagDir
int signal_offset = GetAndClearLastBridgeEntranceSetSignalIndex(end); int signal_offset = GetAndClearLastBridgeEntranceSetSignalIndex(end);
if (signal_offset) { if (signal_offset) {
TileIndex last_signal_tile = end + (TileOffsByDiagDir(dir) * _settings_game.construction.simulated_wormhole_signals * signal_offset); TileIndex last_signal_tile = end + (TileOffsByDiagDir(dir) * _settings_game.construction.simulated_wormhole_signals * signal_offset);
MarkTileDirtyByTile(last_signal_tile); MarkTileDirtyByTile(last_signal_tile, VMDF_NOT_MAP_MODE);
} }
MarkTileDirtyByTile(tile); MarkTileDirtyByTile(tile, VMDF_NOT_MAP_MODE);
} }
if (free) { if (free) {
/* Open up the wormhole and clear m2. */ /* Open up the wormhole and clear m2. */
@@ -2763,11 +2763,11 @@ static void HandleLastTunnelBridgeSignals(TileIndex tile, TileIndex end, DiagDir
if (IsTunnelBridgeSignalSimulationEntrance(end) && GetTunnelBridgeEntranceSignalState(end) == SIGNAL_STATE_RED) { if (IsTunnelBridgeSignalSimulationEntrance(end) && GetTunnelBridgeEntranceSignalState(end) == SIGNAL_STATE_RED) {
SetTunnelBridgeEntranceSignalState(end, SIGNAL_STATE_GREEN); SetTunnelBridgeEntranceSignalState(end, SIGNAL_STATE_GREEN);
MarkTileDirtyByTile(end); MarkTileDirtyByTile(end, VMDF_NOT_MAP_MODE);
} }
if (IsTunnelBridgeSignalSimulationEntrance(tile) && GetTunnelBridgeEntranceSignalState(tile) == SIGNAL_STATE_RED) { if (IsTunnelBridgeSignalSimulationEntrance(tile) && GetTunnelBridgeEntranceSignalState(tile) == SIGNAL_STATE_RED) {
SetTunnelBridgeEntranceSignalState(tile, SIGNAL_STATE_GREEN); SetTunnelBridgeEntranceSignalState(tile, SIGNAL_STATE_GREEN);
MarkTileDirtyByTile(tile); MarkTileDirtyByTile(tile, VMDF_NOT_MAP_MODE);
} }
} }
} }
@@ -3973,11 +3973,11 @@ static void HandleSignalBehindTrain(Train *v, int signal_number)
/* Flip signal on ramp. */ /* Flip signal on ramp. */
if (IsTunnelBridgeSignalSimulationEntrance(tile) && GetTunnelBridgeEntranceSignalState(tile) == SIGNAL_STATE_RED) { if (IsTunnelBridgeSignalSimulationEntrance(tile) && GetTunnelBridgeEntranceSignalState(tile) == SIGNAL_STATE_RED) {
SetTunnelBridgeEntranceSignalState(tile, SIGNAL_STATE_GREEN); SetTunnelBridgeEntranceSignalState(tile, SIGNAL_STATE_GREEN);
MarkTileDirtyByTile(tile); MarkTileDirtyByTile(tile, VMDF_NOT_MAP_MODE);
} }
} else if (IsBridge(v->tile) && signal_number >= 0) { } else if (IsBridge(v->tile) && signal_number >= 0) {
SetBridgeEntranceSimulatedSignalState(v->tile, signal_number, SIGNAL_STATE_GREEN); SetBridgeEntranceSimulatedSignalState(v->tile, signal_number, SIGNAL_STATE_GREEN);
MarkTileDirtyByTile(tile); MarkTileDirtyByTile(tile, VMDF_NOT_MAP_MODE);
} }
} }
@@ -4270,12 +4270,12 @@ bool TrainController(Train *v, Vehicle *nomove, bool reverse)
} }
/* Flip signal on tunnel entrance tile red. */ /* Flip signal on tunnel entrance tile red. */
SetTunnelBridgeEntranceSignalState(gp.new_tile, SIGNAL_STATE_RED); SetTunnelBridgeEntranceSignalState(gp.new_tile, SIGNAL_STATE_RED);
MarkTileDirtyByTile(gp.new_tile); MarkTileDirtyByTile(gp.new_tile, VMDF_NOT_MAP_MODE);
if (IsTunnelBridgeSignalSimulationBidirectional(gp.new_tile)) { if (IsTunnelBridgeSignalSimulationBidirectional(gp.new_tile)) {
/* Set incoming signal in other direction to red as well */ /* Set incoming signal in other direction to red as well */
TileIndex other_end = GetOtherTunnelBridgeEnd(gp.new_tile); TileIndex other_end = GetOtherTunnelBridgeEnd(gp.new_tile);
SetTunnelBridgeEntranceSignalState(other_end, SIGNAL_STATE_RED); SetTunnelBridgeEntranceSignalState(other_end, SIGNAL_STATE_RED);
MarkTileDirtyByTile(other_end); MarkTileDirtyByTile(other_end, VMDF_NOT_MAP_MODE);
} }
} }
} }
@@ -4360,7 +4360,7 @@ bool TrainController(Train *v, Vehicle *nomove, bool reverse)
/* flip signal in front to red on bridges*/ /* flip signal in front to red on bridges*/
if (distance == 0 && IsBridge(v->tile)) { if (distance == 0 && IsBridge(v->tile)) {
SetBridgeEntranceSimulatedSignalState(v->tile, v->tunnel_bridge_signal_num, SIGNAL_STATE_RED); SetBridgeEntranceSimulatedSignalState(v->tile, v->tunnel_bridge_signal_num, SIGNAL_STATE_RED);
MarkTileDirtyByTile(gp.new_tile); MarkTileDirtyByTile(gp.new_tile, VMDF_NOT_MAP_MODE);
} }
} }
} }

View File

@@ -16,6 +16,7 @@
#include "command_func.h" #include "command_func.h"
#include "sound_func.h" #include "sound_func.h"
#include "tree_map.h" #include "tree_map.h"
#include "viewport_func.h"
#include "widgets/tree_widget.h" #include "widgets/tree_widget.h"
@@ -117,13 +118,13 @@ public:
case WID_BT_MANY_RANDOM: // place trees randomly over the landscape case WID_BT_MANY_RANDOM: // place trees randomly over the landscape
if (_settings_client.sound.confirm) SndPlayFx(SND_15_BEEP); if (_settings_client.sound.confirm) SndPlayFx(SND_15_BEEP);
PlaceTreesRandomly(); PlaceTreesRandomly();
MarkWholeScreenDirty(); MarkWholeNonMapViewportsDirty();
break; break;
case WID_BT_REMOVE_ALL: // remove all trees over the landscape case WID_BT_REMOVE_ALL: // remove all trees over the landscape
if (_settings_client.sound.confirm) SndPlayFx(SND_15_BEEP); if (_settings_client.sound.confirm) SndPlayFx(SND_15_BEEP);
RemoveAllTrees(); RemoveAllTrees();
MarkWholeScreenDirty(); MarkWholeNonMapViewportsDirty();
break; break;
} }

View File

@@ -2332,7 +2332,7 @@ void Vehicle::UpdateViewport(bool dirty)
min(old_coord.top, this->coord.top), min(old_coord.top, this->coord.top),
max(old_coord.right, this->coord.right), max(old_coord.right, this->coord.right),
max(old_coord.bottom, this->coord.bottom), max(old_coord.bottom, this->coord.bottom),
this->type != VEH_EFFECT ? VMDF_NONE : VMDF_NOT_MAP_MODE VMDF_NOT_LANDSCAPE | (this->type != VEH_EFFECT ? VMDF_NONE : VMDF_NOT_MAP_MODE)
); );
} }
} }
@@ -2352,7 +2352,7 @@ void Vehicle::UpdatePositionAndViewport()
*/ */
void Vehicle::MarkAllViewportsDirty() const void Vehicle::MarkAllViewportsDirty() const
{ {
::MarkAllViewportsDirty(this->coord.left, this->coord.top, this->coord.right, this->coord.bottom, this->type != VEH_EFFECT ? VMDF_NONE : VMDF_NOT_MAP_MODE); ::MarkAllViewportsDirty(this->coord.left, this->coord.top, this->coord.right, this->coord.bottom, VMDF_NOT_LANDSCAPE | (this->type != VEH_EFFECT ? VMDF_NONE : VMDF_NOT_MAP_MODE));
} }
VehicleOrderID Vehicle::GetFirstWaitingLocation(bool require_wait_timetabled) const VehicleOrderID Vehicle::GetFirstWaitingLocation(bool require_wait_timetabled) const

View File

@@ -233,6 +233,8 @@ struct BridgeSetYComparator {
/** Data structure storing rendering information */ /** Data structure storing rendering information */
struct ViewportDrawer { struct ViewportDrawer {
DrawPixelInfo dpi; DrawPixelInfo dpi;
int offset_x;
int offset_y;
StringSpriteToDrawVector string_sprites_to_draw; StringSpriteToDrawVector string_sprites_to_draw;
TileSpriteToDrawVector tile_sprites_to_draw; TileSpriteToDrawVector tile_sprites_to_draw;
@@ -325,6 +327,7 @@ enum ViewportDebugFlags {
VDF_DIRTY_WHOLE_VIEWPORT, VDF_DIRTY_WHOLE_VIEWPORT,
VDF_DIRTY_BLOCK_PER_SPLIT, VDF_DIRTY_BLOCK_PER_SPLIT,
VDF_DISABLE_DRAW_SPLIT, VDF_DISABLE_DRAW_SPLIT,
VDF_SHOW_NO_LANDSCAPE_MAP_DRAW,
}; };
uint32 _viewport_debug_flags; uint32 _viewport_debug_flags;
@@ -336,6 +339,11 @@ static Point MapXYZToViewport(const Viewport *vp, int x, int y, int z)
return p; return p;
} }
void ClearViewportLandPixelCache(Viewport *vp)
{
vp->land_pixel_cache.assign(vp->land_pixel_cache.size(), 0xD7);
}
void ClearViewportCache(Viewport *vp) void ClearViewportCache(Viewport *vp)
{ {
if (vp->zoom >= ZOOM_LVL_DRAW_MAP) { if (vp->zoom >= ZOOM_LVL_DRAW_MAP) {
@@ -678,6 +686,7 @@ static void SetViewportPosition(Window *w, int x, int y, bool force_update_overl
if (i >= 0) height -= i; if (i >= 0) height -= i;
if (height > 0 && (_vp_move_offs.x != 0 || _vp_move_offs.y != 0)) { if (height > 0 && (_vp_move_offs.x != 0 || _vp_move_offs.y != 0)) {
ClearViewportLandPixelCache(vp);
SCOPE_INFO_FMT([&], "DoSetViewportPosition: %d, %d, %d, %d, %d, %d, %s", left, top, width, height, _vp_move_offs.x, _vp_move_offs.y, scope_dumper().WindowInfo(w)); SCOPE_INFO_FMT([&], "DoSetViewportPosition: %d, %d, %d, %d, %d, %d, %s", left, top, width, height, _vp_move_offs.x, _vp_move_offs.y, scope_dumper().WindowInfo(w));
DoSetViewportPosition((Window *) w->z_front, left, top, width, height); DoSetViewportPosition((Window *) w->z_front, left, top, width, height);
ClearViewportCache(w->viewport); ClearViewportCache(w->viewport);
@@ -2882,9 +2891,8 @@ static void ViewportMapDrawScrollingViewportBox(const Viewport * const vp)
} }
} }
uint32 *_vp_map_line; ///< Buffer for drawing the map of a viewport. template <bool is_32bpp>
static void ViewportMapDrawBridgeTunnel(Viewport * const vp, const TunnelBridgeToMap * const tbtm, const int z,
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) 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 LegendAndColour _legend_land_owners[NUM_NO_COMPANY_ENTRIES + MAX_COMPANIES + 1];
@@ -2908,14 +2916,21 @@ static void ViewportMapDrawBridgeTunnel(const Viewport * const vp, const TunnelB
const int x = UnScaleByZoomLower(pt.x - _vd.dpi.left, _vd.dpi.zoom); const int x = UnScaleByZoomLower(pt.x - _vd.dpi.left, _vd.dpi.zoom);
if (IsInsideMM(x, 0, w)) { if (IsInsideMM(x, 0, w)) {
const int y = UnScaleByZoomLower(pt.y - _vd.dpi.top, _vd.dpi.zoom); 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); if (IsInsideMM(y, 0, h)) {
uint idx = (x + _vd.offset_x) + ((y + _vd.offset_y) * vp->width);
if (is_32bpp) {
reinterpret_cast<uint32 *>(vp->land_pixel_cache.data())[idx] = COL8TO32(colour);
} else {
reinterpret_cast<uint8 *>(vp->land_pixel_cache.data())[idx] = colour;
}
}
} }
} }
} }
/** Draw the map on a viewport. */ /** Draw the map on a viewport. */
template <bool is_32bpp, bool show_slope> template <bool is_32bpp, bool show_slope>
void ViewportMapDraw(const Viewport * const vp) void ViewportMapDraw(Viewport * const vp)
{ {
assert(vp != nullptr); assert(vp != nullptr);
Blitter * const blitter = BlitterFactory::GetCurrentBlitter(); Blitter * const blitter = BlitterFactory::GetCurrentBlitter();
@@ -2942,31 +2957,41 @@ void ViewportMapDraw(const Viewport * const vp)
const int h = UnScaleByZoom(_vd.dpi.height, vp->zoom); const int h = UnScaleByZoom(_vd.dpi.height, vp->zoom);
int j = 0; int j = 0;
const int land_cache_start = _vd.offset_x + (_vd.offset_y * vp->width);
uint32 *land_cache_ptr32 = reinterpret_cast<uint32 *>(vp->land_pixel_cache.data()) + land_cache_start;
uint8 *land_cache_ptr8 = reinterpret_cast<uint8 *>(vp->land_pixel_cache.data()) + land_cache_start;
bool cache_updated = false;
/* Render base map. */ /* Render base map. */
do { // For each line do { // For each line
int i = w; int i = w;
uint colour_index = colour_index_base; uint colour_index = colour_index_base;
colour_index_base ^= 2; colour_index_base ^= 2;
uint32 *vp_map_line_ptr32 = _vp_map_line;
uint8 *vp_map_line_ptr8 = (uint8*) _vp_map_line;
int c = b - a; int c = b - a;
int d = b + a; int d = b + a;
do { // For each pixel of a line do { // For each pixel of a line
if (is_32bpp) { if (is_32bpp) {
*vp_map_line_ptr32 = ViewportMapGetColour<is_32bpp, show_slope>(vp, c, d, colour_index); if (*land_cache_ptr32 == 0xD7D7D7D7) {
vp_map_line_ptr32++; *land_cache_ptr32 = ViewportMapGetColour<is_32bpp, show_slope>(vp, c, d, colour_index);
cache_updated = true;
}
land_cache_ptr32++;
} else { } else {
*vp_map_line_ptr8 = (uint8) ViewportMapGetColour<is_32bpp, show_slope>(vp, c, d, colour_index); if (*land_cache_ptr8 == 0xD7) {
vp_map_line_ptr8++; *land_cache_ptr8 = (uint8) ViewportMapGetColour<is_32bpp, show_slope>(vp, c, d, colour_index);
cache_updated = true;
}
land_cache_ptr8++;
} }
colour_index = (colour_index + 1) & 3; colour_index = (colour_index + 1) & 3;
c -= incr_a; c -= incr_a;
d += incr_a; d += incr_a;
} while (--i); } while (--i);
if (is_32bpp) { if (is_32bpp) {
blitter->SetLine32(_vd.dpi.dst_ptr, 0, j, _vp_map_line, w); land_cache_ptr32 += (vp->width - w);
} else { } else {
blitter->SetLine(_vd.dpi.dst_ptr, 0, j, (uint8*) _vp_map_line, w); land_cache_ptr8 += (vp->width - w);
} }
b += incr_b; b += incr_b;
} while (++j < h); } while (++j < h);
@@ -2989,10 +3014,11 @@ void ViewportMapDraw(const Viewport * const vp)
const int y_to = UnScaleByZoomLower(pt_to.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; if ((y_from < 0 && y_to < 0) || (y_from > h && y_to > h)) continue;
ViewportMapDrawBridgeTunnel(vp, &ttm.tb, tunnel_z, true, w, h, blitter); ViewportMapDrawBridgeTunnel<is_32bpp>(vp, &ttm.tb, tunnel_z, true, w, h, blitter);
} }
}; };
if (cache_updated) {
/* Render tunnels */ /* Render tunnels */
if (_settings_client.gui.show_tunnels_on_map && _vd.tunnel_to_map_x.tunnels.size() != 0) { if (_settings_client.gui.show_tunnels_on_map && _vd.tunnel_to_map_x.tunnels.size() != 0) {
const int y_intercept_min = _vd.dpi.top + (_vd.dpi.left / 2); const int y_intercept_min = _vd.dpi.top + (_vd.dpi.left / 2);
@@ -3009,15 +3035,27 @@ void ViewportMapDraw(const Viewport * const vp)
if (_settings_client.gui.show_bridges_on_map && _vd.bridge_to_map_x.size() != 0) { if (_settings_client.gui.show_bridges_on_map && _vd.bridge_to_map_x.size() != 0) {
for (const auto &it : _vd.bridge_to_map_x) { // For each bridge for (const auto &it : _vd.bridge_to_map_x) { // For each bridge
TunnelBridgeToMap tbtm { it.first, it.second }; TunnelBridgeToMap tbtm { it.first, it.second };
ViewportMapDrawBridgeTunnel(vp, &tbtm, (GetBridgeHeight(tbtm.from_tile) - 1) * TILE_HEIGHT, false, w, h, blitter); ViewportMapDrawBridgeTunnel<is_32bpp>(vp, &tbtm, (GetBridgeHeight(tbtm.from_tile) - 1) * TILE_HEIGHT, false, w, h, blitter);
} }
} }
if (_settings_client.gui.show_bridges_on_map && _vd.bridge_to_map_y.size() != 0) { if (_settings_client.gui.show_bridges_on_map && _vd.bridge_to_map_y.size() != 0) {
for (const auto &it : _vd.bridge_to_map_y) { // For each bridge for (const auto &it : _vd.bridge_to_map_y) { // For each bridge
TunnelBridgeToMap tbtm { it.first, it.second }; TunnelBridgeToMap tbtm { it.first, it.second };
ViewportMapDrawBridgeTunnel(vp, &tbtm, (GetBridgeHeight(tbtm.from_tile) - 1) * TILE_HEIGHT, false, w, h, blitter); ViewportMapDrawBridgeTunnel<is_32bpp>(vp, &tbtm, (GetBridgeHeight(tbtm.from_tile) - 1) * TILE_HEIGHT, false, w, h, blitter);
} }
} }
}
if (is_32bpp) {
blitter->SetRect32(_vd.dpi.dst_ptr, 0, 0, reinterpret_cast<uint32 *>(vp->land_pixel_cache.data()) + land_cache_start, h, w, vp->width);
} else {
blitter->SetRect(_vd.dpi.dst_ptr, 0, 0, reinterpret_cast<uint8 *>(vp->land_pixel_cache.data()) + land_cache_start, h, w, vp->width);
}
if (unlikely(HasBit(_viewport_debug_flags, VDF_SHOW_NO_LANDSCAPE_MAP_DRAW)) && !cache_updated) {
ViewportDrawDirtyBlocks();
++_dirty_block_colour;
}
} }
static void ViewportProcessParentSprites() static void ViewportProcessParentSprites()
@@ -3114,8 +3152,10 @@ void ViewportDoDraw(Viewport *vp, int left, int top, int right, int bottom)
_vd.dpi.pitch = old_dpi->pitch; _vd.dpi.pitch = old_dpi->pitch;
_vd.last_child = nullptr; _vd.last_child = nullptr;
int x = UnScaleByZoomLower(_vd.dpi.left - (vp->virtual_left & mask), vp->zoom) + vp->left; _vd.offset_x = UnScaleByZoomLower(_vd.dpi.left - (vp->virtual_left & mask), vp->zoom);
int y = UnScaleByZoomLower(_vd.dpi.top - (vp->virtual_top & mask), vp->zoom) + vp->top; _vd.offset_y = UnScaleByZoomLower(_vd.dpi.top - (vp->virtual_top & mask), vp->zoom);
int x = _vd.offset_x + vp->left;
int y = _vd.offset_y + vp->top;
_vd.dpi.dst_ptr = BlitterFactory::GetCurrentBlitter()->MoveTo(old_dpi->dst_ptr, x - old_dpi->left, y - old_dpi->top); _vd.dpi.dst_ptr = BlitterFactory::GetCurrentBlitter()->MoveTo(old_dpi->dst_ptr, x - old_dpi->left, y - old_dpi->top);
@@ -3346,8 +3386,16 @@ void UpdateViewportSizeZoom(Viewport *vp)
if (vp->zoom >= ZOOM_LVL_DRAW_MAP) { if (vp->zoom >= ZOOM_LVL_DRAW_MAP) {
memset(vp->map_draw_vehicles_cache.done_hash_bits, 0, sizeof(vp->map_draw_vehicles_cache.done_hash_bits)); memset(vp->map_draw_vehicles_cache.done_hash_bits, 0, sizeof(vp->map_draw_vehicles_cache.done_hash_bits));
vp->map_draw_vehicles_cache.vehicle_pixels.assign(vp->width * vp->height, false); vp->map_draw_vehicles_cache.vehicle_pixels.assign(vp->width * vp->height, false);
if (BlitterFactory::GetCurrentBlitter()->GetScreenDepth() == 32) {
vp->land_pixel_cache.assign(vp->height * vp->width * 4, 0xD7);
} else {
vp->land_pixel_cache.assign(vp->height * vp->width, 0xD7);
}
} else { } else {
vp->map_draw_vehicles_cache.vehicle_pixels.clear(); vp->map_draw_vehicles_cache.vehicle_pixels.clear();
vp->land_pixel_cache.clear();
vp->land_pixel_cache.shrink_to_fit();
} }
} }
@@ -3441,6 +3489,19 @@ void MarkViewportDirty(Viewport * const vp, int left, int top, int right, int bo
pos += column_skip; pos += column_skip;
} }
vp->is_dirty = true; vp->is_dirty = true;
if (unlikely(vp->zoom >= ZOOM_LVL_DRAW_MAP && !(flags & VMDF_NOT_LANDSCAPE))) {
uint l = UnScaleByZoomLower(left, vp->zoom);
uint t = UnScaleByZoomLower(top, vp->zoom);
uint w = UnScaleByZoom(right, vp->zoom) - l;
uint h = UnScaleByZoom(bottom, vp->zoom) - t;
uint bitdepth = BlitterFactory::GetCurrentBlitter()->GetScreenDepth() / 8;
uint8 *land_cache = vp->land_pixel_cache.data() + ((l + (t * vp->width)) * bitdepth);
while (--h) {
memset(land_cache, 0xD7, w * bitdepth);
land_cache += vp->width * bitdepth;
}
}
} }
/** /**
@@ -3474,7 +3535,7 @@ static void MarkRouteStepDirty(const TileIndex tile, uint order_nr)
for (Viewport * const vp : _viewport_window_cache) { for (Viewport * const vp : _viewport_window_cache) {
const int half_width = ScaleByZoom((_vp_route_step_width / 2) + 1, vp->zoom); const int half_width = ScaleByZoom((_vp_route_step_width / 2) + 1, vp->zoom);
const int height = ScaleByZoom(_vp_route_step_height_top + char_height * order_nr + _vp_route_step_height_bottom, vp->zoom); const int height = ScaleByZoom(_vp_route_step_height_top + char_height * order_nr + _vp_route_step_height_bottom, vp->zoom);
MarkViewportDirty(vp, pt.x - half_width, pt.y - height, pt.x + half_width, pt.y, VMDF_NONE); MarkViewportDirty(vp, pt.x - half_width, pt.y - height, pt.x + half_width, pt.y, VMDF_NOT_LANDSCAPE);
} }
} }
@@ -3503,7 +3564,30 @@ void MarkAllViewportMapsDirty(int left, int top, int right, int bottom)
Viewport *vp = w->viewport; Viewport *vp = w->viewport;
if (vp != nullptr && vp->zoom >= ZOOM_LVL_DRAW_MAP) { if (vp != nullptr && vp->zoom >= ZOOM_LVL_DRAW_MAP) {
assert(vp->width != 0); assert(vp->width != 0);
MarkViewportDirty(vp, left, top, right, bottom, VMDF_NONE); MarkViewportDirty(vp, left, top, right, bottom, VMDF_NOT_LANDSCAPE);
}
}
}
void MarkAllViewportMapLandscapesDirty()
{
Window *w;
FOR_ALL_WINDOWS_FROM_BACK(w) {
Viewport *vp = w->viewport;
if (vp != nullptr && vp->zoom >= ZOOM_LVL_DRAW_MAP) {
ClearViewportLandPixelCache(vp);
w->SetDirty();
}
}
}
void MarkWholeNonMapViewportsDirty()
{
Window *w;
FOR_ALL_WINDOWS_FROM_BACK(w) {
Viewport *vp = w->viewport;
if (vp != nullptr && vp->zoom < ZOOM_LVL_DRAW_MAP) {
w->SetDirty();
} }
} }
} }
@@ -3602,7 +3686,7 @@ void MarkViewportLineDirty(Viewport * const vp, const Point from_pt, const Point
} }
} }
void MarkTileLineDirty(const TileIndex from_tile, const TileIndex to_tile) void MarkTileLineDirty(const TileIndex from_tile, const TileIndex to_tile, ViewportMarkDirtyFlags flags)
{ {
assert(from_tile != INVALID_TILE); assert(from_tile != INVALID_TILE);
assert(to_tile != INVALID_TILE); assert(to_tile != INVALID_TILE);
@@ -3629,7 +3713,7 @@ void MarkTileLineDirty(const TileIndex from_tile, const TileIndex to_tile)
(y1 - 1) * block_radius, (y1 - 1) * block_radius,
(x1 + 1) * block_radius, (x1 + 1) * block_radius,
(y1 + 1) * block_radius, (y1 + 1) * block_radius,
VMDF_NONE flags
); );
if (x1 == x2 && y1 == y2) break; if (x1 == x2 && y1 == y2) break;
const int e2 = 2 * err; const int e2 = 2 * err;
@@ -3647,7 +3731,7 @@ void MarkTileLineDirty(const TileIndex from_tile, const TileIndex to_tile)
static void MarkRoutePathsDirty(const std::vector<DrawnPathRouteTileLine> &lines) static void MarkRoutePathsDirty(const std::vector<DrawnPathRouteTileLine> &lines)
{ {
for (std::vector<DrawnPathRouteTileLine>::const_iterator it = lines.begin(); it != lines.end(); ++it) { for (std::vector<DrawnPathRouteTileLine>::const_iterator it = lines.begin(); it != lines.end(); ++it) {
MarkTileLineDirty(it->from_tile, it->to_tile); MarkTileLineDirty(it->from_tile, it->to_tile, VMDF_NOT_LANDSCAPE);
} }
} }
@@ -3662,7 +3746,7 @@ void MarkAllRoutePathsDirty(const Vehicle *veh)
break; break;
} }
for (const auto &iter : _vp_route_paths) { for (const auto &iter : _vp_route_paths) {
MarkTileLineDirty(iter.from_tile, iter.to_tile); MarkTileLineDirty(iter.from_tile, iter.to_tile, VMDF_NOT_LANDSCAPE);
} }
_vp_route_paths_last_mark_dirty.swap(_vp_route_paths); _vp_route_paths_last_mark_dirty.swap(_vp_route_paths);
_vp_route_paths.clear(); _vp_route_paths.clear();
@@ -3758,7 +3842,7 @@ static void SetSelectionTilesDirty()
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 = 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 */ /* 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); MarkAllViewportsDirty(l - OVERLAY_WIDTH, t - OVERLAY_WIDTH - TILE_HEIGHT * ZOOM_LVL_BASE, r + OVERLAY_WIDTH, b + OVERLAY_WIDTH, VMDF_NOT_MAP_MODE);
/* haven't we reached the topmost tile yet? */ /* haven't we reached the topmost tile yet? */
if (top_x != x_start) { if (top_x != x_start) {
@@ -3787,7 +3871,7 @@ static void SetSelectionTilesDirty()
uint y = (_thd.pos.y + (a - b) / 2) / TILE_SIZE; uint y = (_thd.pos.y + (a - b) / 2) / TILE_SIZE;
if (x < MapMaxX() && y < MapMaxY()) { if (x < MapMaxX() && y < MapMaxY()) {
MarkTileDirtyByTile(TileXY(x, y)); MarkTileDirtyByTile(TileXY(x, y), VMDF_NOT_MAP_MODE);
} }
} }
} }
@@ -5495,13 +5579,14 @@ void ResetObjectToPlace()
SetObjectToPlace(SPR_CURSOR_MOUSE, PAL_NONE, HT_NONE, WC_MAIN_WINDOW, 0); SetObjectToPlace(SPR_CURSOR_MOUSE, PAL_NONE, HT_NONE, WC_MAIN_WINDOW, 0);
} }
ViewportMapType ChangeRenderMode(const Viewport *vp, bool down) { void ChangeRenderMode(Viewport *vp, bool down) {
ViewportMapType map_type = vp->map_type; ViewportMapType map_type = vp->map_type;
if (vp->zoom < ZOOM_LVL_DRAW_MAP) return map_type; if (vp->zoom < ZOOM_LVL_DRAW_MAP) return;
ClearViewportLandPixelCache(vp);
if (down) { if (down) {
return (map_type == VPMT_MIN) ? VPMT_MAX : (ViewportMapType) (map_type - 1); vp->map_type = (map_type == VPMT_MIN) ? VPMT_MAX : (ViewportMapType) (map_type - 1);
} else { } else {
return (map_type == VPMT_MAX) ? VPMT_MIN : (ViewportMapType) (map_type + 1); vp->map_type = (map_type == VPMT_MAX) ? VPMT_MIN : (ViewportMapType) (map_type + 1);
} }
} }
@@ -5644,17 +5729,17 @@ void StoreRailPlacementEndpoints(TileIndex start_tile, TileIndex end_tile, Track
static void MarkCatchmentTilesDirty() static void MarkCatchmentTilesDirty()
{ {
if (_viewport_highlight_town != nullptr) { if (_viewport_highlight_town != nullptr) {
MarkWholeScreenDirty(); MarkWholeNonMapViewportsDirty();
return; return;
} }
if (_viewport_highlight_station != nullptr) { if (_viewport_highlight_station != nullptr) {
if (_viewport_highlight_station->catchment_tiles.tile == INVALID_TILE) { if (_viewport_highlight_station->catchment_tiles.tile == INVALID_TILE) {
MarkWholeScreenDirty(); MarkWholeNonMapViewportsDirty();
_viewport_highlight_station = nullptr; _viewport_highlight_station = nullptr;
} else { } else {
BitmapTileIterator it(_viewport_highlight_station->catchment_tiles); BitmapTileIterator it(_viewport_highlight_station->catchment_tiles);
for (TileIndex tile = it; tile != INVALID_TILE; tile = ++it) { for (TileIndex tile = it; tile != INVALID_TILE; tile = ++it) {
MarkTileDirtyByTile(tile); MarkTileDirtyByTile(tile, VMDF_NOT_MAP_MODE);
} }
} }
} }
@@ -5742,10 +5827,10 @@ void SetViewportCatchmentTown(const Town *t, bool sel)
if (sel && _viewport_highlight_town != t) { if (sel && _viewport_highlight_town != t) {
_viewport_highlight_station = nullptr; _viewport_highlight_station = nullptr;
_viewport_highlight_town = t; _viewport_highlight_town = t;
MarkWholeScreenDirty(); MarkWholeNonMapViewportsDirty();
} else if (!sel && _viewport_highlight_town == t) { } else if (!sel && _viewport_highlight_town == t) {
_viewport_highlight_town = nullptr; _viewport_highlight_town = nullptr;
MarkWholeScreenDirty(); MarkWholeNonMapViewportsDirty();
} }
if (_viewport_highlight_town != nullptr) SetWindowDirty(WC_TOWN_VIEW, _viewport_highlight_town->index); if (_viewport_highlight_town != nullptr) SetWindowDirty(WC_TOWN_VIEW, _viewport_highlight_town->index);
} }

View File

@@ -36,10 +36,12 @@ void UpdateViewportSizeZoom(Viewport *vp);
void MarkViewportDirty(Viewport * const vp, int left, int top, int right, int bottom, ViewportMarkDirtyFlags flags); void MarkViewportDirty(Viewport * const vp, int left, int top, int right, int bottom, ViewportMarkDirtyFlags flags);
void MarkAllViewportsDirty(int left, int top, int right, int bottom, ViewportMarkDirtyFlags flags = VMDF_NONE); void MarkAllViewportsDirty(int left, int top, int right, int bottom, ViewportMarkDirtyFlags flags = VMDF_NONE);
void MarkAllViewportMapsDirty(int left, int top, int right, int bottom); void MarkAllViewportMapsDirty(int left, int top, int right, int bottom);
void MarkAllViewportMapLandscapesDirty();
void MarkWholeNonMapViewportsDirty();
void MarkAllViewportOverlayStationLinksDirty(const Station *st); void MarkAllViewportOverlayStationLinksDirty(const Station *st);
void MarkAllRouteStepsDirty(const Vehicle *veh); void MarkAllRouteStepsDirty(const Vehicle *veh);
void MarkViewportLineDirty(Viewport * const vp, const Point from_pt, const Point to_pt, const int block_radius, ViewportMarkDirtyFlags flags); void MarkViewportLineDirty(Viewport * const vp, const Point from_pt, const Point to_pt, const int block_radius, ViewportMarkDirtyFlags flags);
void MarkTileLineDirty(const TileIndex from_tile, const TileIndex to_tile); void MarkTileLineDirty(const TileIndex from_tile, const TileIndex to_tile, ViewportMarkDirtyFlags flags);
void MarkAllRoutePathsDirty(const Vehicle *veh); void MarkAllRoutePathsDirty(const Vehicle *veh);
void CheckMarkDirtyFocusedRoutePaths(const Vehicle *veh); void CheckMarkDirtyFocusedRoutePaths(const Vehicle *veh);
@@ -112,7 +114,7 @@ static inline void MarkTileDirtyByTile(TileIndex tile, ViewportMarkDirtyFlags fl
void MarkTileGroundDirtyByTile(TileIndex tile, ViewportMarkDirtyFlags flags); void MarkTileGroundDirtyByTile(TileIndex tile, ViewportMarkDirtyFlags flags);
ViewportMapType ChangeRenderMode(const Viewport *vp, bool down); void ChangeRenderMode(Viewport *vp, bool down);
Point GetViewportStationMiddle(const Viewport *vp, const Station *st); Point GetViewportStationMiddle(const Viewport *vp, const Station *st);

View File

@@ -144,7 +144,7 @@ public:
{ {
if (_ctrl_pressed) { if (_ctrl_pressed) {
/* Cycle through the drawing modes */ /* Cycle through the drawing modes */
this->viewport->map_type = ChangeRenderMode(this->viewport, wheel < 0); ChangeRenderMode(this->viewport, wheel < 0);
this->SetDirty(); this->SetDirty();
} else if (_settings_client.gui.scrollwheel_scrolling != 2) { } else if (_settings_client.gui.scrollwheel_scrolling != 2) {
ZoomInOrOutToCursorWindow(wheel < 0, this); ZoomInOrOutToCursorWindow(wheel < 0, this);

View File

@@ -60,6 +60,7 @@ struct Viewport {
bool is_dirty = false; bool is_dirty = false;
bool is_drawn = false; bool is_drawn = false;
ViewPortMapDrawVehiclesCache map_draw_vehicles_cache; ViewPortMapDrawVehiclesCache map_draw_vehicles_cache;
std::vector<byte> land_pixel_cache;
uint GetDirtyBlockWidthShift() const { return this->GetDirtyBlockShift(); } uint GetDirtyBlockWidthShift() const { return this->GetDirtyBlockShift(); }
uint GetDirtyBlockHeightShift() const { return this->GetDirtyBlockShift(); } uint GetDirtyBlockHeightShift() const { return this->GetDirtyBlockShift(); }
@@ -218,6 +219,7 @@ enum FoundationPart {
enum ViewportMarkDirtyFlags : byte { enum ViewportMarkDirtyFlags : byte {
VMDF_NONE = 0, VMDF_NONE = 0,
VMDF_NOT_MAP_MODE = 0x1, VMDF_NOT_MAP_MODE = 0x1,
VMDF_NOT_LANDSCAPE = 0x2,
}; };
DECLARE_ENUM_AS_BIT_SET(ViewportMarkDirtyFlags) DECLARE_ENUM_AS_BIT_SET(ViewportMarkDirtyFlags)

View File

@@ -410,7 +410,7 @@ void ZoningMarkDirtyStationCoverageArea(const Station *st, ZoningModeMask mask)
Rect rect = st->GetCatchmentRectUsingRadius(radius); Rect rect = st->GetCatchmentRectUsingRadius(radius);
for (int y = rect.top; y <= rect.bottom; y++) { for (int y = rect.top; y <= rect.bottom; y++) {
for (int x = rect.left; x <= rect.right; x++) { for (int x = rect.left; x <= rect.right; x++) {
MarkTileDirtyByTile(TileXY(x, y)); MarkTileDirtyByTile(TileXY(x, y), VMDF_NOT_MAP_MODE);
} }
} }
auto invalidate_cache_rect = [&](btree::btree_set<uint32> &cache) { auto invalidate_cache_rect = [&](btree::btree_set<uint32> &cache) {
@@ -441,7 +441,7 @@ void ZoningTownAuthorityRatingChange()
if (_zoning.inner == ZEM_AUTHORITY) mask |= ZMM_INNER; if (_zoning.inner == ZEM_AUTHORITY) mask |= ZMM_INNER;
if (_zoning.outer == ZEM_AUTHORITY) mask |= ZMM_OUTER; if (_zoning.outer == ZEM_AUTHORITY) mask |= ZMM_OUTER;
if (mask != ZMM_NOTHING) { if (mask != ZMM_NOTHING) {
MarkWholeScreenDirty(); MarkWholeNonMapViewportsDirty();
} }
} }
@@ -460,5 +460,5 @@ void SetZoningMode(bool inner, ZoningEvaluationMode mode)
current_mode = mode; current_mode = mode;
cache.clear(); cache.clear();
MarkWholeScreenDirty(); MarkWholeNonMapViewportsDirty();
} }