diff --git a/src/blitter/32bpp_anim.cpp b/src/blitter/32bpp_anim.cpp index 38cc577cda..5c674edd4e 100644 --- a/src/blitter/32bpp_anim.cpp +++ b/src/blitter/32bpp_anim.cpp @@ -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; if (_screen_disable_anim) { do { - *dst = LookupColourInPalette(*colours); - dst++; - colours++; - } while (--width); + uint w = width; + do { + *dst = LookupColourInPalette(*colours); + dst++; + colours++; + } while (--w); + dst += _screen.pitch - width; + colours += pitch - width; + } while (--lines); } else { uint16 *dstanim = (uint16 *)(&this->anim_buf[this->ScreenToAnimOffset((uint32 *)video) + x + y * this->anim_buf_pitch]); do { - *dstanim = *colours | (DEFAULT_BRIGHTNESS << 8); - *dst = LookupColourInPalette(*colours); - dst++; - dstanim++; - colours++; - } while (--width); + uint w = width; + do { + *dstanim = *colours | (DEFAULT_BRIGHTNESS << 8); + *dst = LookupColourInPalette(*colours); + dst++; + dstanim++; + colours++; + } 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) { do { - *dst = *colours; - dst++; - colours++; - } while (--width); + memcpy(dst, colours, width * sizeof(uint32)); + dst += _screen.pitch; + colours += pitch; + } while (--lines); } else { uint16 *dstanim = (uint16 *)(&this->anim_buf[this->ScreenToAnimOffset((uint32 *)video) + x + y * this->anim_buf_pitch]); do { - *dstanim = 0; - *dst = *colours; - dst++; - dstanim++; - colours++; - } while (--width); + memcpy(dst, colours, width * sizeof(uint32)); + memset(dstanim, 0, width * sizeof(uint16)); + dst += _screen.pitch; + dstanim += this->anim_buf_pitch; + colours += pitch; + } while (--lines); } } diff --git a/src/blitter/32bpp_anim.hpp b/src/blitter/32bpp_anim.hpp index 1ff745632c..90d1b544da 100644 --- a/src/blitter/32bpp_anim.hpp +++ b/src/blitter/32bpp_anim.hpp @@ -39,8 +39,8 @@ public: void DrawColourMappingRect(void *dst, int width, int height, PaletteID pal) 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 SetLine(void *video, int x, int y, uint8 *colours, uint width) override; - void SetLine32(void *video, int x, int y, uint32 *colours, uint width) override; + void SetRect(void *video, int x, int y, const uint8 *colours, uint lines, uint width, uint pitch) 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 CopyFromBuffer(void *video, const void *src, int width, int height) override; void CopyToBuffer(const void *video, void *dst, int width, int height) override; diff --git a/src/blitter/32bpp_base.cpp b/src/blitter/32bpp_base.cpp index 9d02ad8fa5..ac29d7536b 100644 --- a/src/blitter/32bpp_base.cpp +++ b/src/blitter/32bpp_base.cpp @@ -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; do { - *dst = LookupColourInPalette(*colours); - dst++; - colours++; - } while (--width); + uint w = width; + do { + *dst = LookupColourInPalette(*colours); + dst++; + colours++; + } 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 { - *dst = *colours; - dst++; - colours++; - } while (--width); + memcpy(dst, colours, width * sizeof(uint32)); + dst += _screen.pitch; + colours += pitch; + } while (--lines); } void Blitter_32bppBase::DrawRect(void *video, int width, int height, uint8 colour) diff --git a/src/blitter/32bpp_base.hpp b/src/blitter/32bpp_base.hpp index 4992c3e022..e8bca1efed 100644 --- a/src/blitter/32bpp_base.hpp +++ b/src/blitter/32bpp_base.hpp @@ -22,8 +22,8 @@ public: void *MoveTo(void *video, int x, int y) 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 SetLine(void *video, int x, int y, uint8 *colours, uint width) override; - void SetLine32(void *video, int x, int y, uint32 *colours, uint width) override; + void SetRect(void *video, int x, int y, const uint8 *colours, uint lines, uint width, uint pitch) 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 CopyFromBuffer(void *video, const void *src, int width, int height) override; void CopyToBuffer(const void *video, void *dst, int width, int height) override; diff --git a/src/blitter/8bpp_base.cpp b/src/blitter/8bpp_base.cpp index ed91ed1d20..436c5c387e 100644 --- a/src/blitter/8bpp_base.cpp +++ b/src/blitter/8bpp_base.cpp @@ -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) diff --git a/src/blitter/8bpp_base.hpp b/src/blitter/8bpp_base.hpp index a51e17d590..359121b535 100644 --- a/src/blitter/8bpp_base.hpp +++ b/src/blitter/8bpp_base.hpp @@ -20,7 +20,7 @@ public: void *MoveTo(void *video, int x, int y) 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 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 CopyFromBuffer(void *video, const void *src, int width, int height) override; void CopyToBuffer(const void *video, void *dst, int width, int height) override; diff --git a/src/blitter/base.hpp b/src/blitter/base.hpp index f956459951..dbb1b5feac 100644 --- a/src/blitter/base.hpp +++ b/src/blitter/base.hpp @@ -115,24 +115,28 @@ public: 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 x The x position within video-buffer. * @param y The y position within video-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 x The x position within video-buffer. * @param y The y position within video-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. diff --git a/src/blitter/null.hpp b/src/blitter/null.hpp index 187afcf166..822d504dae 100644 --- a/src/blitter/null.hpp +++ b/src/blitter/null.hpp @@ -23,8 +23,8 @@ public: void SetPixel(void *video, int x, int y, 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 SetLine(void *video, int x, int y, uint8 *colours, uint width) override {}; - void SetLine32(void *video, int x, int y, uint32 *colours, uint width) override {}; + void SetRect(void *video, int x, int y, const uint8 *colours, uint lines, uint width, uint pitch) 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 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 {}; diff --git a/src/gfx.cpp b/src/gfx.cpp index 52b68bfff9..62066b5fc8 100644 --- a/src/gfx.cpp +++ b/src/gfx.cpp @@ -1328,9 +1328,6 @@ void ScreenSizeChanged() { MarkWholeScreenDirty(); - extern uint32 *_vp_map_line; - _vp_map_line = ReallocT(_vp_map_line, _screen.width); - /* screen size changed and the old bitmap is invalid now, so we don't want to undraw it */ _cursor.visible = false; } diff --git a/src/linkgraph/linkgraph_gui.cpp b/src/linkgraph/linkgraph_gui.cpp index a054194fb0..1e4cee65ef 100644 --- a/src/linkgraph/linkgraph_gui.cpp +++ b/src/linkgraph/linkgraph_gui.cpp @@ -88,18 +88,18 @@ void LinkGraphOverlay::MarkStationViewportLinksDirty(const Station *st) Viewport *vp = this->window->viewport; const Point pt = RemapCoords2(TileX(st->xy) * TILE_SIZE, TileY(st->xy) * TILE_SIZE); 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); for (LinkList::iterator i(this->cached_links.begin()); i != this->cached_links.end(); ++i) { if (i->from_id == st->index) { const Station *stb = Station::GetIfValid(i->to_id); 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) { const Station *sta = Station::GetIfValid(i->from_id); 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); } } } diff --git a/src/main_gui.cpp b/src/main_gui.cpp index d5248e0982..95366269a3 100644 --- a/src/main_gui.cpp +++ b/src/main_gui.cpp @@ -416,19 +416,19 @@ struct MainWindow : Window case GHK_CHANGE_MAP_MODE_PREV: 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(); } else if (this->viewport->zoom >= ZOOM_LVL_DRAW_MAP) { - this->viewport->map_type = ChangeRenderMode(this->viewport, true); + ChangeRenderMode(this->viewport, true); this->SetDirty(); } break; case GHK_CHANGE_MAP_MODE_NEXT: 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(); } else if (this->viewport->zoom >= ZOOM_LVL_DRAW_MAP) { - this->viewport->map_type = ChangeRenderMode(this->viewport, false); + ChangeRenderMode(this->viewport, false); this->SetDirty(); } break; @@ -451,7 +451,7 @@ struct MainWindow : Window { if (_ctrl_pressed) { /* Cycle through the drawing modes */ - this->viewport->map_type = ChangeRenderMode(this->viewport, wheel < 0); + ChangeRenderMode(this->viewport, wheel < 0); this->SetDirty(); } else if (_settings_client.gui.scrollwheel_scrolling != 2) { ZoomInOrOutToCursorWindow(wheel < 0, this); diff --git a/src/plans_base.h b/src/plans_base.h index 31b13d5172..81d31fb17d 100644 --- a/src/plans_base.h +++ b/src/plans_base.h @@ -56,7 +56,7 @@ struct PlanLine { if (cnt > 0) { const TileIndex last_tile = this->tiles[cnt - 1]; if (last_tile == tile) return false; - MarkTileLineDirty(last_tile, tile); + MarkTileLineDirty(last_tile, tile, VMDF_NOT_LANDSCAPE); if (cnt > 1) { 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. /* The new tile is in the continuity, just update the last tile. */ this->tiles[cnt - 1] = tile; - MarkTileLineDirty(t1, tile); + MarkTileLineDirty(t1, tile, VMDF_NOT_LANDSCAPE); return true; } } @@ -107,7 +107,7 @@ struct PlanLine { { const uint sz = (uint) this->tiles.size(); 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); } } diff --git a/src/settings.cpp b/src/settings.cpp index 4e0aec5b6e..dbe5017b81 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -1343,7 +1343,19 @@ static bool ViewportMapShowTunnelModeChanged(int32 p1) { extern void 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) diff --git a/src/table/settings.ini b/src/table/settings.ini index 410c8b54f9..b77df8cafa 100644 --- a/src/table/settings.ini +++ b/src/table/settings.ini @@ -54,6 +54,7 @@ static bool SimulatedWormholeSignalsChanged(int32 p1); static bool EnableSingleVehSharedOrderGuiChanged(int32 p1); static bool CheckYapfRailSignalPenalties(int32 p1); static bool ViewportMapShowTunnelModeChanged(int32 p1); +static bool ViewportMapLandscapeModeChanged(int32 p1); static bool UpdateLinkgraphColours(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 def = true str = STR_CONFIG_SETTING_VIEWPORT_MAP_SCAN_SURROUNDINGS -proc = RedrawScreen +proc = ViewportMapLandscapeModeChanged [SDTC_BOOL] var = gui.show_slopes_on_viewport_map flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC def = true str = STR_CONFIG_SETTING_VIEWPORT_MAP_SHOW_SLOPES -proc = RedrawScreen +proc = ViewportMapLandscapeModeChanged [SDTC_BOOL] var = gui.show_bridges_on_map flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC def = true str = STR_CONFIG_SETTING_VIEWPORT_MAP_SHOW_BRIDGES -proc = RedrawScreen +proc = ViewportMapLandscapeModeChanged [SDTC_BOOL] 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 def = false str = STR_CONFIG_SETTING_VIEWPORT_MAP_USE_OWNER_COLOUR_BRIDGE_TUNNEL -proc = RedrawScreen +proc = ViewportMapLandscapeModeChanged [SDTC_VAR] var = gui.show_scrolling_viewport_on_map diff --git a/src/town_gui.cpp b/src/town_gui.cpp index 9f949ded99..7dc5266746 100644 --- a/src/town_gui.cpp +++ b/src/town_gui.cpp @@ -275,7 +275,7 @@ public: this->town->show_zone = new_show_state; this->SetWidgetLoweredState(widget, new_show_state); - MarkWholeScreenDirty(); + MarkWholeNonMapViewportsDirty(); break; } diff --git a/src/train_cmd.cpp b/src/train_cmd.cpp index fe9ec465fc..7202a5b0d9 100644 --- a/src/train_cmd.cpp +++ b/src/train_cmd.cpp @@ -2303,7 +2303,7 @@ void ReverseTrainDirection(Train *v) if (IsTunnelBridgeWithSignalSimulation(v->tile) && IsTunnelBridgeSignalSimulationEntrance(v->tile)) { /* Flip signal on tunnel entrance tile red. */ SetTunnelBridgeEntranceSignalState(v->tile, SIGNAL_STATE_RED); - MarkTileDirtyByTile(v->tile); + MarkTileDirtyByTile(v->tile, VMDF_NOT_MAP_MODE); /* Clear counters. */ v->wait_counter = 0; v->tunnel_bridge_signal_num = 0; @@ -2750,9 +2750,9 @@ static void HandleLastTunnelBridgeSignals(TileIndex tile, TileIndex end, DiagDir int signal_offset = GetAndClearLastBridgeEntranceSetSignalIndex(end); if (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) { /* 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) { SetTunnelBridgeEntranceSignalState(end, SIGNAL_STATE_GREEN); - MarkTileDirtyByTile(end); + MarkTileDirtyByTile(end, VMDF_NOT_MAP_MODE); } if (IsTunnelBridgeSignalSimulationEntrance(tile) && GetTunnelBridgeEntranceSignalState(tile) == SIGNAL_STATE_RED) { 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. */ if (IsTunnelBridgeSignalSimulationEntrance(tile) && GetTunnelBridgeEntranceSignalState(tile) == SIGNAL_STATE_RED) { SetTunnelBridgeEntranceSignalState(tile, SIGNAL_STATE_GREEN); - MarkTileDirtyByTile(tile); + MarkTileDirtyByTile(tile, VMDF_NOT_MAP_MODE); } } else if (IsBridge(v->tile) && signal_number >= 0) { 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. */ SetTunnelBridgeEntranceSignalState(gp.new_tile, SIGNAL_STATE_RED); - MarkTileDirtyByTile(gp.new_tile); + MarkTileDirtyByTile(gp.new_tile, VMDF_NOT_MAP_MODE); if (IsTunnelBridgeSignalSimulationBidirectional(gp.new_tile)) { /* Set incoming signal in other direction to red as well */ TileIndex other_end = GetOtherTunnelBridgeEnd(gp.new_tile); 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*/ if (distance == 0 && IsBridge(v->tile)) { SetBridgeEntranceSimulatedSignalState(v->tile, v->tunnel_bridge_signal_num, SIGNAL_STATE_RED); - MarkTileDirtyByTile(gp.new_tile); + MarkTileDirtyByTile(gp.new_tile, VMDF_NOT_MAP_MODE); } } } diff --git a/src/tree_gui.cpp b/src/tree_gui.cpp index eaff881897..9f152e4903 100644 --- a/src/tree_gui.cpp +++ b/src/tree_gui.cpp @@ -16,6 +16,7 @@ #include "command_func.h" #include "sound_func.h" #include "tree_map.h" +#include "viewport_func.h" #include "widgets/tree_widget.h" @@ -117,13 +118,13 @@ public: case WID_BT_MANY_RANDOM: // place trees randomly over the landscape if (_settings_client.sound.confirm) SndPlayFx(SND_15_BEEP); PlaceTreesRandomly(); - MarkWholeScreenDirty(); + MarkWholeNonMapViewportsDirty(); break; case WID_BT_REMOVE_ALL: // remove all trees over the landscape if (_settings_client.sound.confirm) SndPlayFx(SND_15_BEEP); RemoveAllTrees(); - MarkWholeScreenDirty(); + MarkWholeNonMapViewportsDirty(); break; } diff --git a/src/vehicle.cpp b/src/vehicle.cpp index f3008a6f09..19f2362ce2 100644 --- a/src/vehicle.cpp +++ b/src/vehicle.cpp @@ -2332,7 +2332,7 @@ void Vehicle::UpdateViewport(bool dirty) min(old_coord.top, this->coord.top), max(old_coord.right, this->coord.right), 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 { - ::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 diff --git a/src/viewport.cpp b/src/viewport.cpp index 8e8ba63633..6cfcfc69f3 100644 --- a/src/viewport.cpp +++ b/src/viewport.cpp @@ -233,6 +233,8 @@ struct BridgeSetYComparator { /** Data structure storing rendering information */ struct ViewportDrawer { DrawPixelInfo dpi; + int offset_x; + int offset_y; StringSpriteToDrawVector string_sprites_to_draw; TileSpriteToDrawVector tile_sprites_to_draw; @@ -325,6 +327,7 @@ enum ViewportDebugFlags { VDF_DIRTY_WHOLE_VIEWPORT, VDF_DIRTY_BLOCK_PER_SPLIT, VDF_DISABLE_DRAW_SPLIT, + VDF_SHOW_NO_LANDSCAPE_MAP_DRAW, }; uint32 _viewport_debug_flags; @@ -336,6 +339,11 @@ static Point MapXYZToViewport(const Viewport *vp, int x, int y, int z) return p; } +void ClearViewportLandPixelCache(Viewport *vp) +{ + vp->land_pixel_cache.assign(vp->land_pixel_cache.size(), 0xD7); +} + void ClearViewportCache(Viewport *vp) { 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 (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)); DoSetViewportPosition((Window *) w->z_front, left, top, width, height); 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. - -static void ViewportMapDrawBridgeTunnel(const Viewport * const vp, const TunnelBridgeToMap * const tbtm, const int z, +template +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) { 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); 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); + if (IsInsideMM(y, 0, h)) { + uint idx = (x + _vd.offset_x) + ((y + _vd.offset_y) * vp->width); + if (is_32bpp) { + reinterpret_cast(vp->land_pixel_cache.data())[idx] = COL8TO32(colour); + } else { + reinterpret_cast(vp->land_pixel_cache.data())[idx] = colour; + } + } } } } /** Draw the map on a viewport. */ template -void ViewportMapDraw(const Viewport * const vp) +void ViewportMapDraw(Viewport * const vp) { assert(vp != nullptr); Blitter * const blitter = BlitterFactory::GetCurrentBlitter(); @@ -2942,31 +2957,41 @@ void ViewportMapDraw(const Viewport * const vp) const int h = UnScaleByZoom(_vd.dpi.height, vp->zoom); int j = 0; + const int land_cache_start = _vd.offset_x + (_vd.offset_y * vp->width); + uint32 *land_cache_ptr32 = reinterpret_cast(vp->land_pixel_cache.data()) + land_cache_start; + uint8 *land_cache_ptr8 = reinterpret_cast(vp->land_pixel_cache.data()) + land_cache_start; + + bool cache_updated = false; + /* Render base map. */ do { // For each line int i = w; uint colour_index = colour_index_base; 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 d = b + a; do { // For each pixel of a line if (is_32bpp) { - *vp_map_line_ptr32 = ViewportMapGetColour(vp, c, d, colour_index); - vp_map_line_ptr32++; + if (*land_cache_ptr32 == 0xD7D7D7D7) { + *land_cache_ptr32 = ViewportMapGetColour(vp, c, d, colour_index); + cache_updated = true; + } + land_cache_ptr32++; } else { - *vp_map_line_ptr8 = (uint8) ViewportMapGetColour(vp, c, d, colour_index); - vp_map_line_ptr8++; + if (*land_cache_ptr8 == 0xD7) { + *land_cache_ptr8 = (uint8) ViewportMapGetColour(vp, c, d, colour_index); + cache_updated = true; + } + land_cache_ptr8++; } colour_index = (colour_index + 1) & 3; c -= incr_a; d += incr_a; } while (--i); if (is_32bpp) { - blitter->SetLine32(_vd.dpi.dst_ptr, 0, j, _vp_map_line, w); + land_cache_ptr32 += (vp->width - w); } else { - blitter->SetLine(_vd.dpi.dst_ptr, 0, j, (uint8*) _vp_map_line, w); + land_cache_ptr8 += (vp->width - w); } b += incr_b; } while (++j < h); @@ -2989,34 +3014,47 @@ void ViewportMapDraw(const Viewport * const vp) 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, &ttm.tb, tunnel_z, true, w, h, blitter); + ViewportMapDrawBridgeTunnel(vp, &ttm.tb, tunnel_z, true, w, h, blitter); } }; - /* Render tunnels */ - 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_max = _vd.dpi.top + _vd.dpi.height + ((_vd.dpi.left + _vd.dpi.width) / 2); - draw_tunnels(y_intercept_min, y_intercept_max, _vd.tunnel_to_map_x); - } - if (_settings_client.gui.show_tunnels_on_map && _vd.tunnel_to_map_y.tunnels.size() != 0) { - const int y_intercept_min = _vd.dpi.top - ((_vd.dpi.left + _vd.dpi.width) / 2); - const int y_intercept_max = _vd.dpi.top + _vd.dpi.height - (_vd.dpi.left / 2); - draw_tunnels(y_intercept_min, y_intercept_max, _vd.tunnel_to_map_y); + if (cache_updated) { + /* Render tunnels */ + 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_max = _vd.dpi.top + _vd.dpi.height + ((_vd.dpi.left + _vd.dpi.width) / 2); + draw_tunnels(y_intercept_min, y_intercept_max, _vd.tunnel_to_map_x); + } + if (_settings_client.gui.show_tunnels_on_map && _vd.tunnel_to_map_y.tunnels.size() != 0) { + const int y_intercept_min = _vd.dpi.top - ((_vd.dpi.left + _vd.dpi.width) / 2); + const int y_intercept_max = _vd.dpi.top + _vd.dpi.height - (_vd.dpi.left / 2); + draw_tunnels(y_intercept_min, y_intercept_max, _vd.tunnel_to_map_y); + } + + /* Render bridges */ + 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 + TunnelBridgeToMap tbtm { it.first, it.second }; + ViewportMapDrawBridgeTunnel(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) { + for (const auto &it : _vd.bridge_to_map_y) { // For each bridge + TunnelBridgeToMap tbtm { it.first, it.second }; + ViewportMapDrawBridgeTunnel(vp, &tbtm, (GetBridgeHeight(tbtm.from_tile) - 1) * TILE_HEIGHT, false, w, h, blitter); + } + } } - /* Render bridges */ - 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 - TunnelBridgeToMap tbtm { it.first, it.second }; - ViewportMapDrawBridgeTunnel(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(vp->land_pixel_cache.data()) + land_cache_start, h, w, vp->width); + } else { + blitter->SetRect(_vd.dpi.dst_ptr, 0, 0, reinterpret_cast(vp->land_pixel_cache.data()) + land_cache_start, h, w, vp->width); } - 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 - TunnelBridgeToMap tbtm { it.first, it.second }; - ViewportMapDrawBridgeTunnel(vp, &tbtm, (GetBridgeHeight(tbtm.from_tile) - 1) * TILE_HEIGHT, false, w, h, blitter); - } + + if (unlikely(HasBit(_viewport_debug_flags, VDF_SHOW_NO_LANDSCAPE_MAP_DRAW)) && !cache_updated) { + ViewportDrawDirtyBlocks(); + ++_dirty_block_colour; } } @@ -3114,8 +3152,10 @@ void ViewportDoDraw(Viewport *vp, int left, int top, int right, int bottom) _vd.dpi.pitch = old_dpi->pitch; _vd.last_child = nullptr; - int x = UnScaleByZoomLower(_vd.dpi.left - (vp->virtual_left & mask), vp->zoom) + vp->left; - int y = UnScaleByZoomLower(_vd.dpi.top - (vp->virtual_top & mask), vp->zoom) + vp->top; + _vd.offset_x = UnScaleByZoomLower(_vd.dpi.left - (vp->virtual_left & mask), vp->zoom); + _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); @@ -3346,8 +3386,16 @@ void UpdateViewportSizeZoom(Viewport *vp) 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)); 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 { 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; } 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) { 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); - 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; if (vp != nullptr && vp->zoom >= ZOOM_LVL_DRAW_MAP) { 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(to_tile != INVALID_TILE); @@ -3629,7 +3713,7 @@ void MarkTileLineDirty(const TileIndex from_tile, const TileIndex to_tile) (y1 - 1) * block_radius, (x1 + 1) * block_radius, (y1 + 1) * block_radius, - VMDF_NONE + flags ); if (x1 == x2 && y1 == y2) break; 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 &lines) { for (std::vector::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; } 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.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) /* 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? */ if (top_x != x_start) { @@ -3787,7 +3871,7 @@ static void SetSelectionTilesDirty() uint y = (_thd.pos.y + (a - b) / 2) / TILE_SIZE; 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); } -ViewportMapType ChangeRenderMode(const Viewport *vp, bool down) { +void ChangeRenderMode(Viewport *vp, bool down) { 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) { - 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 { - 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() { if (_viewport_highlight_town != nullptr) { - MarkWholeScreenDirty(); + MarkWholeNonMapViewportsDirty(); return; } if (_viewport_highlight_station != nullptr) { if (_viewport_highlight_station->catchment_tiles.tile == INVALID_TILE) { - MarkWholeScreenDirty(); + MarkWholeNonMapViewportsDirty(); _viewport_highlight_station = nullptr; } else { BitmapTileIterator it(_viewport_highlight_station->catchment_tiles); 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) { _viewport_highlight_station = nullptr; _viewport_highlight_town = t; - MarkWholeScreenDirty(); + MarkWholeNonMapViewportsDirty(); } else if (!sel && _viewport_highlight_town == t) { _viewport_highlight_town = nullptr; - MarkWholeScreenDirty(); + MarkWholeNonMapViewportsDirty(); } if (_viewport_highlight_town != nullptr) SetWindowDirty(WC_TOWN_VIEW, _viewport_highlight_town->index); } diff --git a/src/viewport_func.h b/src/viewport_func.h index 15485316ff..2ba709b835 100644 --- a/src/viewport_func.h +++ b/src/viewport_func.h @@ -36,10 +36,12 @@ void UpdateViewportSizeZoom(Viewport *vp); 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 MarkAllViewportMapsDirty(int left, int top, int right, int bottom); +void MarkAllViewportMapLandscapesDirty(); +void MarkWholeNonMapViewportsDirty(); void MarkAllViewportOverlayStationLinksDirty(const Station *st); 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 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 CheckMarkDirtyFocusedRoutePaths(const Vehicle *veh); @@ -112,7 +114,7 @@ static inline void MarkTileDirtyByTile(TileIndex tile, ViewportMarkDirtyFlags fl 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); diff --git a/src/viewport_gui.cpp b/src/viewport_gui.cpp index 14b0224d27..ea57f0e18d 100644 --- a/src/viewport_gui.cpp +++ b/src/viewport_gui.cpp @@ -144,7 +144,7 @@ public: { if (_ctrl_pressed) { /* Cycle through the drawing modes */ - this->viewport->map_type = ChangeRenderMode(this->viewport, wheel < 0); + ChangeRenderMode(this->viewport, wheel < 0); this->SetDirty(); } else if (_settings_client.gui.scrollwheel_scrolling != 2) { ZoomInOrOutToCursorWindow(wheel < 0, this); diff --git a/src/viewport_type.h b/src/viewport_type.h index 2b0e314340..4383758d2f 100644 --- a/src/viewport_type.h +++ b/src/viewport_type.h @@ -60,6 +60,7 @@ struct Viewport { bool is_dirty = false; bool is_drawn = false; ViewPortMapDrawVehiclesCache map_draw_vehicles_cache; + std::vector land_pixel_cache; uint GetDirtyBlockWidthShift() const { return this->GetDirtyBlockShift(); } uint GetDirtyBlockHeightShift() const { return this->GetDirtyBlockShift(); } @@ -218,6 +219,7 @@ enum FoundationPart { enum ViewportMarkDirtyFlags : byte { VMDF_NONE = 0, VMDF_NOT_MAP_MODE = 0x1, + VMDF_NOT_LANDSCAPE = 0x2, }; DECLARE_ENUM_AS_BIT_SET(ViewportMarkDirtyFlags) diff --git a/src/zoning_cmd.cpp b/src/zoning_cmd.cpp index 2a7fad1807..3c0005c8a3 100644 --- a/src/zoning_cmd.cpp +++ b/src/zoning_cmd.cpp @@ -410,7 +410,7 @@ void ZoningMarkDirtyStationCoverageArea(const Station *st, ZoningModeMask mask) Rect rect = st->GetCatchmentRectUsingRadius(radius); for (int y = rect.top; y <= rect.bottom; y++) { 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 &cache) { @@ -441,7 +441,7 @@ void ZoningTownAuthorityRatingChange() if (_zoning.inner == ZEM_AUTHORITY) mask |= ZMM_INNER; if (_zoning.outer == ZEM_AUTHORITY) mask |= ZMM_OUTER; if (mask != ZMM_NOTHING) { - MarkWholeScreenDirty(); + MarkWholeNonMapViewportsDirty(); } } @@ -460,5 +460,5 @@ void SetZoningMode(bool inner, ZoningEvaluationMode mode) current_mode = mode; cache.clear(); - MarkWholeScreenDirty(); + MarkWholeNonMapViewportsDirty(); }