From 3f1991804ac033d2dc763a12c443ec74751b68d0 Mon Sep 17 00:00:00 2001 From: Ted John Date: Thu, 31 Aug 2017 22:31:57 +0100 Subject: [PATCH] Add debug option to show dirty blocks --- data/language/en-GB.txt | 1 + .../engines/HardwareDisplayDrawingEngine.cpp | 96 +++++++++++++++++++ src/openrct2-ui/windows/DebugPaint.cpp | 24 +++-- src/openrct2/drawing/X8DrawingEngine.cpp | 5 + src/openrct2/drawing/X8DrawingEngine.h | 1 + src/openrct2/localisation/string_ids.h | 2 + src/openrct2/paint/paint.c | 1 + src/openrct2/paint/paint.h | 1 + 8 files changed, 125 insertions(+), 6 deletions(-) diff --git a/data/language/en-GB.txt b/data/language/en-GB.txt index 28f889fcfb..2e3f35814b 100644 --- a/data/language/en-GB.txt +++ b/data/language/en-GB.txt @@ -4452,6 +4452,7 @@ STR_6140 :Changelog... STR_6141 :RCT1 Bottom Toolbar STR_6142 :{WINDOW_COLOUR_2}Track name: {BLACK}{STRING} STR_6143 :{WINDOW_COLOUR_2}Ride type: {BLACK}{STRINGID} +STR_6144 :Show dirty visuals ############# # Scenarios # diff --git a/src/openrct2-ui/drawing/engines/HardwareDisplayDrawingEngine.cpp b/src/openrct2-ui/drawing/engines/HardwareDisplayDrawingEngine.cpp index a7ecb40915..fd89fd74b9 100644 --- a/src/openrct2-ui/drawing/engines/HardwareDisplayDrawingEngine.cpp +++ b/src/openrct2-ui/drawing/engines/HardwareDisplayDrawingEngine.cpp @@ -14,6 +14,7 @@ *****************************************************************************/ #pragma endregion +#include #include #include #include @@ -26,6 +27,7 @@ extern "C" { #include #include + #include } using namespace OpenRCT2; @@ -35,6 +37,8 @@ using namespace OpenRCT2::Ui; class HardwareDisplayDrawingEngine final : public X8DrawingEngine { private: + constexpr static uint32 DIRTY_VISUAL_TIME = 32; + IUiContext * const _uiContext; SDL_Window * _window = nullptr; SDL_Renderer * _sdlRenderer = nullptr; @@ -51,6 +55,8 @@ private: bool _overlayActive = false; bool _pausedBeforeOverlay = false; + std::vector _dirtyVisualsTime; + public: explicit HardwareDisplayDrawingEngine(IUiContext * uiContext) : X8DrawingEngine(uiContext), @@ -130,6 +136,27 @@ public: void EndDraw() override { Display(); + if (gShowDirtyVisuals) + { + UpdateDirtyVisuals(); + } + } + +protected: + void OnDrawDirtyBlock(uint32 left, uint32 top, uint32 columns, uint32 rows) override + { + if (gShowDirtyVisuals) + { + uint32 right = left + columns; + uint32 bottom = top + rows; + for (uint32 x = left; x < right; x++) + { + for (uint32 y = top; y < bottom; y++) + { + SetDirtyVisualTime(x, y, DIRTY_VISUAL_TIME); + } + } + } } private: @@ -153,6 +180,11 @@ private: } SDL_RenderCopy(_sdlRenderer, _screenTexture, nullptr, nullptr); + if (gShowDirtyVisuals) + { + RenderDirtyVisuals(); + } + bool isSteamOverlayActive = GetContext()->GetUiContext()->IsSteamOverlayActive(); if (isSteamOverlayActive && gConfigGeneral.steam_overlay_pause) { @@ -215,6 +247,70 @@ private: } } + uint32 GetDirtyVisualTime(uint32 x, uint32 y) + { + uint32 result = 0; + uint32 i = y * _dirtyGrid.BlockColumns + x; + if (_dirtyVisualsTime.size() > i) + { + result = _dirtyVisualsTime[i]; + } + return result; + } + + void SetDirtyVisualTime(uint32 x, uint32 y, uint32 value) + { + uint32 i = y * _dirtyGrid.BlockColumns + x; + if (_dirtyVisualsTime.size() > i) + { + _dirtyVisualsTime[i] = value; + } + } + + void UpdateDirtyVisuals() + { + _dirtyVisualsTime.resize(_dirtyGrid.BlockRows * _dirtyGrid.BlockColumns); + for (uint32 y = 0; y < _dirtyGrid.BlockRows; y++) + { + for (uint32 x = 0; x < _dirtyGrid.BlockColumns; x++) + { + auto timeLeft = GetDirtyVisualTime(x, y); + if (timeLeft > 0) + { + SetDirtyVisualTime(x, y, timeLeft - 1); + } + } + } + } + + void RenderDirtyVisuals() + { + float scaleX = gConfigGeneral.window_scale; + float scaleY = gConfigGeneral.window_scale; + + SDL_SetRenderDrawBlendMode(_sdlRenderer, SDL_BLENDMODE_BLEND); + for (uint32 y = 0; y < _dirtyGrid.BlockRows; y++) + { + for (uint32 x = 0; x < _dirtyGrid.BlockColumns; x++) + { + auto timeLeft = GetDirtyVisualTime(x, y); + if (timeLeft > 0) + { + uint8 alpha = (uint8)(timeLeft * 5 / 2); + + SDL_Rect ddRect; + ddRect.x = (sint32)(x * _dirtyGrid.BlockWidth * scaleX); + ddRect.y = (sint32)(y * _dirtyGrid.BlockHeight * scaleY); + ddRect.w = (sint32)(_dirtyGrid.BlockWidth * scaleX); + ddRect.h = (sint32)(_dirtyGrid.BlockHeight * scaleY); + + SDL_SetRenderDrawColor(_sdlRenderer, 255, 255, 255, alpha); + SDL_RenderFillRect(_sdlRenderer, &ddRect); + } + } + } + } + void ReadCentrePixel(uint32 * pixel) { SDL_Rect centrePixelRegion = { (sint32)(_width / 2), (sint32)(_height / 2), 1, 1 }; diff --git a/src/openrct2-ui/windows/DebugPaint.cpp b/src/openrct2-ui/windows/DebugPaint.cpp index bc8439befc..2387330d6c 100644 --- a/src/openrct2-ui/windows/DebugPaint.cpp +++ b/src/openrct2-ui/windows/DebugPaint.cpp @@ -31,16 +31,18 @@ enum WINDOW_DEBUG_PAINT_WIDGET_IDX WIDX_TOGGLE_OLD_DRAWING, WIDX_TOGGLE_SHOW_SEGMENT_HEIGHTS, WIDX_TOGGLE_SHOW_BOUND_BOXES, + WIDX_TOGGLE_SHOW_DIRTY_VISUALS, }; #define WINDOW_WIDTH (200) -#define WINDOW_HEIGHT (8 + 15 + 15 + 11 + 8) +#define WINDOW_HEIGHT (8 + 15 + 15 + 15 + 11 + 8) static rct_widget window_debug_paint_widgets[] = { - { WWT_FRAME, 0, 0, WINDOW_WIDTH - 1, 0, WINDOW_HEIGHT - 1, 0xFFFFFFFF, STR_NONE}, - { WWT_CHECKBOX, 1, 8, WINDOW_WIDTH - 8, 8, 8 + 11, STR_DEBUG_PAINT_USE_OLD_DRAWING, STR_NONE}, - { WWT_CHECKBOX, 1, 8, WINDOW_WIDTH - 8, 8 + 15, 8 + 15 + 11, STR_DEBUG_PAINT_SHOW_SEGMENT_HEIGHTS, STR_NONE}, - { WWT_CHECKBOX, 1, 8, WINDOW_WIDTH - 8, 8 + 15 + 15, 8 + 15 + 15 + 11, STR_DEBUG_PAINT_SHOW_BOUND_BOXES, STR_NONE}, + { WWT_FRAME, 0, 0, WINDOW_WIDTH - 1, 0, WINDOW_HEIGHT - 1, 0xFFFFFFFF, STR_NONE }, + { WWT_CHECKBOX, 1, 8, WINDOW_WIDTH - 8, 8, 8 + 11, STR_DEBUG_PAINT_USE_OLD_DRAWING, STR_NONE }, + { WWT_CHECKBOX, 1, 8, WINDOW_WIDTH - 8, 8 + 15, 8 + 15 + 11, STR_DEBUG_PAINT_SHOW_SEGMENT_HEIGHTS, STR_NONE }, + { WWT_CHECKBOX, 1, 8, WINDOW_WIDTH - 8, 8 + 15 + 15, 8 + 15 + 15 + 11, STR_DEBUG_PAINT_SHOW_BOUND_BOXES, STR_NONE }, + { WWT_CHECKBOX, 1, 8, WINDOW_WIDTH - 8, 8 + 15 + 15 + 15, 8 + 15 + 15 + 15 + 11, STR_DEBUG_PAINT_SHOW_DIRTY_VISUALS, STR_NONE }, { WIDGETS_END }, }; @@ -99,7 +101,11 @@ rct_window * window_debug_paint_open() ); window->widgets = window_debug_paint_widgets; - window->enabled_widgets = (1 << WIDX_TOGGLE_OLD_DRAWING) | (1 << WIDX_TOGGLE_SHOW_BOUND_BOXES) | (1 << WIDX_TOGGLE_SHOW_SEGMENT_HEIGHTS); + window->enabled_widgets = + (1 << WIDX_TOGGLE_OLD_DRAWING) | + (1 << WIDX_TOGGLE_SHOW_BOUND_BOXES) | + (1 << WIDX_TOGGLE_SHOW_SEGMENT_HEIGHTS) | + (1 << WIDX_TOGGLE_SHOW_DIRTY_VISUALS); window_init_scroll_widgets(window); window_push_others_below(window); @@ -126,6 +132,11 @@ static void window_debug_paint_mouseup(rct_window * w, rct_widgetindex widgetInd gPaintBoundingBoxes = !gPaintBoundingBoxes; gfx_invalidate_screen(); break; + + case WIDX_TOGGLE_SHOW_DIRTY_VISUALS: + gShowDirtyVisuals = !gShowDirtyVisuals; + gfx_invalidate_screen(); + break; } } @@ -134,6 +145,7 @@ static void window_debug_paint_invalidate(rct_window * w) widget_set_checkbox_value(w, WIDX_TOGGLE_OLD_DRAWING, gUseOriginalRidePaint); widget_set_checkbox_value(w, WIDX_TOGGLE_SHOW_SEGMENT_HEIGHTS, gShowSupportSegmentHeights); widget_set_checkbox_value(w, WIDX_TOGGLE_SHOW_BOUND_BOXES, gPaintBoundingBoxes); + widget_set_checkbox_value(w, WIDX_TOGGLE_SHOW_DIRTY_VISUALS, gShowDirtyVisuals); } static void window_debug_paint_paint(rct_window * w, rct_drawpixelinfo * dpi) diff --git a/src/openrct2/drawing/X8DrawingEngine.cpp b/src/openrct2/drawing/X8DrawingEngine.cpp index 262d676916..88953b4622 100644 --- a/src/openrct2/drawing/X8DrawingEngine.cpp +++ b/src/openrct2/drawing/X8DrawingEngine.cpp @@ -369,6 +369,10 @@ void X8DrawingEngine::ConfigureBits(uint32 width, uint32 height, uint32 pitch) #endif } +void X8DrawingEngine::OnDrawDirtyBlock(uint32 x, uint32 y, uint32 columns, uint32 rows) +{ +} + void X8DrawingEngine::ConfigureDirtyGrid() { _dirtyGrid.BlockShiftX = 7; @@ -466,6 +470,7 @@ void X8DrawingEngine::DrawDirtyBlocks(uint32 x, uint32 y, uint32 columns, uint32 } // Draw region + OnDrawDirtyBlock(x, y, columns, rows); window_draw_all(&_bitsDPI, left, top, right, bottom); } diff --git a/src/openrct2/drawing/X8DrawingEngine.h b/src/openrct2/drawing/X8DrawingEngine.h index 55ef22de52..d9a0e52b55 100644 --- a/src/openrct2/drawing/X8DrawingEngine.h +++ b/src/openrct2/drawing/X8DrawingEngine.h @@ -114,6 +114,7 @@ namespace OpenRCT2 protected: void ConfigureBits(uint32 width, uint32 height, uint32 pitch); + virtual void OnDrawDirtyBlock(uint32 x, uint32 y, uint32 columns, uint32 rows); private: void ConfigureDirtyGrid(); diff --git a/src/openrct2/localisation/string_ids.h b/src/openrct2/localisation/string_ids.h index 33c05b34c1..12a9cb2a9c 100644 --- a/src/openrct2/localisation/string_ids.h +++ b/src/openrct2/localisation/string_ids.h @@ -3791,6 +3791,8 @@ enum { STR_TRACK_DESIGN_NAME = 6142, STR_TRACK_DESIGN_TYPE = 6143, + STR_DEBUG_PAINT_SHOW_DIRTY_VISUALS = 6144, + // Have to include resource strings (from scenarios and objects) for the time being now that language is partially working STR_COUNT = 32768 }; diff --git a/src/openrct2/paint/paint.c b/src/openrct2/paint/paint.c index 4e366bc82c..f2fa618451 100644 --- a/src/openrct2/paint/paint.c +++ b/src/openrct2/paint/paint.c @@ -75,6 +75,7 @@ static const uint8 BoundBoxDebugColours[] = { 222, // BANNER }; +bool gShowDirtyVisuals; bool gPaintBoundingBoxes; static void paint_attached_ps(rct_drawpixelinfo * dpi, paint_struct * ps, uint32 viewFlags); diff --git a/src/openrct2/paint/paint.h b/src/openrct2/paint/paint.h index c9d2ebe615..a67f119346 100644 --- a/src/openrct2/paint/paint.h +++ b/src/openrct2/paint/paint.h @@ -161,6 +161,7 @@ extern paint_string_struct * gPaintPSStringHead; /** rct2: 0x00993CC4 */ extern const uint32 construction_markers[]; +extern bool gShowDirtyVisuals; extern bool gPaintBoundingBoxes; paint_struct * sub_98196C(uint32 image_id, sint8 x_offset, sint8 y_offset, sint16 bound_box_length_x, sint16 bound_box_length_y, sint8 bound_box_length_z, sint16 z_offset, uint32 rotation);