diff --git a/src/gfx.cpp b/src/gfx.cpp index ab798a2013..fdc49ba5a5 100644 --- a/src/gfx.cpp +++ b/src/gfx.cpp @@ -114,6 +114,7 @@ uint32_t _gfx_debug_flags; * Applies a certain FillRectMode-operation to a rectangle [left, right] x [top, bottom] on the screen. * * @pre dpi->zoom == ZOOM_LVL_NORMAL, right >= left, bottom >= top + * @param blitter Blitter to use * @param dpi Draw pixel info * @param left Minimum X (inclusive) * @param top Minimum Y (inclusive) @@ -125,9 +126,8 @@ uint32_t _gfx_debug_flags; * FILLRECT_CHECKER: Like FILLRECT_OPAQUE, but only draw every second pixel (used to grey out things) * FILLRECT_RECOLOUR: Apply a recolour sprite to every pixel in the rectangle currently on screen */ -void GfxFillRect(const DrawPixelInfo *dpi, int left, int top, int right, int bottom, int colour, FillRectMode mode) +void GfxFillRect(Blitter *blitter, const DrawPixelInfo *dpi, int left, int top, int right, int bottom, int colour, FillRectMode mode) { - Blitter *blitter = BlitterFactory::GetCurrentBlitter(); void *dst; const int otop = top; const int oleft = left; @@ -173,6 +173,11 @@ void GfxFillRect(const DrawPixelInfo *dpi, int left, int top, int right, int bot } } +void GfxFillRect(int left, int top, int right, int bottom, int colour, FillRectMode mode) +{ + GfxFillRect(BlitterFactory::GetCurrentBlitter(), _cur_dpi, left, top, right, bottom, colour, mode); +} + typedef std::pair LineSegment; /** @@ -319,6 +324,7 @@ void GfxFillPolygon(const std::vector &shape, int colour, FillRectMode mo /** * Check line clipping by using a linear equation and draw the visible part of * the line given by x/y and x2/y2. + * @param blitter Blitter to use. * @param video Destination pointer to draw into. * @param x X coordinate of first point. * @param y Y coordinate of first point. @@ -330,10 +336,8 @@ void GfxFillPolygon(const std::vector &shape, int colour, FillRectMode mo * @param width Width of the line. * @param dash Length of dashes for dashed lines. 0 means solid line. */ -static inline void GfxDoDrawLine(void *video, int x, int y, int x2, int y2, int screen_width, int screen_height, uint8_t colour, int width, int dash = 0) +static inline void GfxDoDrawLine(Blitter *blitter, void *video, int x, int y, int x2, int y2, int screen_width, int screen_height, uint8_t colour, int width, int dash = 0) { - Blitter *blitter = BlitterFactory::GetCurrentBlitter(); - assert(width > 0); if (y2 == y || x2 == x) { @@ -403,17 +407,24 @@ static inline bool GfxPreprocessLine(const DrawPixelInfo *dpi, int &x, int &y, i return true; } -void GfxDrawLine(const DrawPixelInfo *dpi, int x, int y, int x2, int y2, int colour, int width, int dash) +void GfxDrawLine(Blitter *blitter, const DrawPixelInfo *dpi, int x, int y, int x2, int y2, int colour, int width, int dash) { if (GfxPreprocessLine(dpi, x, y, x2, y2, width)) { - GfxDoDrawLine(dpi->dst_ptr, x, y, x2, y2, dpi->width, dpi->height, colour, width, dash); + GfxDoDrawLine(blitter, dpi->dst_ptr, x, y, x2, y2, dpi->width, dpi->height, colour, width, dash); } } -void GfxDrawLineUnscaled(const DrawPixelInfo *dpi, int x, int y, int x2, int y2, int colour) +void GfxDrawLine(int x, int y, int x2, int y2, int colour, int width, int dash) +{ + if (GfxPreprocessLine(_cur_dpi, x, y, x2, y2, width)) { + GfxDoDrawLine(BlitterFactory::GetCurrentBlitter(), _cur_dpi->dst_ptr, x, y, x2, y2, _cur_dpi->width, _cur_dpi->height, colour, width, dash); + } +} + +static void GfxDrawLineUnscaled(const DrawPixelInfo *dpi, int x, int y, int x2, int y2, int colour) { if (GfxPreprocessLine(dpi, x, y, x2, y2, 1)) { - GfxDoDrawLine(dpi->dst_ptr, + GfxDoDrawLine(BlitterFactory::GetCurrentBlitter(), dpi->dst_ptr, UnScaleByZoom(x, dpi->zoom), UnScaleByZoom(y, dpi->zoom), UnScaleByZoom(x2, dpi->zoom), UnScaleByZoom(y2, dpi->zoom), UnScaleByZoom(dpi->width, dpi->zoom), UnScaleByZoom(dpi->height, dpi->zoom), colour, 1); diff --git a/src/gfx_func.h b/src/gfx_func.h index eee3afa81d..0c68acb2d1 100644 --- a/src/gfx_func.h +++ b/src/gfx_func.h @@ -117,11 +117,11 @@ int DrawStringMultiLine(int left, int right, int top, int bottom, StringID str, void DrawCharCentered(char32_t c, const Rect &r, TextColour colour); -void GfxFillRect(const DrawPixelInfo *dpi, int left, int top, int right, int bottom, int colour, FillRectMode mode = FILLRECT_OPAQUE); -inline void GfxFillRect(int left, int top, int right, int bottom, int colour, FillRectMode mode = FILLRECT_OPAQUE) { GfxFillRect(_cur_dpi, left, top, right, bottom, colour, mode); } +void GfxFillRect(struct Blitter *blitter, const DrawPixelInfo *dpi, int left, int top, int right, int bottom, int colour, FillRectMode mode = FILLRECT_OPAQUE); +void GfxFillRect(int left, int top, int right, int bottom, int colour, FillRectMode mode = FILLRECT_OPAQUE); void GfxFillPolygon(const std::vector &shape, int colour, FillRectMode mode = FILLRECT_OPAQUE, GfxFillRectModeFunctor *fill_functor = nullptr); -void GfxDrawLine(const DrawPixelInfo *dpi, int left, int top, int right, int bottom, int colour, int width = 1, int dash = 0); -inline void GfxDrawLine(int left, int top, int right, int bottom, int colour, int width = 1, int dash = 0) { GfxDrawLine(_cur_dpi, left, top, right, bottom, colour, width, dash); } +void GfxDrawLine(struct Blitter * blitter, const DrawPixelInfo *dpi, int left, int top, int right, int bottom, int colour, int width = 1, int dash = 0); +void GfxDrawLine(int left, int top, int right, int bottom, int colour, int width = 1, int dash = 0); void DrawBox(const DrawPixelInfo *dpi, int x, int y, int dx1, int dy1, int dx2, int dy2, int dx3, int dy3); void DrawRectOutline(const Rect &r, int colour, int width = 1, int dash = 0); diff --git a/src/linkgraph/linkgraph_gui.cpp b/src/linkgraph/linkgraph_gui.cpp index 89b67ccbed..67b426d3bf 100644 --- a/src/linkgraph/linkgraph_gui.cpp +++ b/src/linkgraph/linkgraph_gui.cpp @@ -467,22 +467,22 @@ void LinkGraphOverlay::PrepareDraw() * Draw the linkgraph overlay or some part of it, in the area given. * @param dpi Area to be drawn to. */ -void LinkGraphOverlay::Draw(const DrawPixelInfo *dpi) const +void LinkGraphOverlay::Draw(Blitter *blitter, const DrawPixelInfo *dpi) const { - this->DrawLinks(dpi); - this->DrawStationDots(dpi); + this->DrawLinks(blitter, dpi); + this->DrawStationDots(blitter, dpi); } /** * Draw the cached links or part of them into the given area. * @param dpi Area to be drawn to. */ -void LinkGraphOverlay::DrawLinks(const DrawPixelInfo *dpi) const +void LinkGraphOverlay::DrawLinks(Blitter *blitter, const DrawPixelInfo *dpi) const { int width = ScaleGUITrad(this->scale); for (const auto &i : this->cached_links) { if (!this->IsLinkVisible(i.from_pt, i.to_pt, dpi, width + 2)) continue; - this->DrawContent(dpi, i.from_pt, i.to_pt, i.prop); + this->DrawContent(blitter, dpi, i.from_pt, i.to_pt, i.prop); } } @@ -492,7 +492,7 @@ void LinkGraphOverlay::DrawLinks(const DrawPixelInfo *dpi) const * @param ptb Destination of the link. * @param cargo Properties of the link. */ -void LinkGraphOverlay::DrawContent(const DrawPixelInfo *dpi, Point pta, Point ptb, const LinkProperties &cargo) const +void LinkGraphOverlay::DrawContent(Blitter *blitter, const DrawPixelInfo *dpi, Point pta, Point ptb, const LinkProperties &cargo) const { uint usage_or_plan = std::min(cargo.capacity * 2 + 1, cargo.Usage()); int colour = LinkGraphOverlay::LINK_COLOURS[_settings_client.gui.linkgraph_colours][usage_or_plan * lengthof(LinkGraphOverlay::LINK_COLOURS[0]) / (cargo.capacity * 2 + 2)]; @@ -504,20 +504,20 @@ void LinkGraphOverlay::DrawContent(const DrawPixelInfo *dpi, Point pta, Point pt int side = _settings_game.vehicle.road_side ? 1 : -1; if (abs(pta.x - ptb.x) < abs(pta.y - ptb.y)) { int offset_x = (pta.y > ptb.y ? 1 : -1) * side * width; - GfxDrawLine(dpi, pta.x + offset_x, pta.y, ptb.x + offset_x, ptb.y, colour, width, dash); + GfxDrawLine(blitter, dpi, pta.x + offset_x, pta.y, ptb.x + offset_x, ptb.y, colour, width, dash); } else { int offset_y = (pta.x < ptb.x ? 1 : -1) * side * width; - GfxDrawLine(dpi, pta.x, pta.y + offset_y, ptb.x, ptb.y + offset_y, colour, width, dash); + GfxDrawLine(blitter, dpi, pta.x, pta.y + offset_y, ptb.x, ptb.y + offset_y, colour, width, dash); } - GfxDrawLine(dpi, pta.x, pta.y, ptb.x, ptb.y, _colour_gradient[COLOUR_GREY][1], width); + GfxDrawLine(blitter, dpi, pta.x, pta.y, ptb.x, ptb.y, _colour_gradient[COLOUR_GREY][1], width); } /** * Draw dots for stations into the smallmap. The dots' sizes are determined by the amount of * cargo produced there, their colours by the type of cargo produced. */ -void LinkGraphOverlay::DrawStationDots(const DrawPixelInfo *dpi) const +void LinkGraphOverlay::DrawStationDots(Blitter *blitter, const DrawPixelInfo *dpi) const { int width = ScaleGUITrad(this->scale); for (const auto &i : this->cached_stations) { @@ -529,7 +529,7 @@ void LinkGraphOverlay::DrawStationDots(const DrawPixelInfo *dpi) const uint r = width * 2 + width * 2 * std::min(200, i.quantity) / 200; - LinkGraphOverlay::DrawVertex(dpi, pt.x, pt.y, r, + LinkGraphOverlay::DrawVertex(blitter, dpi, pt.x, pt.y, r, _colour_gradient[st->owner != OWNER_NONE ? (Colours)Company::Get(st->owner)->colour : COLOUR_GREY][5], _colour_gradient[COLOUR_GREY][1]); @@ -544,20 +544,20 @@ void LinkGraphOverlay::DrawStationDots(const DrawPixelInfo *dpi) const * @param colour Colour with which the vertex will be filled. * @param border_colour Colour for the border of the vertex. */ -/* static */ void LinkGraphOverlay::DrawVertex(const DrawPixelInfo *dpi, int x, int y, int size, int colour, int border_colour) +/* static */ void LinkGraphOverlay::DrawVertex(Blitter *blitter, const DrawPixelInfo *dpi, int x, int y, int size, int colour, int border_colour) { size--; int w1 = size / 2; int w2 = size / 2 + size % 2; - GfxFillRect(dpi, x - w1, y - w1, x + w2, y + w2, colour); + GfxFillRect(blitter, dpi, x - w1, y - w1, x + w2, y + w2, colour); w1++; w2++; - GfxDrawLine(dpi, x - w1, y - w1, x + w2, y - w1, border_colour); - GfxDrawLine(dpi, x - w1, y + w2, x + w2, y + w2, border_colour); - GfxDrawLine(dpi, x - w1, y - w1, x - w1, y + w2, border_colour); - GfxDrawLine(dpi, x + w2, y - w1, x + w2, y + w2, border_colour); + GfxDrawLine(blitter, dpi, x - w1, y - w1, x + w2, y - w1, border_colour); + GfxDrawLine(blitter, dpi, x - w1, y + w2, x + w2, y + w2, border_colour); + GfxDrawLine(blitter, dpi, x - w1, y - w1, x - w1, y + w2, border_colour); + GfxDrawLine(blitter, dpi, x + w2, y - w1, x + w2, y + w2, border_colour); } bool LinkGraphOverlay::ShowTooltip(Point pt, TooltipCloseCondition close_cond) diff --git a/src/linkgraph/linkgraph_gui.h b/src/linkgraph/linkgraph_gui.h index 56176b111a..73ca5e27f0 100644 --- a/src/linkgraph/linkgraph_gui.h +++ b/src/linkgraph/linkgraph_gui.h @@ -84,7 +84,7 @@ public: bool CacheStillValid() const; void MarkStationViewportLinksDirty(const Station *st); void PrepareDraw(); - void Draw(const DrawPixelInfo *dpi) const; + void Draw(struct Blitter *blitter, const DrawPixelInfo *dpi) const; void SetCargoMask(CargoTypes cargo_mask); void SetCompanyMask(CompanyMask company_mask); @@ -117,15 +117,15 @@ protected: Point GetStationMiddle(const Station *st) const; void RefreshDrawCache(); - void DrawLinks(const DrawPixelInfo *dpi) const; - void DrawStationDots(const DrawPixelInfo *dpi) const; - void DrawContent(const DrawPixelInfo *dpi, Point pta, Point ptb, const LinkProperties &cargo) const; + void DrawLinks(struct Blitter *blitter, const DrawPixelInfo *dpi) const; + void DrawStationDots(struct Blitter *blitter, const DrawPixelInfo *dpi) const; + void DrawContent(struct Blitter *blitter, const DrawPixelInfo *dpi, Point pta, Point ptb, const LinkProperties &cargo) const; bool IsLinkVisible(Point pta, Point ptb, const DrawPixelInfo *dpi, int padding = 0) const; bool IsPointVisible(Point pt, const DrawPixelInfo *dpi, int padding = 0) const; void GetWidgetDpi(DrawPixelInfo *dpi, uint margin = 0) const; static void AddStats(CargoID new_cargo, uint new_cap, uint new_usg, uint new_plan, uint32_t time, bool new_shared, LinkProperties &cargo); - static void DrawVertex(const DrawPixelInfo *dpi, int x, int y, int size, int colour, int border_colour); + static void DrawVertex(struct Blitter *blitter, const DrawPixelInfo *dpi, int x, int y, int size, int colour, int border_colour); }; void ShowLinkGraphLegend(); diff --git a/src/smallmap_gui.cpp b/src/smallmap_gui.cpp index 3cbdc9922d..7394c3a46a 100644 --- a/src/smallmap_gui.cpp +++ b/src/smallmap_gui.cpp @@ -27,6 +27,7 @@ #include "zoom_func.h" #include "object_map.h" #include "newgrf_object.h" +#include "blitter/factory.hpp" #include "smallmap_colours.h" #include "smallmap_gui.h" @@ -1007,7 +1008,7 @@ void SmallMapWindow::DrawSmallMap(DrawPixelInfo *dpi, bool draw_indicators) cons /* Draw link stat overlay */ if (this->map_type == SMT_LINKSTATS) { this->overlay->PrepareDraw(); - this->overlay->Draw(dpi); + this->overlay->Draw(BlitterFactory::GetCurrentBlitter(), dpi); } /* Draw town names */ diff --git a/src/viewport.cpp b/src/viewport.cpp index 6535228bdc..c0d4ffd2d6 100644 --- a/src/viewport.cpp +++ b/src/viewport.cpp @@ -327,7 +327,7 @@ struct ViewportDrawerDynamic { static void MarkRouteStepDirty(RouteStepsMap::const_iterator cit); static void MarkRouteStepDirty(const TileIndex tile, uint order_nr); static void HideMeasurementTooltips(); -static void ViewportDrawPlans(const Viewport *vp, DrawPixelInfo *plan_dpi); +static void ViewportDrawPlans(const Viewport *vp, Blitter *blitter, DrawPixelInfo *plan_dpi); static std::unique_ptr _vdd; std::vector> _spare_viewport_drawers; @@ -561,8 +561,7 @@ static void ScrollPlanPixelCache(Viewport *vp, int offset_x, int offset_y) const int pitch = vp->width; Blitter_8bppDrawing blitter(&pitch); - BlitterFactory::TemporaryCurrentBlitterOverride current_blitter(&blitter); - ViewportDrawPlans(vp, &plan_dpi); + ViewportDrawPlans(vp, &blitter, &plan_dpi); }); if (clear) ClearViewportPlanPixelCache(vp); } @@ -588,8 +587,7 @@ static void ScrollOrInvalidateOverlayPixelCache(Viewport *vp, int offset_x, int const int pitch = vp->width; Blitter_8bppDrawing blitter(&pitch); - BlitterFactory::TemporaryCurrentBlitterOverride current_blitter(&blitter); - vp->overlay->Draw(&overlay_dpi); + vp->overlay->Draw(&blitter, &overlay_dpi); }); if (clear) vp->overlay_pixel_cache.clear(); } @@ -2603,10 +2601,10 @@ void ViewportRouteOverlay::DrawVehicleRoutePath(const Viewport *vp, ViewportDraw int line_width = 3; if (_settings_client.gui.dash_level_of_route_lines == 0) { - GfxDrawLine(&dpi_for_text, from_x, from_y, to_x, to_y, PC_BLACK, 3, _settings_client.gui.dash_level_of_route_lines); + GfxDrawLine(BlitterFactory::GetCurrentBlitter(), &dpi_for_text, from_x, from_y, to_x, to_y, PC_BLACK, 3, _settings_client.gui.dash_level_of_route_lines); line_width = 1; } - GfxDrawLine(&dpi_for_text, from_x, from_y, to_x, to_y, iter.order_conditional ? PC_YELLOW : PC_WHITE, line_width, _settings_client.gui.dash_level_of_route_lines); + GfxDrawLine(BlitterFactory::GetCurrentBlitter(), &dpi_for_text, from_x, from_y, to_x, to_y, iter.order_conditional ? PC_YELLOW : PC_WHITE, line_width, _settings_client.gui.dash_level_of_route_lines); } } @@ -2797,7 +2795,7 @@ static void ViewportDrawVehicleRouteSteps(const Viewport * const vp) } } -static void ViewportDrawPlans(const Viewport *vp, DrawPixelInfo *plan_dpi) +static void ViewportDrawPlans(const Viewport *vp, Blitter *blitter, DrawPixelInfo *plan_dpi) { const Rect bounds = { ScaleByZoom(plan_dpi->left - 2, vp->zoom), @@ -2843,11 +2841,11 @@ static void ViewportDrawPlans(const Viewport *vp, DrawPixelInfo *plan_dpi) const int to_x = UnScaleByZoom(to_pt.x, vp->zoom); const int to_y = UnScaleByZoom(to_pt.y, vp->zoom); - GfxDrawLine(plan_dpi, from_x, from_y, to_x, to_y, PC_BLACK, 3); + GfxDrawLine(blitter, plan_dpi, from_x, from_y, to_x, to_y, PC_BLACK, 3); if (pl->focused) { - GfxDrawLine(plan_dpi, from_x, from_y, to_x, to_y, PC_RED, 1); + GfxDrawLine(blitter, plan_dpi, from_x, from_y, to_x, to_y, PC_RED, 1); } else { - GfxDrawLine(plan_dpi, from_x, from_y, to_x, to_y, _colour_value[p->colour], 1); + GfxDrawLine(blitter, plan_dpi, from_x, from_y, to_x, to_y, _colour_value[p->colour], 1); } } } @@ -2874,7 +2872,7 @@ static void ViewportDrawPlans(const Viewport *vp, DrawPixelInfo *plan_dpi) const int to_x = UnScaleByZoom(to_pt.x, vp->zoom); const int to_y = UnScaleByZoom(to_pt.y, vp->zoom); - GfxDrawLine(plan_dpi, from_x, from_y, to_x, to_y, _colour_value[_current_plan->colour], 3, 1); + GfxDrawLine(blitter, plan_dpi, from_x, from_y, to_x, to_y, _colour_value[_current_plan->colour], 3, 1); } } } @@ -3907,8 +3905,7 @@ void ViewportDoDraw(Viewport *vp, int left, int top, int right, int bottom, uint const int pitch = vp->width; Blitter_8bppDrawing blitter(&pitch); - BlitterFactory::TemporaryCurrentBlitterOverride current_blitter(&blitter); - vp->overlay->Draw(&overlay_dpi); + vp->overlay->Draw(&blitter, &overlay_dpi); } } @@ -3944,8 +3941,7 @@ void ViewportDoDraw(Viewport *vp, int left, int top, int right, int bottom, uint const int pitch = vp->width; Blitter_8bppDrawing blitter(&pitch); - BlitterFactory::TemporaryCurrentBlitterOverride current_blitter(&blitter); - ViewportDrawPlans(vp, &plan_dpi); + ViewportDrawPlans(vp, &blitter, &plan_dpi); } } else { vp->plan_pixel_cache.clear(); @@ -4082,7 +4078,7 @@ static void ViewportDoDrawPhase2(Viewport *vp, ViewportDrawerDynamic *vdd) dp.height = UnScaleByZoom(dp.height, zoom); dp.left = vdd->offset_x + vp->left; dp.top = vdd->offset_y + vp->top; - vp->overlay->Draw(&dp); + vp->overlay->Draw(BlitterFactory::GetCurrentBlitter(), &dp); } else { const int pixel_cache_start = vdd->offset_x + (vdd->offset_y * vp->width); BlitterFactory::GetCurrentBlitter()->SetRectNoD7(vdd->dpi.dst_ptr, 0, 0, vp->overlay_pixel_cache.data() + pixel_cache_start, @@ -4117,7 +4113,7 @@ static void ViewportDoDrawPhase3(Viewport *vp) if (vp->zoom < ZOOM_LVL_DRAW_MAP && AreAnyPlansVisible()) { DrawPixelInfo plan_dpi = _vdd->MakeDPIForText(); - ViewportDrawPlans(vp, &plan_dpi); + ViewportDrawPlans(vp, BlitterFactory::GetCurrentBlitter(), &plan_dpi); } else if (vp->zoom >= ZOOM_LVL_DRAW_MAP && !vp->plan_pixel_cache.empty()) { const int pixel_cache_start = _vdd->offset_x + (_vdd->offset_y * vp->width); BlitterFactory::GetCurrentBlitter()->SetRectNoD7(_vdd->dpi.dst_ptr, 0, 0, vp->plan_pixel_cache.data() + pixel_cache_start, @@ -4126,7 +4122,7 @@ static void ViewportDoDrawPhase3(Viewport *vp) if (_vdd->display_flags & (ND_SHADE_GREY | ND_SHADE_DIMMED)) { DrawPixelInfo dp = _vdd->MakeDPIForText(); - GfxFillRect(&dp, dp.left, dp.top, dp.left + dp.width, dp.top + dp.height, + GfxFillRect(BlitterFactory::GetCurrentBlitter(), &dp, dp.left, dp.top, dp.left + dp.width, dp.top + dp.height, (_vdd->display_flags & ND_SHADE_DIMMED) ? PALETTE_TO_TRANSPARENT : PALETTE_NEWSPAPER, FILLRECT_RECOLOUR); }