diff --git a/src/openrct2-ui/drawing/engines/HardwareDisplayDrawingEngine.cpp b/src/openrct2-ui/drawing/engines/HardwareDisplayDrawingEngine.cpp index 30448d0c1a..bfa9297019 100644 --- a/src/openrct2-ui/drawing/engines/HardwareDisplayDrawingEngine.cpp +++ b/src/openrct2-ui/drawing/engines/HardwareDisplayDrawingEngine.cpp @@ -53,7 +53,8 @@ private: public: explicit HardwareDisplayDrawingEngine(IUiContext * uiContext) - : _uiContext(uiContext) + : X8DrawingEngine(uiContext), + _uiContext(uiContext) { _window = (SDL_Window *)_uiContext->GetWindow(); } diff --git a/src/openrct2-ui/drawing/engines/SoftwareDrawingEngine.cpp b/src/openrct2-ui/drawing/engines/SoftwareDrawingEngine.cpp index 73af8490b2..19fa111f29 100644 --- a/src/openrct2-ui/drawing/engines/SoftwareDrawingEngine.cpp +++ b/src/openrct2-ui/drawing/engines/SoftwareDrawingEngine.cpp @@ -44,7 +44,8 @@ private: public: explicit SoftwareDrawingEngine(IUiContext * uiContext) - : _uiContext(uiContext) + : X8DrawingEngine(uiContext), + _uiContext(uiContext) { _window = (SDL_Window *)_uiContext->GetWindow(); } diff --git a/src/openrct2-ui/drawing/engines/opengl/OpenGLDrawingEngine.cpp b/src/openrct2-ui/drawing/engines/opengl/OpenGLDrawingEngine.cpp index d56a85eebb..72dd76d8e0 100644 --- a/src/openrct2-ui/drawing/engines/opengl/OpenGLDrawingEngine.cpp +++ b/src/openrct2-ui/drawing/engines/opengl/OpenGLDrawingEngine.cpp @@ -29,6 +29,7 @@ #include #include #include +#include #include extern "C" @@ -52,6 +53,7 @@ extern "C" using namespace OpenRCT2; using namespace OpenRCT2::Drawing; +using namespace OpenRCT2::Paint; using namespace OpenRCT2::Ui; struct OpenGLVersion @@ -228,6 +230,7 @@ private: IUiContext * const _uiContext = nullptr; SDL_Window * _window = nullptr; SDL_GLContext _context = nullptr; + Painter _painter; uint32 _width = 0; uint32 _height = 0; @@ -248,7 +251,8 @@ public: vec4f GLPalette[256]; OpenGLDrawingEngine(IUiContext * uiContext) - : _uiContext(uiContext) + : _uiContext(uiContext), + _painter(uiContext) { _window = (SDL_Window *)_uiContext->GetWindow(); _drawingContext = new OpenGLDrawingContext(this); @@ -349,7 +353,7 @@ public: _drawingContext->FlushCommandBuffers(); _swapFramebuffer->SwapCopy(); - rct2_draw(&_bitsDPI); + _painter.Paint(&_bitsDPI); } _drawingContext->FlushCommandBuffers(); diff --git a/src/openrct2/drawing/X8DrawingEngine.cpp b/src/openrct2/drawing/X8DrawingEngine.cpp index bf3c1428b5..ff2d5ccfa7 100644 --- a/src/openrct2/drawing/X8DrawingEngine.cpp +++ b/src/openrct2/drawing/X8DrawingEngine.cpp @@ -21,6 +21,7 @@ #include "../core/Math.hpp" #include "../core/Memory.hpp" #include "../interface/Screenshot.h" +#include "../paint/Painter.h" #include "IDrawingContext.h" #include "IDrawingEngine.h" #include "Rain.h" @@ -40,6 +41,7 @@ extern "C" using namespace OpenRCT2; using namespace OpenRCT2::Drawing; +using namespace OpenRCT2::Paint; using namespace OpenRCT2::Ui; X8RainDrawer::X8RainDrawer() @@ -136,9 +138,10 @@ void X8RainDrawer::Restore() #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wsuggest-final-methods" -X8DrawingEngine::X8DrawingEngine() +X8DrawingEngine::X8DrawingEngine(Ui::IUiContext * uiContext) { _drawingContext = new X8DrawingContext(this); + _painter = new Painter(uiContext); #ifdef __ENABLE_LIGHTFX__ _lastLightFXenabled = (gConfigGeneral.enable_light_fx != 0); #endif @@ -146,6 +149,7 @@ X8DrawingEngine::X8DrawingEngine() X8DrawingEngine::~X8DrawingEngine() { + delete _painter; delete _drawingContext; delete [] _dirtyGrid.Blocks; delete [] _bits; @@ -234,7 +238,7 @@ void X8DrawingEngine::Draw() DrawRain(&_bitsDPI, &_rainDrawer); - rct2_draw(&_bitsDPI); + _painter->Paint(&_bitsDPI); } } diff --git a/src/openrct2/drawing/X8DrawingEngine.h b/src/openrct2/drawing/X8DrawingEngine.h index c626b208cc..0c16de9757 100644 --- a/src/openrct2/drawing/X8DrawingEngine.h +++ b/src/openrct2/drawing/X8DrawingEngine.h @@ -20,118 +20,134 @@ #include "IDrawingContext.h" #include "IDrawingEngine.h" -namespace OpenRCT2 { namespace Drawing +namespace OpenRCT2 { - class X8DrawingContext; - - struct DirtyGrid + namespace Paint { - uint32 BlockShiftX; - uint32 BlockShiftY; - uint32 BlockWidth; - uint32 BlockHeight; - uint32 BlockColumns; - uint32 BlockRows; - uint8 * Blocks; - }; + class Painter; + } - class X8RainDrawer final : public IRainDrawer + namespace Ui { - private: - struct RainPixel + interface IUiContext; + } + + namespace Drawing + { + class X8DrawingContext; + + struct DirtyGrid { - uint32 Position; - uint8 Colour; + uint32 BlockShiftX; + uint32 BlockShiftY; + uint32 BlockWidth; + uint32 BlockHeight; + uint32 BlockColumns; + uint32 BlockRows; + uint8 * Blocks; }; - static constexpr uint32 MaxRainPixels = 0xFFFE; + class X8RainDrawer final : public IRainDrawer + { + private: + struct RainPixel + { + uint32 Position; + uint8 Colour; + }; - size_t _rainPixelsCapacity = MaxRainPixels; - uint32 _rainPixelsCount = 0; - RainPixel * _rainPixels = nullptr; - rct_drawpixelinfo * _screenDPI = nullptr; + static constexpr uint32 MaxRainPixels = 0xFFFE; - public: - X8RainDrawer(); - ~X8RainDrawer(); - void SetDPI(rct_drawpixelinfo * dpi); - void Draw(sint32 x, sint32 y, sint32 width, sint32 height, sint32 xStart, sint32 yStart) override; - void Restore(); - }; + size_t _rainPixelsCapacity = MaxRainPixels; + uint32 _rainPixelsCount = 0; + RainPixel * _rainPixels = nullptr; + rct_drawpixelinfo * _screenDPI = nullptr; -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wsuggest-final-types" - class X8DrawingEngine : public IDrawingEngine - { - protected: - uint32 _width = 0; - uint32 _height = 0; - uint32 _pitch = 0; - size_t _bitsSize = 0; - uint8 * _bits = nullptr; + public: + X8RainDrawer(); + ~X8RainDrawer(); + void SetDPI(rct_drawpixelinfo * dpi); + void Draw(sint32 x, sint32 y, sint32 width, sint32 height, sint32 xStart, sint32 yStart) override; + void Restore(); + }; - DirtyGrid _dirtyGrid = { 0 }; + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wsuggest-final-types" + class X8DrawingEngine : public IDrawingEngine + { + private: + Paint::Painter * _painter = nullptr; - rct_drawpixelinfo _bitsDPI = { 0 }; + protected: + uint32 _width = 0; + uint32 _height = 0; + uint32 _pitch = 0; + size_t _bitsSize = 0; + uint8 * _bits = nullptr; -#ifdef __ENABLE_LIGHTFX__ - bool _lastLightFXenabled = false; -#endif + DirtyGrid _dirtyGrid = { 0 }; - X8RainDrawer _rainDrawer; - X8DrawingContext * _drawingContext; + rct_drawpixelinfo _bitsDPI = { 0 }; - public: - explicit X8DrawingEngine(); - ~X8DrawingEngine() override; + #ifdef __ENABLE_LIGHTFX__ + bool _lastLightFXenabled = false; + #endif - void Initialise() override; - void Resize(uint32 width, uint32 height) override; - void SetPalette(const rct_palette_entry * palette) override; - void SetUncappedFrameRate(bool uncapped) override; - void Invalidate(sint32 left, sint32 top, sint32 right, sint32 bottom) override; - void Draw() override; - void CopyRect(sint32 x, sint32 y, sint32 width, sint32 height, sint32 dx, sint32 dy) override; - sint32 Screenshot() override; - IDrawingContext * GetDrawingContext(rct_drawpixelinfo * dpi) override; - rct_drawpixelinfo * GetDrawingPixelInfo() override; - DRAWING_ENGINE_FLAGS GetFlags() override; - void InvalidateImage(uint32 image) override; + X8RainDrawer _rainDrawer; + X8DrawingContext * _drawingContext; - rct_drawpixelinfo * GetDPI(); + public: + explicit X8DrawingEngine(Ui::IUiContext * uiContext); + ~X8DrawingEngine() override; - protected: - void ConfigureBits(uint32 width, uint32 height, uint32 pitch); + void Initialise() override; + void Resize(uint32 width, uint32 height) override; + void SetPalette(const rct_palette_entry * palette) override; + void SetUncappedFrameRate(bool uncapped) override; + void Invalidate(sint32 left, sint32 top, sint32 right, sint32 bottom) override; + void Draw() override; + void CopyRect(sint32 x, sint32 y, sint32 width, sint32 height, sint32 dx, sint32 dy) override; + sint32 Screenshot() override; + IDrawingContext * GetDrawingContext(rct_drawpixelinfo * dpi) override; + rct_drawpixelinfo * GetDrawingPixelInfo() override; + DRAWING_ENGINE_FLAGS GetFlags() override; + void InvalidateImage(uint32 image) override; - private: - void ConfigureDirtyGrid(); - static void ResetWindowVisbilities(); - void DrawAllDirtyBlocks(); - void DrawDirtyBlocks(uint32 x, uint32 y, uint32 columns, uint32 rows); - }; -#pragma GCC diagnostic pop + rct_drawpixelinfo * GetDPI(); - class X8DrawingContext final : public IDrawingContext - { - private: - X8DrawingEngine * _engine = nullptr; - rct_drawpixelinfo * _dpi = nullptr; + protected: + void ConfigureBits(uint32 width, uint32 height, uint32 pitch); - public: - explicit X8DrawingContext(X8DrawingEngine * engine); - ~X8DrawingContext() override; + private: + void ConfigureDirtyGrid(); + static void ResetWindowVisbilities(); + void DrawAllDirtyBlocks(); + void DrawDirtyBlocks(uint32 x, uint32 y, uint32 columns, uint32 rows); + }; + #pragma GCC diagnostic pop - IDrawingEngine * GetEngine() override; + class X8DrawingContext final : public IDrawingContext + { + private: + X8DrawingEngine * _engine = nullptr; + rct_drawpixelinfo * _dpi = nullptr; - void Clear(uint8 paletteIndex) override; - void FillRect(uint32 colour, sint32 x, sint32 y, sint32 w, sint32 h) override; - void FilterRect(FILTER_PALETTE_ID palette, sint32 left, sint32 top, sint32 right, sint32 bottom) override; - void DrawLine(uint32 colour, sint32 x1, sint32 y1, sint32 x2, sint32 y2) override; - void DrawSprite(uint32 image, sint32 x, sint32 y, uint32 tertiaryColour) override; - void DrawSpriteRawMasked(sint32 x, sint32 y, uint32 maskImage, uint32 colourImage) override; - void DrawSpriteSolid(uint32 image, sint32 x, sint32 y, uint8 colour) override; - void DrawGlyph(uint32 image, sint32 x, sint32 y, uint8 * palette) override; + public: + explicit X8DrawingContext(X8DrawingEngine * engine); + ~X8DrawingContext() override; - void SetDPI(rct_drawpixelinfo * dpi); - }; -} } + IDrawingEngine * GetEngine() override; + + void Clear(uint8 paletteIndex) override; + void FillRect(uint32 colour, sint32 x, sint32 y, sint32 w, sint32 h) override; + void FilterRect(FILTER_PALETTE_ID palette, sint32 left, sint32 top, sint32 right, sint32 bottom) override; + void DrawLine(uint32 colour, sint32 x1, sint32 y1, sint32 x2, sint32 y2) override; + void DrawSprite(uint32 image, sint32 x, sint32 y, uint32 tertiaryColour) override; + void DrawSpriteRawMasked(sint32 x, sint32 y, uint32 maskImage, uint32 colourImage) override; + void DrawSpriteSolid(uint32 image, sint32 x, sint32 y, uint8 colour) override; + void DrawGlyph(uint32 image, sint32 x, sint32 y, uint8 * palette) override; + + void SetDPI(rct_drawpixelinfo * dpi); + }; + } +} diff --git a/src/openrct2/drawing/drawing.h b/src/openrct2/drawing/drawing.h index d764d1303a..b45660347b 100644 --- a/src/openrct2/drawing/drawing.h +++ b/src/openrct2/drawing/drawing.h @@ -363,8 +363,6 @@ void shorten_path(utf8 *buffer, size_t bufferSize, const utf8 *path, sint32 avai void scrolling_text_initialise_bitmaps(); sint32 scrolling_text_setup(rct_string_id stringId, uint16 scroll, uint16 scrollingMode); -void rct2_draw(rct_drawpixelinfo *dpi); - #include "NewDrawing.h" #endif diff --git a/src/openrct2/paint/Painter.cpp b/src/openrct2/paint/Painter.cpp new file mode 100644 index 0000000000..3b81e21ce5 --- /dev/null +++ b/src/openrct2/paint/Painter.cpp @@ -0,0 +1,103 @@ +#pragma region Copyright (c) 2014-2017 OpenRCT2 Developers +/***************************************************************************** + * OpenRCT2, an open source clone of Roller Coaster Tycoon 2. + * + * OpenRCT2 is the work of many authors, a full list can be found in contributors.md + * For more information, visit https://github.com/OpenRCT2/OpenRCT2 + * + * OpenRCT2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * A full copy of the GNU General Public License can be found in licence.txt + *****************************************************************************/ +#pragma endregion + +#include "../config/Config.h" +#include "../title/TitleScreen.h" +#include "../ui/UiContext.h" +#include "Painter.h" + +extern "C" +{ + #include "../drawing/drawing.h" + #include "../game.h" + #include "../interface/chat.h" + #include "../interface/console.h" + #include "../intro.h" + #include "../localisation/localisation.h" +} + +using namespace OpenRCT2; +using namespace OpenRCT2::Paint; +using namespace OpenRCT2::Ui; + +Painter::Painter(IUiContext * uiContext) + : _uiContext(uiContext) +{ +} + +void Painter::Paint(rct_drawpixelinfo * dpi) +{ + if (gIntroState != INTRO_STATE_NONE) + { + return; + } + + update_palette_effects(); + + chat_draw(dpi); + console_draw(dpi); + + if ((gScreenFlags & SCREEN_FLAGS_TITLE_DEMO) && !gTitleHideVersionInfo) + { + DrawOpenRCT2(dpi, 0, _uiContext->GetHeight() - 20); + } + + if (gConfigGeneral.show_fps) + { + PaintFPS(dpi); + } + + gCurrentDrawCount++; +} + +void Painter::PaintFPS(rct_drawpixelinfo * dpi) +{ + sint32 x = _uiContext->GetWidth() / 2; + sint32 y = 2; + + // Measure FPS + MeasureFPS(); + + // Format string + utf8 buffer[64] = { 0 }; + utf8 * ch = buffer; + ch = utf8_write_codepoint(ch, FORMAT_MEDIUMFONT); + ch = utf8_write_codepoint(ch, FORMAT_OUTLINE); + ch = utf8_write_codepoint(ch, FORMAT_WHITE); + + snprintf(ch, 64 - (ch - buffer), "%d", _currentFPS); + + // Draw Text + sint32 stringWidth = gfx_get_string_width(buffer); + x = x - (stringWidth / 2); + gfx_draw_string(dpi, buffer, 0, x, y); + + // Make area dirty so the text doesn't get drawn over the last + gfx_set_dirty_blocks(x - 16, y - 4, gLastDrawStringX + 16, 16); +} + +void Painter::MeasureFPS() +{ + _frames++; + + auto currentTime = time(nullptr); + if (currentTime != _lastSecond) + { + _currentFPS = _frames; + _frames = 0; + } + _lastSecond = currentTime; +} diff --git a/src/openrct2/paint/Painter.h b/src/openrct2/paint/Painter.h new file mode 100644 index 0000000000..f752d8f901 --- /dev/null +++ b/src/openrct2/paint/Painter.h @@ -0,0 +1,49 @@ +#pragma region Copyright (c) 2014-2017 OpenRCT2 Developers +/***************************************************************************** + * OpenRCT2, an open source clone of Roller Coaster Tycoon 2. + * + * OpenRCT2 is the work of many authors, a full list can be found in contributors.md + * For more information, visit https://github.com/OpenRCT2/OpenRCT2 + * + * OpenRCT2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * A full copy of the GNU General Public License can be found in licence.txt + *****************************************************************************/ +#pragma endregion + +#include +#include "../common.h" + +struct rct_drawpixelinfo; + +namespace OpenRCT2 +{ + namespace Ui + { + interface IUiContext; + } + + namespace Paint + { + class Painter final + { + private: + Ui::IUiContext * const _uiContext; + + time_t _lastSecond = 0; + sint32 _currentFPS = 0; + sint32 _frames = 0; + + public: + Painter(Ui::IUiContext * uiContext); + void Paint(rct_drawpixelinfo * dpi); + + private: + void PaintFPS(rct_drawpixelinfo * dpi); + void MeasureFPS(); + }; + } +} diff --git a/src/openrct2/rct2.c b/src/openrct2/rct2.c index d7efca9542..3d3dc302eb 100644 --- a/src/openrct2/rct2.c +++ b/src/openrct2/rct2.c @@ -127,8 +127,6 @@ typedef struct tm tm_t; void print_launch_information(); -static void rct2_draw_fps(rct_drawpixelinfo *dpi); - void rct2_quit() { gSavePromptMode = PM_QUIT; @@ -192,77 +190,6 @@ void substitute_path(char *dest, size_t size, const char *path, const char *file safe_strcpy(dest, filename, size - written); } -void rct2_draw(rct_drawpixelinfo *dpi) -{ - if (gIntroState != INTRO_STATE_NONE) { - return; - } - - // redraw_rain(); - // window_update_all(); - // gfx_invalidate_pickedup_peep(); - // gfx_draw_pickedup_peep(); - // update_rain_animation(); - update_palette_effects(); - - chat_draw(dpi); - console_draw(dpi); - - if ((gScreenFlags & SCREEN_FLAGS_TITLE_DEMO) && !gTitleHideVersionInfo) { - DrawOpenRCT2(dpi, 0, context_get_height() - 20); - } - - if (gConfigGeneral.show_fps) { - rct2_draw_fps(dpi); - } - - gCurrentDrawCount++; -} - -static time_t _lastSecond; -static sint32 _currentFPS; -static sint32 _frames; - -static void rct2_measure_fps() -{ - _frames++; - - time_t currentTime = time(NULL); - - if (currentTime != _lastSecond) { - _currentFPS = _frames; - _frames = 0; - } - - _lastSecond = currentTime; -} - -static void rct2_draw_fps(rct_drawpixelinfo *dpi) -{ - sint32 x = context_get_width() / 2; - sint32 y = 2; - - // Measure FPS - rct2_measure_fps(); - - // Format string - utf8 buffer[64]; - utf8 *ch = buffer; - ch = utf8_write_codepoint(ch, FORMAT_MEDIUMFONT); - ch = utf8_write_codepoint(ch, FORMAT_OUTLINE); - ch = utf8_write_codepoint(ch, FORMAT_WHITE); - - snprintf(ch, 64 - (ch - buffer), "%d", _currentFPS); - - // Draw Text - sint32 stringWidth = gfx_get_string_width(buffer); - x = x - (stringWidth / 2); - gfx_draw_string(dpi, buffer, 0, x, y); - - // Make area dirty so the text doesn't get drawn over the last - gfx_set_dirty_blocks(x - 16, y - 4, gLastDrawStringX + 16, 16); -} - /** * * rct2: 0x00674E6C diff --git a/src/openrct2/title/TitleScreen.h b/src/openrct2/title/TitleScreen.h index 58b94a7f2e..dc8666bbbc 100644 --- a/src/openrct2/title/TitleScreen.h +++ b/src/openrct2/title/TitleScreen.h @@ -16,12 +16,12 @@ #pragma once -#include "../drawing/drawing.h" - #ifdef __cplusplus extern "C" { #endif + #include "../drawing/drawing.h" + extern bool gTitleHideVersionInfo; extern uint16 gTitleCurrentSequence; diff --git a/src/openrct2/ui/DummyUiContext.cpp b/src/openrct2/ui/DummyUiContext.cpp index 8aa168560e..ca89441286 100644 --- a/src/openrct2/ui/DummyUiContext.cpp +++ b/src/openrct2/ui/DummyUiContext.cpp @@ -64,7 +64,7 @@ namespace OpenRCT2 { namespace Ui // Drawing Drawing::IDrawingEngine * CreateDrawingEngine(Drawing::DRAWING_ENGINE_TYPE type) override { - return new X8DrawingEngine(); + return new X8DrawingEngine(this); } // Text input