Pass rct_drawpixelinfo explicit to avoid races

This commit is contained in:
ζeh Matt 2021-10-06 23:37:02 +03:00
parent 911f168f8f
commit a0e7752f26
No known key found for this signature in database
GPG Key ID: 18CE582C71A225B0
10 changed files with 214 additions and 198 deletions

View File

@ -296,7 +296,7 @@ public:
for (auto& w : g_window_list)
{
DrawWeatherWindow(weatherDrawer, w.get(), left, right, top, bottom, drawFunc);
DrawWeatherWindow(dpi, weatherDrawer, w.get(), left, right, top, bottom, drawFunc);
}
}
@ -860,8 +860,8 @@ private:
}
static void DrawWeatherWindow(
IWeatherDrawer* weatherDrawer, rct_window* original_w, int16_t left, int16_t right, int16_t top, int16_t bottom,
DrawWeatherFunc drawFunc)
rct_drawpixelinfo* dpi, IWeatherDrawer* weatherDrawer, rct_window* original_w, int16_t left, int16_t right, int16_t top,
int16_t bottom, DrawWeatherFunc drawFunc)
{
rct_window* w{};
auto itStart = window_get_iterator(original_w);
@ -881,7 +881,7 @@ private:
{
auto width = right - left;
auto height = bottom - top;
drawFunc(weatherDrawer, left, top, width, height);
drawFunc(dpi, weatherDrawer, left, top, width, height);
}
}
return;
@ -903,39 +903,39 @@ private:
break;
}
DrawWeatherWindow(weatherDrawer, original_w, left, w->windowPos.x, top, bottom, drawFunc);
DrawWeatherWindow(dpi, weatherDrawer, original_w, left, w->windowPos.x, top, bottom, drawFunc);
left = w->windowPos.x;
DrawWeatherWindow(weatherDrawer, original_w, left, right, top, bottom, drawFunc);
DrawWeatherWindow(dpi, weatherDrawer, original_w, left, right, top, bottom, drawFunc);
return;
}
int16_t w_right = RCT_WINDOW_RIGHT(w);
if (right > w_right)
{
DrawWeatherWindow(weatherDrawer, original_w, left, w_right, top, bottom, drawFunc);
DrawWeatherWindow(dpi, weatherDrawer, original_w, left, w_right, top, bottom, drawFunc);
left = w_right;
DrawWeatherWindow(weatherDrawer, original_w, left, right, top, bottom, drawFunc);
DrawWeatherWindow(dpi, weatherDrawer, original_w, left, right, top, bottom, drawFunc);
return;
}
if (top < w->windowPos.y)
{
DrawWeatherWindow(weatherDrawer, original_w, left, right, top, w->windowPos.y, drawFunc);
DrawWeatherWindow(dpi, weatherDrawer, original_w, left, right, top, w->windowPos.y, drawFunc);
top = w->windowPos.y;
DrawWeatherWindow(weatherDrawer, original_w, left, right, top, bottom, drawFunc);
DrawWeatherWindow(dpi, weatherDrawer, original_w, left, right, top, bottom, drawFunc);
return;
}
int16_t w_bottom = RCT_WINDOW_BOTTOM(w);
if (bottom > w_bottom)
{
DrawWeatherWindow(weatherDrawer, original_w, left, right, top, w_bottom, drawFunc);
DrawWeatherWindow(dpi, weatherDrawer, original_w, left, right, top, w_bottom, drawFunc);
top = w_bottom;
DrawWeatherWindow(weatherDrawer, original_w, left, right, top, bottom, drawFunc);
DrawWeatherWindow(dpi, weatherDrawer, original_w, left, right, top, bottom, drawFunc);
return;
}
}

View File

