mirror of
https://github.com/OpenRCT2/OpenRCT2
synced 2026-01-16 03:23:15 +01:00
Merge pull request #6235 from IntelOrca/feature/dirty-visuals
Add drawing debug option for showing visuals when and where blocks of the screen are painted. This will currently only work in hardware display drawing engine.
This commit is contained in:
@@ -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 #
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
- Feature: [#3994] Show bottom toolbar with map tooltip (theme option).
|
||||
- Feature: [#6078] Game now converts mp.dat to SC21.SC4 (Mega Park) automatically.
|
||||
- Feature: [#6181] Map generator now allows adjusting random terrain and tree placement in Simplex Noise tab.
|
||||
- Feature: [#6235] Add drawing debug option for showing visuals when and where blocks of the screen are painted.
|
||||
- Fix: [#816] In the map window, there are more peeps flickering than there are selected (original bug).
|
||||
- Fix: [#1833, #4937, #6138] 'Too low!' warning when building rides and shops on the lowest land level (original bug).
|
||||
- Fix: [#5417] Hacked Crooked House tracked rides do not dispatch vehicles.
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
*****************************************************************************/
|
||||
#pragma endregion
|
||||
|
||||
#include <vector>
|
||||
#include <openrct2/common.h>
|
||||
#include <SDL.h>
|
||||
#include <openrct2/config/Config.h>
|
||||
@@ -26,6 +27,7 @@ extern "C"
|
||||
{
|
||||
#include <openrct2/drawing/lightfx.h>
|
||||
#include <openrct2/game.h>
|
||||
#include <openrct2/paint/paint.h>
|
||||
}
|
||||
|
||||
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<uint32> _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 };
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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
|
||||
};
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user