diff --git a/src/vehicle.cpp b/src/vehicle.cpp index 156537d659..d1e17ca863 100644 --- a/src/vehicle.cpp +++ b/src/vehicle.cpp @@ -2081,7 +2081,8 @@ void ViewportMapDrawVehicles(DrawPixelInfo *dpi, Viewport *vp) if (pt.x >= l && pt.x < r && pt.y >= t && pt.y < b) { const int pixel_x = UnScaleByZoomLower(pt.x - l, dpi->zoom); const int pixel_y = UnScaleByZoomLower(pt.y - t, dpi->zoom); - vp->map_draw_vehicles_cache.vehicle_pixels[pixel_x + (pixel_y) * vp->width] = true; + const int pos = pixel_x + (pixel_y) * vp->width; + SetBit(vp->map_draw_vehicles_cache.vehicle_pixels[pos / VP_BLOCK_BITS], pos % VP_BLOCK_BITS); } } v = v->hash_viewport_next; @@ -2103,9 +2104,17 @@ void ViewportMapDrawVehicles(DrawPixelInfo *dpi, Viewport *vp) const int db = UnScaleByZoomLower(dpi->top + dpi->height - (vp->virtual_top & mask), dpi->zoom); int y_ptr = vp->width * dt; for (int y = dt; y < db; y++, y_ptr += vp->width) { - for (int x = dl; x < dr; x++) { - if (vp->map_draw_vehicles_cache.vehicle_pixels[y_ptr + x]) { - blitter->SetPixel32(dpi->dst_ptr, x - dl, y - dt, PC_WHITE, Colour(0xFC, 0xFC, 0xFC).data); + const uint row_start = static_cast(y_ptr + dl); + const uint row_end = static_cast(y_ptr + dr); + + ViewPortBlockT ignore_mask = GetBitMaskSC(0, row_start % VP_BLOCK_BITS); + const ViewPortBlockT *ptr = vp->map_draw_vehicles_cache.vehicle_pixels.data() + (row_start / VP_BLOCK_BITS); + for (uint block = row_start - (row_start % VP_BLOCK_BITS); block < row_end; block += VP_BLOCK_BITS, ignore_mask = 0, ptr++) { + const ViewPortBlockT value = *ptr & ~ignore_mask; + for (uint8_t bit : SetBitIterator(value)) { + uint pos = block + bit; + if (pos >= row_end) break; + blitter->SetPixel32(dpi->dst_ptr, pos - row_start, y - dt, PC_WHITE, Colour(0xFC, 0xFC, 0xFC).data); } } } diff --git a/src/viewport.cpp b/src/viewport.cpp index 14d44737b4..7871a94931 100644 --- a/src/viewport.cpp +++ b/src/viewport.cpp @@ -607,7 +607,9 @@ void ClearViewportCache(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->map_draw_vehicles_cache.vehicle_pixels.size(), false); + if (!vp->map_draw_vehicles_cache.vehicle_pixels.empty()) { + MemSetT(vp->map_draw_vehicles_cache.vehicle_pixels.data(), 0, vp->map_draw_vehicles_cache.vehicle_pixels.size()); + } } } @@ -4444,7 +4446,7 @@ void UpdateViewportSizeZoom(Viewport *vp) UpdateViewportDirtyBlockLeftMargin(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->ScreenArea(), false); + vp->map_draw_vehicles_cache.vehicle_pixels.assign(CeilDivT(vp->ScreenArea(), VP_BLOCK_BITS), 0); if (BlitterFactory::GetCurrentBlitter()->GetScreenDepth() == 32) { vp->land_pixel_cache.assign(vp->ScreenArea() * 4, 0xD7); diff --git a/src/viewport_type.h b/src/viewport_type.h index 38ac26dd18..f389d6de37 100644 --- a/src/viewport_type.h +++ b/src/viewport_type.h @@ -14,6 +14,7 @@ #include "strings_type.h" #include "table/strings.h" +#include #include class LinkGraphOverlay; @@ -30,9 +31,12 @@ enum ViewportMapType { VPMT_MAX = VPMT_INDUSTRY, }; +using ViewPortBlockT = size_t; +static constexpr uint VP_BLOCK_BITS = std::numeric_limits::digits; + struct ViewPortMapDrawVehiclesCache { uint64_t done_hash_bits[64]; - std::vector vehicle_pixels; + std::vector vehicle_pixels; }; /**