@ -57,7 +57,6 @@ class OpenGLDrawingContext final : public IDrawingContext
{
private:
OpenGLDrawingEngine* _engine = nullptr;
rct_drawpixelinfo* _dpi = nullptr;
ApplyTransparencyShader* _applyTransparencyShader = nullptr;
DrawLineShader* _drawLineShader = nullptr;
DrawRectShader* _drawRectShader = nullptr;
@ -101,27 +100,25 @@ public:
void ResetPalette();
void StartNewDraw();
void Clear(uint8_t paletteIndex) override;
void FillRect(uint32_t colour, int32_t x, int32_t y, int32_t w, int32_t h) override;
void FilterRect(FilterPaletteID palette, int32_t left, int32_t top, int32_t right, int32_t bottom) override;
void DrawLine(uint32_t colour, const ScreenLine& line) override;
void DrawSprite(uint32_t image, int32_t x, int32_t y, uint32_t tertiaryColour) override;
void DrawSpriteRawMasked(int32_t x, int32_t y, uint32_t maskImage, uint32_t colourImage) override;
void DrawSpriteSolid(uint32_t image, int32_t x, int32_t y, uint8_t colour) override;
void DrawGlyph(uint32_t image, int32_t x, int32_t y, const PaletteMap& palette) override;
void DrawBitmap(uint32_t image, const void* pixels, int32_t width, int32_t height, int32_t x, int32_t y) override;
void Clear(rct_drawpixelinfo* dpi, uint8_t paletteIndex) override;
void FillRect(rct_drawpixelinfo* dpi, uint32_t colour, int32_t x, int32_t y, int32_t w, int32_t h) override;
void FilterRect(
rct_drawpixelinfo* dpi, FilterPaletteID palette, int32_t left, int32_t top, int32_t right, int32_t bottom) override;
void DrawLine(rct_drawpixelinfo* dpi, uint32_t colour, const ScreenLine& line) override;
void DrawSprite(rct_drawpixelinfo* dpi, uint32_t image, int32_t x, int32_t y, uint32_t tertiaryColour) override;
void DrawSpriteRawMasked(rct_drawpixelinfo* dpi, int32_t x, int32_t y, uint32_t maskImage, uint32_t colourImage) override;
void DrawSpriteSolid(rct_drawpixelinfo* dpi, uint32_t image, int32_t x, int32_t y, uint8_t colour) override;
void DrawGlyph(rct_drawpixelinfo* dpi, uint32_t image, int32_t x, int32_t y, const PaletteMap& palette) override;
void DrawBitmap(
rct_drawpixelinfo* dpi, uint32_t image, const void* pixels, int32_t width, int32_t height, int32_t x,
int32_t y) override;
void FlushCommandBuffers();
void FlushLines();
void FlushRectangles();
void HandleTransparency();
void SetDPI(rct_drawpixelinfo* dpi);
rct_drawpixelinfo* GetDPI() const
{
return _dpi;
}
void CalculcateClipping(rct_drawpixelinfo* dpi);
};
class OpenGLWeatherDrawer final : public IWeatherDrawer
@ -135,7 +132,7 @@ public:
}
virtual void Draw(
int32_t x, int32_t y, int32_t width, int32_t height, int32_t xStart, int32_t yStart,
rct_drawpixelinfo* dpi, int32_t x, int32_t y, int32_t width, int32_t height, int32_t xStart, int32_t yStart,
const uint8_t* weatherpattern) override
{
const uint8_t* pattern = weatherpattern;
@ -145,8 +142,6 @@ public:
uint8_t patternStartXOffset = xStart % patternXSpace;
uint8_t patternStartYOffset = yStart % patternYSpace;
const auto* dpi = _drawingContext->GetDPI();
uint32_t pixelOffset = (dpi->pitch + dpi->width) * y + x;
uint8_t patternYPos = patternStartYOffset % patternYSpace;
@ -166,7 +161,7 @@ public:
int32_t pixelX = xPixelOffset % dpi->width;
int32_t pixelY = (xPixelOffset / dpi->width) % dpi->height;
_drawingContext->DrawLine(patternPixel, { { pixelX, pixelY }, { pixelX + 1, pixelY + 1 } });
_drawingContext->DrawLine(dpi, patternPixel, { { pixelX, pixelY }, { pixelX + 1, pixelY + 1 } });
}
}
@ -298,6 +293,7 @@ public:
assert(_screenFramebuffer != nullptr);
_drawingContext->StartNewDraw();
_drawingContext->CalculcateClipping(&_bitsDPI);
}
void EndDraw() override
@ -335,13 +331,16 @@ public:
void PaintWindows() override
{
_drawingContext->CalculcateClipping(&_bitsDPI);
window_update_all_viewports();
window_draw_all(&_bitsDPI, 0, 0, _width, _height);
}
void PaintWeather() override
{
_drawingContext->SetDPI(&_bitsDPI);
_drawingContext->CalculcateClipping(&_bitsDPI);
DrawWeather(&_bitsDPI, &_weatherDrawer);
}
@ -359,9 +358,8 @@ public:
// Not applicable for this engine
}
IDrawingContext* GetDrawingContext(rct_drawpixelinfo* dpi) override
IDrawingContext* GetDrawingContext() override
{
_drawingContext->SetDPI(dpi);
return _drawingContext;
}
@ -541,13 +539,18 @@ void OpenGLDrawingContext::StartNewDraw()
_swapFramebuffer->Clear();
}
void OpenGLDrawingContext::Clear(uint8_t paletteIndex)
void OpenGLDrawingContext::Clear(rct_drawpixelinfo* dpi, uint8_t paletteIndex)
{
FillRect(paletteIndex, _clipLeft - _offsetX, _clipTop - _offsetY, _clipRight - _offsetX, _clipBottom - _offsetY);
CalculcateClipping(dpi);
FillRect(dpi, paletteIndex, _clipLeft - _offsetX, _clipTop - _offsetY, _clipRight - _offsetX, _clipBottom - _offsetY);
}
void OpenGLDrawingContext::FillRect(uint32_t colour, int32_t left, int32_t top, int32_t right, int32_t bottom)
void OpenGLDrawingContext::FillRect(
rct_drawpixelinfo* dpi, uint32_t colour, int32_t left, int32_t top, int32_t right, int32_t bottom)
{
CalculcateClipping(dpi);
left += _offsetX;
top += _offsetY;
right += _offsetX;
@ -578,8 +581,11 @@ void OpenGLDrawingContext::FillRect(uint32_t colour, int32_t left, int32_t top,
}
}
void OpenGLDrawingContext::FilterRect(FilterPaletteID palette, int32_t left, int32_t top, int32_t right, int32_t bottom)
void OpenGLDrawingContext::FilterRect(
rct_drawpixelinfo* dpi, FilterPaletteID palette, int32_t left, int32_t top, int32_t right, int32_t bottom)
{
CalculcateClipping(dpi);
left += _offsetX;
top += _offsetY;
right += _offsetX;
@ -599,8 +605,10 @@ void OpenGLDrawingContext::FilterRect(FilterPaletteID palette, int32_t left, int
command.depth = _drawCount++;
}
void OpenGLDrawingContext::DrawLine(uint32_t colour, const ScreenLine& line)
void OpenGLDrawingContext::DrawLine(rct_drawpixelinfo* dpi, uint32_t colour, const ScreenLine& line)
{
CalculcateClipping(dpi);
DrawLineCommand& command = _commandBuffers.lines.allocate();
command.clip = { _clipLeft, _clipTop, _clipRight, _clipBottom };
@ -609,8 +617,10 @@ void OpenGLDrawingContext::DrawLine(uint32_t colour, const ScreenLine& line)
command.depth = _drawCount++;
}
void OpenGLDrawingContext::DrawSprite(uint32_t image, int32_t x, int32_t y, uint32_t tertiaryColour)
void OpenGLDrawingContext::DrawSprite(rct_drawpixelinfo* dpi, uint32_t image, int32_t x, int32_t y, uint32_t tertiaryColour)
{
CalculcateClipping(dpi);
int32_t g1Id = image & 0x7FFFF;
auto g1Element = gfx_get_g1_element(g1Id);
if (g1Element == nullptr)
@ -618,20 +628,19 @@ void OpenGLDrawingContext::DrawSprite(uint32_t image, int32_t x, int32_t y, uint
return;
}
if (_dpi->zoom_level > 0)
if (dpi->zoom_level > 0)
{
if (g1Element->flags & G1_FLAG_HAS_ZOOM_SPRITE)
{
rct_drawpixelinfo zoomedDPI;
zoomedDPI.bits = _dpi->bits;
zoomedDPI.x = _dpi->x >> 1;
zoomedDPI.y = _dpi->y >> 1;
zoomedDPI.height = _dpi->height >> 1;
zoomedDPI.width = _dpi->width >> 1;
zoomedDPI.pitch = _dpi->pitch;
zoomedDPI.zoom_level = _dpi->zoom_level - 1;
SetDPI(&zoomedDPI);
DrawSprite((image & 0xFFF80000) | (g1Id - g1Element->zoomed_offset), x >> 1, y >> 1, tertiaryColour);
zoomedDPI.bits = dpi->bits;
zoomedDPI.x = dpi->x >> 1;
zoomedDPI.y = dpi->y >> 1;
zoomedDPI.height = dpi->height >> 1;
zoomedDPI.width = dpi->width >> 1;
zoomedDPI.pitch = dpi->pitch;
zoomedDPI.zoom_level = dpi->zoom_level - 1;
DrawSprite(&zoomedDPI, (image & 0xFFF80000) | (g1Id - g1Element->zoomed_offset), x >> 1, y >> 1, tertiaryColour);
return;
}
if (g1Element->flags & G1_FLAG_NO_ZOOM_DRAW)
@ -644,11 +653,11 @@ void OpenGLDrawingContext::DrawSprite(uint32_t image, int32_t x, int32_t y, uint
int32_t top = y + g1Element->y_offset;
int32_t zoom_mask;
if (_dpi->zoom_level >= 0)
zoom_mask = 0xFFFFFFFF * _dpi->zoom_level;
if (dpi->zoom_level >= 0)
zoom_mask = 0xFFFFFFFF * dpi->zoom_level;
else
zoom_mask = 0xFFFFFFFF;
if (_dpi->zoom_level != 0 && (g1Element->flags & G1_FLAG_RLE_COMPRESSION))
if (dpi->zoom_level != 0 && (g1Element->flags & G1_FLAG_RLE_COMPRESSION))
{
top -= ~zoom_mask;
}
@ -664,7 +673,7 @@ void OpenGLDrawingContext::DrawSprite(uint32_t image, int32_t x, int32_t y, uint
int32_t right = left + g1Element->width;
int32_t bottom = top + g1Element->height;
if (_dpi->zoom_level != 0 && (g1Element->flags & G1_FLAG_RLE_COMPRESSION))
if (dpi->zoom_level != 0 && (g1Element->flags & G1_FLAG_RLE_COMPRESSION))
{
bottom += top & ~zoom_mask;
}
@ -678,15 +687,15 @@ void OpenGLDrawingContext::DrawSprite(uint32_t image, int32_t x, int32_t y, uint
std::swap(top, bottom);
}
left -= _dpi->x;
top -= _dpi->y;
right -= _dpi->x;
bottom -= _dpi->y;
left -= dpi->x;
top -= dpi->y;
right -= dpi->x;
bottom -= dpi->y;
left = left / _dpi->zoom_level;
top = top / _dpi->zoom_level;
right = right / _dpi->zoom_level;
bottom = bottom / _dpi->zoom_level;
left = left / dpi->zoom_level;
top = top / dpi->zoom_level;
right = right / dpi->zoom_level;
bottom = bottom / dpi->zoom_level;
left += _spriteOffset.x;
top += _spriteOffset.y;
@ -759,8 +768,11 @@ void OpenGLDrawingContext::DrawSprite(uint32_t image, int32_t x, int32_t y, uint
}
}
void OpenGLDrawingContext::DrawSpriteRawMasked(int32_t x, int32_t y, uint32_t maskImage, uint32_t colourImage)
void OpenGLDrawingContext::DrawSpriteRawMasked(
rct_drawpixelinfo* dpi, int32_t x, int32_t y, uint32_t maskImage, uint32_t colourImage)
{
CalculcateClipping(dpi);
auto g1ElementMask = gfx_get_g1_element(maskImage & 0x7FFFF);
auto g1ElementColour = gfx_get_g1_element(colourImage & 0x7FFFF);
if (g1ElementMask == nullptr || g1ElementColour == nullptr)
@ -790,15 +802,15 @@ void OpenGLDrawingContext::DrawSpriteRawMasked(int32_t x, int32_t y, uint32_t ma
std::swap(top, bottom);
}
left -= _dpi->x;
top -= _dpi->y;
right -= _dpi->x;
bottom -= _dpi->y;
left -= dpi->x;
top -= dpi->y;
right -= dpi->x;
bottom -= dpi->y;
left = left / _dpi->zoom_level;
top = top / _dpi->zoom_level;
right = right / _dpi->zoom_level;
bottom = bottom / _dpi->zoom_level;
left = left / dpi->zoom_level;
top = top / dpi->zoom_level;
right = right / dpi->zoom_level;
bottom = bottom / dpi->zoom_level;
left += _spriteOffset.x;
top += _spriteOffset.y;
@ -819,8 +831,10 @@ void OpenGLDrawingContext::DrawSpriteRawMasked(int32_t x, int32_t y, uint32_t ma
command.depth = _drawCount++;
}
void OpenGLDrawingContext::DrawSpriteSolid(uint32_t image, int32_t x, int32_t y, uint8_t colour)
void OpenGLDrawingContext::DrawSpriteSolid(rct_drawpixelinfo* dpi, uint32_t image, int32_t x, int32_t y, uint8_t colour)
{
CalculcateClipping(dpi);
assert((colour & 0xFF) > 0u);
int32_t g1Id = image & 0x7FFFF;
@ -870,8 +884,10 @@ void OpenGLDrawingContext::DrawSpriteSolid(uint32_t image, int32_t x, int32_t y,
command.depth = _drawCount++;
}
void OpenGLDrawingContext::DrawGlyph(uint32_t image, int32_t x, int32_t y, const PaletteMap& palette)
void OpenGLDrawingContext::DrawGlyph(rct_drawpixelinfo* dpi, uint32_t image, int32_t x, int32_t y, const PaletteMap& palette)
{
CalculcateClipping(dpi);
auto g1Element = gfx_get_g1_element(image & 0x7FFFF);
if (g1Element == nullptr)
{
@ -894,15 +910,15 @@ void OpenGLDrawingContext::DrawGlyph(uint32_t image, int32_t x, int32_t y, const
std::swap(top, bottom);
}
left -= _dpi->x;
top -= _dpi->y;
right -= _dpi->x;
bottom -= _dpi->y;
left -= dpi->x;
top -= dpi->y;
right -= dpi->x;
bottom -= dpi->y;
left = left / _dpi->zoom_level;
top = top / _dpi->zoom_level;
right = right / _dpi->zoom_level;
bottom = bottom / _dpi->zoom_level;
left = left / dpi->zoom_level;
top = top / dpi->zoom_level;
right = right / dpi->zoom_level;
bottom = bottom / dpi->zoom_level;
left += _spriteOffset.x;
top += _spriteOffset.y;
@ -923,8 +939,11 @@ void OpenGLDrawingContext::DrawGlyph(uint32_t image, int32_t x, int32_t y, const
command.depth = _drawCount++;
}
void OpenGLDrawingContext::DrawBitmap(uint32_t image, const void* pixels, int32_t width, int32_t height, int32_t x, int32_t y)
void OpenGLDrawingContext::DrawBitmap(
rct_drawpixelinfo* dpi, uint32_t image, const void* pixels, int32_t width, int32_t height, int32_t x, int32_t y)
{
CalculcateClipping(dpi);
const auto texture = _textureCache->GetOrLoadBitmapTexture(image, pixels, width, height);
int32_t drawOffsetX = 0;
@ -1041,7 +1060,7 @@ void OpenGLDrawingContext::HandleTransparency()
_commandBuffers.transparent.clear();
}
void OpenGLDrawingContext::SetDPI(rct_drawpixelinfo* dpi)
void OpenGLDrawingContext::CalculcateClipping(rct_drawpixelinfo* dpi)
{
auto screenDPI = _engine->GetDPI();
auto bytesPerRow = screenDPI->GetBytesPerRow();
@ -1059,8 +1078,6 @@ void OpenGLDrawingContext::SetDPI(rct_drawpixelinfo* dpi)
_offsetY = _clipTop - dpi->y;
_spriteOffset.x = _clipLeft - dpi->remX;
_spriteOffset.y = _clipTop - dpi->remY;
_dpi = dpi;
}
#endif /* DISABLE_OPENGL */

View File

@ -578,9 +578,9 @@ static void ttf_draw_string_raw_ttf(rct_drawpixelinfo* dpi, std::string_view tex
auto baseId = uint32_t(0x7FFFF) - 1024;
auto imageId = baseId + _ttfGlId;
auto drawingEngine = dpi->DrawingEngine;
auto drawingContext = drawingEngine->GetDrawingContext(dpi);
auto drawingContext = drawingEngine->GetDrawingContext();
drawingEngine->InvalidateImage(imageId);
drawingContext->DrawBitmap(imageId, surface->pixels, surface->pitch, surface->h, drawX, drawY);
drawingContext->DrawBitmap(dpi, imageId, surface->pixels, surface->pitch, surface->h, drawX, drawY);
_ttfGlId++;
if (_ttfGlId >= 1023)

View File

@ -21,15 +21,21 @@ namespace OpenRCT2::Drawing
virtual ~IDrawingContext() = default;
virtual OpenRCT2::Drawing::IDrawingEngine* GetEngine() abstract;
virtual void Clear(uint8_t paletteIndex) abstract;
virtual void FillRect(uint32_t colour, int32_t left, int32_t top, int32_t right, int32_t bottom) abstract;
virtual void FilterRect(FilterPaletteID palette, int32_t left, int32_t top, int32_t right, int32_t bottom) abstract;
virtual void DrawLine(uint32_t colour, const ScreenLine& line) abstract;
virtual void DrawSprite(uint32_t image, int32_t x, int32_t y, uint32_t tertiaryColour) abstract;
virtual void DrawSpriteRawMasked(int32_t x, int32_t y, uint32_t maskImage, uint32_t colourImage) abstract;
virtual void DrawSpriteSolid(uint32_t image, int32_t x, int32_t y, uint8_t colour) abstract;
virtual void DrawGlyph(uint32_t image, int32_t x, int32_t y, const PaletteMap& palette) abstract;
virtual void Clear(rct_drawpixelinfo* dpi, uint8_t paletteIndex) abstract;
virtual void FillRect(
rct_drawpixelinfo* dpi, uint32_t colour, int32_t left, int32_t top, int32_t right, int32_t bottom) abstract;
virtual void FilterRect(
rct_drawpixelinfo* dpi, FilterPaletteID palette, int32_t left, int32_t top, int32_t right, int32_t bottom) abstract;
virtual void DrawLine(rct_drawpixelinfo* dpi, uint32_t colour, const ScreenLine& line) abstract;
virtual void DrawSprite(rct_drawpixelinfo* dpi, uint32_t image, int32_t x, int32_t y, uint32_t tertiaryColour) abstract;
virtual void DrawSpriteRawMasked(
rct_drawpixelinfo* dpi, int32_t x, int32_t y, uint32_t maskImage, uint32_t colourImage) abstract;
virtual void DrawSpriteSolid(rct_drawpixelinfo* dpi, uint32_t image, int32_t x, int32_t y, uint8_t colour) abstract;
virtual void DrawGlyph(
rct_drawpixelinfo* dpi, uint32_t image, int32_t x, int32_t y, const PaletteMap& palette) abstract;
virtual void DrawBitmap(
uint32_t image, const void* pixels, int32_t width, int32_t height, int32_t x, int32_t y) abstract;
rct_drawpixelinfo* dpi, uint32_t image, const void* pixels, int32_t width, int32_t height, int32_t x,
int32_t y) abstract;
};
} // namespace OpenRCT2::Drawing

View File

@ -71,7 +71,7 @@ namespace OpenRCT2::Drawing
virtual void CopyRect(int32_t x, int32_t y, int32_t width, int32_t height, int32_t dx, int32_t dy) abstract;
virtual std::string Screenshot() abstract;
virtual IDrawingContext* GetDrawingContext(rct_drawpixelinfo* dpi) abstract;
virtual IDrawingContext* GetDrawingContext() abstract;
virtual rct_drawpixelinfo* GetDrawingPixelInfo() abstract;
virtual DRAWING_ENGINE_FLAGS GetFlags() abstract;
@ -90,11 +90,9 @@ namespace OpenRCT2::Drawing
struct IWeatherDrawer
{
virtual ~IWeatherDrawer()
{
}
virtual ~IWeatherDrawer() = default;
virtual void Draw(
int32_t x, int32_t y, int32_t width, int32_t height, int32_t xStart, int32_t yStart,
rct_drawpixelinfo* dpi, int32_t x, int32_t y, int32_t width, int32_t height, int32_t xStart, int32_t yStart,
const uint8_t* weatherpattern) abstract;
};
} // namespace OpenRCT2::Drawing

View File

@ -165,8 +165,8 @@ void gfx_clear(rct_drawpixelinfo* dpi, uint8_t paletteIndex)
auto drawingEngine = dpi->DrawingEngine;
if (drawingEngine != nullptr)
{
IDrawingContext* dc = drawingEngine->GetDrawingContext(dpi);
dc->Clear(paletteIndex);
IDrawingContext* dc = drawingEngine->GetDrawingContext();
dc->Clear(dpi, paletteIndex);
}
}
@ -175,8 +175,8 @@ void gfx_fill_rect(rct_drawpixelinfo* dpi, const ScreenRect& rect, int32_t colou
auto drawingEngine = dpi->DrawingEngine;
if (drawingEngine != nullptr)
{
IDrawingContext* dc = drawingEngine->GetDrawingContext(dpi);
dc->FillRect(colour, rect.GetLeft(), rect.GetTop(), rect.GetRight(), rect.GetBottom());
IDrawingContext* dc = drawingEngine->GetDrawingContext();
dc->FillRect(dpi, colour, rect.GetLeft(), rect.GetTop(), rect.GetRight(), rect.GetBottom());
}
}
@ -190,8 +190,8 @@ void gfx_filter_rect(rct_drawpixelinfo* dpi, const ScreenRect& rect, FilterPalet
auto drawingEngine = dpi->DrawingEngine;
if (drawingEngine != nullptr)
{
IDrawingContext* dc = drawingEngine->GetDrawingContext(dpi);
dc->FilterRect(palette, rect.GetLeft(), rect.GetTop(), rect.GetRight(), rect.GetBottom());
IDrawingContext* dc = drawingEngine->GetDrawingContext();
dc->FilterRect(dpi, palette, rect.GetLeft(), rect.GetTop(), rect.GetRight(), rect.GetBottom());
}
}
@ -200,8 +200,8 @@ void gfx_draw_line(rct_drawpixelinfo* dpi, const ScreenLine& line, int32_t colou
auto drawingEngine = dpi->DrawingEngine;
if (drawingEngine != nullptr)
{
IDrawingContext* dc = drawingEngine->GetDrawingContext(dpi);
dc->DrawLine(colour, line);
IDrawingContext* dc = drawingEngine->GetDrawingContext();
dc->DrawLine(dpi, colour, line);
}
}
@ -227,13 +227,13 @@ void gfx_draw_dashed_line(
const int32_t lineYDist = std::abs(screenLine.GetY2() - screenLine.GetY1());
const int32_t dxPrecise = precisionFactor * lineXDist / lineSegmentCount / 2;
const int32_t dyPrecise = precisionFactor * lineYDist / lineSegmentCount / 2;
IDrawingContext* dc = drawingEngine->GetDrawingContext(dpi);
IDrawingContext* dc = drawingEngine->GetDrawingContext();
for (int32_t i = 0, x, y; i < lineSegmentCount; ++i)
{
x = screenLine.GetX1() + dxPrecise * i * 2 / precisionFactor;
y = screenLine.GetY1() + dyPrecise * i * 2 / precisionFactor;
dc->DrawLine(color, { { x, y }, { x + dxPrecise / precisionFactor, y + dyPrecise / precisionFactor } });
dc->DrawLine(dpi, color, { { x, y }, { x + dxPrecise / precisionFactor, y + dyPrecise / precisionFactor } });
}
}
}
@ -248,8 +248,8 @@ void FASTCALL gfx_draw_sprite(rct_drawpixelinfo* dpi, int32_t image, const Scree
auto drawingEngine = dpi->DrawingEngine;
if (drawingEngine != nullptr)
{
IDrawingContext* dc = drawingEngine->GetDrawingContext(dpi);
dc->DrawSprite(image, coords.x, coords.y, tertiary_colour);
IDrawingContext* dc = drawingEngine->GetDrawingContext();
dc->DrawSprite(dpi, image, coords.x, coords.y, tertiary_colour);
}
}
@ -258,8 +258,8 @@ void FASTCALL gfx_draw_glyph(rct_drawpixelinfo* dpi, int32_t image, const Screen
auto drawingEngine = dpi->DrawingEngine;
if (drawingEngine != nullptr)
{
IDrawingContext* dc = drawingEngine->GetDrawingContext(dpi);
dc->DrawGlyph(image, coords.x, coords.y, paletteMap);
IDrawingContext* dc = drawingEngine->GetDrawingContext();
dc->DrawGlyph(dpi, image, coords.x, coords.y, paletteMap);
}
}
@ -269,8 +269,8 @@ void FASTCALL
auto drawingEngine = dpi->DrawingEngine;
if (drawingEngine != nullptr)
{
IDrawingContext* dc = drawingEngine->GetDrawingContext(dpi);
dc->DrawSpriteRawMasked(coords.x, coords.y, maskImage, colourImage);
IDrawingContext* dc = drawingEngine->GetDrawingContext();
dc->DrawSpriteRawMasked(dpi, coords.x, coords.y, maskImage, colourImage);
}
}
@ -279,8 +279,8 @@ void FASTCALL gfx_draw_sprite_solid(rct_drawpixelinfo* dpi, int32_t image, const
auto drawingEngine = dpi->DrawingEngine;
if (drawingEngine != nullptr)
{
IDrawingContext* dc = drawingEngine->GetDrawingContext(dpi);
dc->DrawSpriteSolid(image, coords.x, coords.y, colour);
IDrawingContext* dc = drawingEngine->GetDrawingContext();
dc->DrawSpriteSolid(dpi, image, coords.x, coords.y, colour);
}
}

View File

@ -22,10 +22,14 @@
using namespace OpenRCT2;
using namespace OpenRCT2::Drawing;
static void DrawLightRain(IWeatherDrawer* weatherDrawer, int32_t left, int32_t top, int32_t width, int32_t height);
static void DrawHeavyRain(IWeatherDrawer* weatherDrawer, int32_t left, int32_t top, int32_t width, int32_t height);
static void DrawLightSnow(IWeatherDrawer* weatherDrawer, int32_t left, int32_t top, int32_t width, int32_t height);
static void DrawHeavySnow(IWeatherDrawer* weatherDrawer, int32_t left, int32_t top, int32_t width, int32_t height);
static void DrawLightRain(
rct_drawpixelinfo* dpi, IWeatherDrawer* weatherDrawer, int32_t left, int32_t top, int32_t width, int32_t height);
static void DrawHeavyRain(
rct_drawpixelinfo* dpi, IWeatherDrawer* weatherDrawer, int32_t left, int32_t top, int32_t width, int32_t height);
static void DrawLightSnow(
rct_drawpixelinfo* dpi, IWeatherDrawer* weatherDrawer, int32_t left, int32_t top, int32_t width, int32_t height);
static void DrawHeavySnow(
rct_drawpixelinfo* dpi, IWeatherDrawer* weatherDrawer, int32_t left, int32_t top, int32_t width, int32_t height);
/**
*
@ -76,59 +80,62 @@ void DrawWeather(rct_drawpixelinfo* dpi, IWeatherDrawer* weatherDrawer)
*
* rct2: 0x00684114
*/
static void DrawLightRain(IWeatherDrawer* weatherDrawer, int32_t left, int32_t top, int32_t width, int32_t height)
static void DrawLightRain(
rct_drawpixelinfo* dpi, IWeatherDrawer* weatherDrawer, int32_t left, int32_t top, int32_t width, int32_t height)
{
int32_t x_start = -static_cast<int32_t>(gCurrentTicks) + 8;
int32_t y_start = (gCurrentTicks * 3) + 7;
y_start = -y_start;
x_start += left;
y_start += top;
weatherDrawer->Draw(left, top, width, height, x_start, y_start, RainPattern);
weatherDrawer->Draw(dpi, left, top, width, height, x_start, y_start, RainPattern);
x_start = -static_cast<int32_t>(gCurrentTicks) + 0x18;
y_start = (gCurrentTicks * 4) + 0x0D;
y_start = -y_start;
x_start += left;
y_start += top;
weatherDrawer->Draw(left, top, width, height, x_start, y_start, RainPattern);
weatherDrawer->Draw(dpi, left, top, width, height, x_start, y_start, RainPattern);
}
/**
*
* rct2: 0x0068416D
*/
static void DrawHeavyRain(IWeatherDrawer* weatherDrawer, int32_t left, int32_t top, int32_t width, int32_t height)
static void DrawHeavyRain(
rct_drawpixelinfo* dpi, IWeatherDrawer* weatherDrawer, int32_t left, int32_t top, int32_t width, int32_t height)
{
int32_t x_start = -static_cast<int32_t>(gCurrentTicks);
int32_t y_start = gCurrentTicks * 5;
y_start = -y_start;
x_start += left;
y_start += top;
weatherDrawer->Draw(left, top, width, height, x_start, y_start, RainPattern);
weatherDrawer->Draw(dpi, left, top, width, height, x_start, y_start, RainPattern);
x_start = -static_cast<int32_t>(gCurrentTicks) + 0x10;
y_start = (gCurrentTicks * 6) + 5;
y_start = -y_start;
x_start += left;
y_start += top;
weatherDrawer->Draw(left, top, width, height, x_start, y_start, RainPattern);
weatherDrawer->Draw(dpi, left, top, width, height, x_start, y_start, RainPattern);
x_start = -static_cast<int32_t>(gCurrentTicks) + 8;
y_start = (gCurrentTicks * 3) + 7;
y_start = -y_start;
x_start += left;
y_start += top;
weatherDrawer->Draw(left, top, width, height, x_start, y_start, RainPattern);
weatherDrawer->Draw(dpi, left, top, width, height, x_start, y_start, RainPattern);
x_start = -static_cast<int32_t>(gCurrentTicks) + 0x18;
y_start = (gCurrentTicks * 4) + 0x0D;
y_start = -y_start;
x_start += left;
y_start += top;
weatherDrawer->Draw(left, top, width, height, x_start, y_start, RainPattern);
weatherDrawer->Draw(dpi, left, top, width, height, x_start, y_start, RainPattern);
}
static void DrawLightSnow(IWeatherDrawer* weatherDrawer, int32_t left, int32_t top, int32_t width, int32_t height)
static void DrawLightSnow(
rct_drawpixelinfo* dpi, IWeatherDrawer* weatherDrawer, int32_t left, int32_t top, int32_t width, int32_t height)
{
const uint32_t t = gCurrentTicks / 2;
const int32_t negT = -static_cast<int32_t>(t);
@ -139,43 +146,44 @@ static void DrawLightSnow(IWeatherDrawer* weatherDrawer, int32_t left, int32_t t
y_start = -y_start;
x_start += left;
y_start += top;
weatherDrawer->Draw(left, top, width, height, x_start, y_start, SnowPattern);
weatherDrawer->Draw(dpi, left, top, width, height, x_start, y_start, SnowPattern);
x_start = negT + 16 + (cos(cosTick) * 6);
y_start = t + 16;
y_start = -y_start;
x_start += left;
y_start += top;
weatherDrawer->Draw(left, top, width, height, x_start, y_start, SnowPattern);
weatherDrawer->Draw(dpi, left, top, width, height, x_start, y_start, SnowPattern);
}
static void DrawHeavySnow(IWeatherDrawer* weatherDrawer, int32_t left, int32_t top, int32_t width, int32_t height)
static void DrawHeavySnow(
rct_drawpixelinfo* dpi, IWeatherDrawer* weatherDrawer, int32_t left, int32_t top, int32_t width, int32_t height)
{
int32_t x_start = -static_cast<int32_t>(gCurrentTicks * 3) + 1;
int32_t y_start = gCurrentTicks + 23;
y_start = -y_start;
x_start += left;
y_start += top;
weatherDrawer->Draw(left, top, width, height, x_start, y_start, SnowPattern);
weatherDrawer->Draw(dpi, left, top, width, height, x_start, y_start, SnowPattern);
x_start = -static_cast<int32_t>(gCurrentTicks * 4) + 6;
y_start = gCurrentTicks + 5;
y_start = -y_start;
x_start += left;
y_start += top;
weatherDrawer->Draw(left, top, width, height, x_start, y_start, SnowPattern);
weatherDrawer->Draw(dpi, left, top, width, height, x_start, y_start, SnowPattern);
x_start = -static_cast<int32_t>(gCurrentTicks * 2) + 11;
y_start = gCurrentTicks + 18;
y_start = -y_start;
x_start += left;
y_start += top;
weatherDrawer->Draw(left, top, width, height, x_start, y_start, SnowPattern);
weatherDrawer->Draw(dpi, left, top, width, height, x_start, y_start, SnowPattern);
x_start = -static_cast<int32_t>(gCurrentTicks * 3) + 17;
y_start = gCurrentTicks + 11;
y_start = -y_start;
x_start += left;
y_start += top;
weatherDrawer->Draw(left, top, width, height, x_start, y_start, SnowPattern);
weatherDrawer->Draw(dpi, left, top, width, height, x_start, y_start, SnowPattern);
}

View File

@ -43,13 +43,9 @@ X8WeatherDrawer::~X8WeatherDrawer()
delete[] _weatherPixels;
}
void X8WeatherDrawer::SetDPI(rct_drawpixelinfo* dpi)
{
_screenDPI = dpi;
}
void X8WeatherDrawer::Draw(
int32_t x, int32_t y, int32_t width, int32_t height, int32_t xStart, int32_t yStart, const uint8_t* weatherpattern)
rct_drawpixelinfo* dpi, int32_t x, int32_t y, int32_t width, int32_t height, int32_t xStart, int32_t yStart,
const uint8_t* weatherpattern)
{
const uint8_t* pattern = weatherpattern;
auto patternXSpace = *pattern++;
@ -58,10 +54,10 @@ void X8WeatherDrawer::Draw(
uint8_t patternStartXOffset = xStart % patternXSpace;
uint8_t patternStartYOffset = yStart % patternYSpace;
uint32_t pixelOffset = (_screenDPI->pitch + _screenDPI->width) * y + x;
uint32_t pixelOffset = (dpi->pitch + dpi->width) * y + x;
uint8_t patternYPos = patternStartYOffset % patternYSpace;
uint8_t* screenBits = _screenDPI->bits;
uint8_t* screenBits = dpi->bits;
// Stores the colours of changed pixels
WeatherPixel* newPixels = &_weatherPixels[_weatherPixelsCount];
@ -90,18 +86,18 @@ void X8WeatherDrawer::Draw(
}
}
pixelOffset += _screenDPI->pitch + _screenDPI->width;
pixelOffset += dpi->pitch + dpi->width;
patternYPos++;
patternYPos %= patternYSpace;
}
}
void X8WeatherDrawer::Restore()
void X8WeatherDrawer::Restore(rct_drawpixelinfo* dpi)
{
if (_weatherPixelsCount > 0)
{
uint32_t numPixels = (_screenDPI->width + _screenDPI->pitch) * _screenDPI->height;
uint8_t* bits = _screenDPI->bits;
uint32_t numPixels = (dpi->width + dpi->pitch) * dpi->height;
uint8_t* bits = dpi->bits;
for (uint32_t i = 0; i < _weatherPixelsCount; i++)
{
WeatherPixel weatherPixel = _weatherPixels[i];
@ -201,8 +197,7 @@ void X8DrawingEngine::BeginDraw()
Resize(_width, _height);
}
#endif
_weatherDrawer.SetDPI(&_bitsDPI);
_weatherDrawer.Restore();
_weatherDrawer.Restore(&_bitsDPI);
}
}
@ -271,9 +266,8 @@ std::string X8DrawingEngine::Screenshot()
return screenshot_dump_png(&_bitsDPI);
}
IDrawingContext* X8DrawingEngine::GetDrawingContext(rct_drawpixelinfo* dpi)
IDrawingContext* X8DrawingEngine::GetDrawingContext()
{
_drawingContext->SetDPI(dpi);
return _drawingContext;
}
@ -466,10 +460,8 @@ IDrawingEngine* X8DrawingContext::GetEngine()
return _engine;
}
void X8DrawingContext::Clear(uint8_t paletteIndex)
void X8DrawingContext::Clear(rct_drawpixelinfo* dpi, uint8_t paletteIndex)
{
rct_drawpixelinfo* dpi = _dpi;
int32_t w = dpi->width / dpi->zoom_level;
int32_t h = dpi->height / dpi->zoom_level;
uint8_t* ptr = dpi->bits;
@ -529,10 +521,9 @@ static constexpr const uint16_t * Patterns[] = {
};
// clang-format on
void X8DrawingContext::FillRect(uint32_t colour, int32_t left, int32_t top, int32_t right, int32_t bottom)
void X8DrawingContext::FillRect(
rct_drawpixelinfo* dpi, uint32_t colour, int32_t left, int32_t top, int32_t right, int32_t bottom)
{
rct_drawpixelinfo* dpi = _dpi;
if (left > right)
return;
if (top > bottom)
@ -650,10 +641,9 @@ void X8DrawingContext::FillRect(uint32_t colour, int32_t left, int32_t top, int3
}
}
void X8DrawingContext::FilterRect(FilterPaletteID palette, int32_t left, int32_t top, int32_t right, int32_t bottom)
void X8DrawingContext::FilterRect(
rct_drawpixelinfo* dpi, FilterPaletteID palette, int32_t left, int32_t top, int32_t right, int32_t bottom)
{
rct_drawpixelinfo* dpi = _dpi;
if (left > right)
return;
if (top > bottom)
@ -723,22 +713,23 @@ void X8DrawingContext::FilterRect(FilterPaletteID palette, int32_t left, int32_t
}
}
void X8DrawingContext::DrawLine(uint32_t colour, const ScreenLine& line)
void X8DrawingContext::DrawLine(rct_drawpixelinfo* dpi, uint32_t colour, const ScreenLine& line)
{
gfx_draw_line_software(_dpi, line, colour);
gfx_draw_line_software(dpi, line, colour);
}
void X8DrawingContext::DrawSprite(uint32_t image, int32_t x, int32_t y, uint32_t tertiaryColour)
void X8DrawingContext::DrawSprite(rct_drawpixelinfo* dpi, uint32_t image, int32_t x, int32_t y, uint32_t tertiaryColour)
{
gfx_draw_sprite_software(_dpi, ImageId::FromUInt32(image, tertiaryColour), { x, y });
gfx_draw_sprite_software(dpi, ImageId::FromUInt32(image, tertiaryColour), { x, y });
}
void X8DrawingContext::DrawSpriteRawMasked(int32_t x, int32_t y, uint32_t maskImage, uint32_t colourImage)
void X8DrawingContext::DrawSpriteRawMasked(
rct_drawpixelinfo* dpi, int32_t x, int32_t y, uint32_t maskImage, uint32_t colourImage)
{
gfx_draw_sprite_raw_masked_software(_dpi, { x, y }, maskImage, colourImage);
gfx_draw_sprite_raw_masked_software(dpi, { x, y }, maskImage, colourImage);
}
void X8DrawingContext::DrawSpriteSolid(uint32_t image, int32_t x, int32_t y, uint8_t colour)
void X8DrawingContext::DrawSpriteSolid(rct_drawpixelinfo* dpi, uint32_t image, int32_t x, int32_t y, uint8_t colour)
{
uint8_t palette[256];
std::fill_n(palette, sizeof(palette), colour);
@ -746,15 +737,10 @@ void X8DrawingContext::DrawSpriteSolid(uint32_t image, int32_t x, int32_t y, uin
const auto spriteCoords = ScreenCoordsXY{ x, y };
gfx_draw_sprite_palette_set_software(
_dpi, ImageId::FromUInt32((image & 0x7FFFF) | IMAGE_TYPE_REMAP), spriteCoords, PaletteMap(palette));
dpi, ImageId::FromUInt32((image & 0x7FFFF) | IMAGE_TYPE_REMAP), spriteCoords, PaletteMap(palette));
}
void X8DrawingContext::DrawGlyph(uint32_t image, int32_t x, int32_t y, const PaletteMap& paletteMap)
void X8DrawingContext::DrawGlyph(rct_drawpixelinfo* dpi, uint32_t image, int32_t x, int32_t y, const PaletteMap& paletteMap)
{
gfx_draw_sprite_palette_set_software(_dpi, ImageId::FromUInt32(image), { x, y }, paletteMap);
}
void X8DrawingContext::SetDPI(rct_drawpixelinfo* dpi)
{
_dpi = dpi;
gfx_draw_sprite_palette_set_software(dpi, ImageId::FromUInt32(image), { x, y }, paletteMap);
}

View File

@ -49,16 +49,14 @@ namespace OpenRCT2
size_t _weatherPixelsCapacity = MaxWeatherPixels;
uint32_t _weatherPixelsCount = 0;
WeatherPixel* _weatherPixels = nullptr;
rct_drawpixelinfo* _screenDPI = nullptr;
public:
X8WeatherDrawer();
~X8WeatherDrawer();
void SetDPI(rct_drawpixelinfo* dpi);
void Draw(
int32_t x, int32_t y, int32_t width, int32_t height, int32_t xStart, int32_t yStart,
rct_drawpixelinfo* dpi, int32_t x, int32_t y, int32_t width, int32_t height, int32_t xStart, int32_t yStart,
const uint8_t* weatherpattern) override;
void Restore();
void Restore(rct_drawpixelinfo* dpi);
};
#ifdef __WARN_SUGGEST_FINAL_TYPES__
@ -109,7 +107,7 @@ namespace OpenRCT2
void PaintWeather() override;
void CopyRect(int32_t x, int32_t y, int32_t width, int32_t height, int32_t dx, int32_t dy) override;
std::string Screenshot() override;
IDrawingContext* GetDrawingContext(rct_drawpixelinfo* dpi) override;
IDrawingContext* GetDrawingContext() override;
rct_drawpixelinfo* GetDrawingPixelInfo() override;
DRAWING_ENGINE_FLAGS GetFlags() override;
void InvalidateImage(uint32_t image) override;
@ -135,26 +133,28 @@ namespace OpenRCT2
{
private:
X8DrawingEngine* _engine = nullptr;
rct_drawpixelinfo* _dpi = nullptr;
public:
explicit X8DrawingContext(X8DrawingEngine* engine);
IDrawingEngine* GetEngine() override;
void Clear(uint8_t paletteIndex) override;
void FillRect(uint32_t colour, int32_t x, int32_t y, int32_t w, int32_t h) override;
void FilterRect(FilterPaletteID palette, int32_t left, int32_t top, int32_t right, int32_t bottom) override;
void DrawLine(uint32_t colour, const ScreenLine& line) override;
void DrawSprite(uint32_t image, int32_t x, int32_t y, uint32_t tertiaryColour) override;
void DrawSpriteRawMasked(int32_t x, int32_t y, uint32_t maskImage, uint32_t colourImage) override;
void DrawSpriteSolid(uint32_t image, int32_t x, int32_t y, uint8_t colour) override;
void DrawGlyph(uint32_t image, int32_t x, int32_t y, const PaletteMap& paletteMap) override;
void DrawBitmap(uint32_t image, const void* pixels, int32_t width, int32_t height, int32_t x, int32_t y) override
void Clear(rct_drawpixelinfo* dpi, uint8_t paletteIndex) override;
void FillRect(rct_drawpixelinfo* dpi, uint32_t colour, int32_t x, int32_t y, int32_t w, int32_t h) override;
void FilterRect(
rct_drawpixelinfo* dpi, FilterPaletteID palette, int32_t left, int32_t top, int32_t right,
int32_t bottom) override;
void DrawLine(rct_drawpixelinfo* dpi, uint32_t colour, const ScreenLine& line) override;
void DrawSprite(rct_drawpixelinfo* dpi, uint32_t image, int32_t x, int32_t y, uint32_t tertiaryColour) override;
void DrawSpriteRawMasked(
rct_drawpixelinfo* dpi, int32_t x, int32_t y, uint32_t maskImage, uint32_t colourImage) override;
void DrawSpriteSolid(rct_drawpixelinfo* dpi, uint32_t image, int32_t x, int32_t y, uint8_t colour) override;
void DrawGlyph(rct_drawpixelinfo* dpi, uint32_t image, int32_t x, int32_t y, const PaletteMap& paletteMap) override;
void DrawBitmap(
rct_drawpixelinfo* dpi, uint32_t image, const void* pixels, int32_t width, int32_t height, int32_t x,
int32_t y) override
{
}
void SetDPI(rct_drawpixelinfo* dpi);
};
} // namespace Drawing
} // namespace OpenRCT2

View File

@ -29,7 +29,8 @@ namespace OpenRCT2
struct IDrawingEngineFactory;
struct IWeatherDrawer;
using DrawWeatherFunc = void (*)(
OpenRCT2::Drawing::IWeatherDrawer* weatherDrawer, int32_t left, int32_t top, int32_t width, int32_t height);
rct_drawpixelinfo* dpi, OpenRCT2::Drawing::IWeatherDrawer* weatherDrawer, int32_t left, int32_t top, int32_t width,
int32_t height);
} // namespace Drawing
namespace Ui