mirror of https://github.com/OpenRCT2/OpenRCT2.git
Prevent viewport_invalidate from causing covered viewports to redraw and cache window and viewport visibility.
This commit is contained in:
parent
19d873fedf
commit
5c9110b99a
|
@ -365,6 +365,8 @@ public:
|
|||
_rainDrawer.SetDPI(&_bitsDPI);
|
||||
_rainDrawer.Restore();
|
||||
|
||||
ResetWindowVisbilities();
|
||||
|
||||
// Redraw dirty regions before updating the viewports, otherwise
|
||||
// when viewports get panned, they copy dirty pixels
|
||||
DrawAllDirtyBlocks();
|
||||
|
@ -528,6 +530,16 @@ private:
|
|||
_dirtyGrid.Blocks = new uint8[_dirtyGrid.BlockColumns * _dirtyGrid.BlockRows];
|
||||
}
|
||||
|
||||
static void ResetWindowVisbilities()
|
||||
{
|
||||
// reset window visibilty status to unknown
|
||||
for (rct_window *w = g_window_list; w < gWindowNextSlot; w++)
|
||||
{
|
||||
w->visibility = VC_UNKNOWN;
|
||||
if (w->viewport != NULL) w->viewport->visibility = VC_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
void DrawAllDirtyBlocks()
|
||||
{
|
||||
uint32 dirtyBlockColumns = _dirtyGrid.BlockColumns;
|
||||
|
|
|
@ -1396,6 +1396,23 @@ void get_map_coordinates_from_pos(int screenX, int screenY, int flags, sint16 *x
|
|||
*/
|
||||
void viewport_invalidate(rct_viewport *viewport, int left, int top, int right, int bottom)
|
||||
{
|
||||
// if unknown viewport visibility, use the containing window to discover the status
|
||||
if (viewport->visibility == VC_UNKNOWN)
|
||||
{
|
||||
for (rct_window *w = g_window_list; w < gWindowNextSlot; w++)
|
||||
{
|
||||
if (w->classification != WC_MAIN_WINDOW && w->viewport != NULL && w->viewport == viewport)
|
||||
{
|
||||
// note, window_is_visible will update viewport->visibility, so this should have a low hit count
|
||||
if (!window_is_visible(w)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (viewport->visibility == VC_COVERED) return;
|
||||
|
||||
int viewportLeft = viewport->view_x;
|
||||
int viewportTop = viewport->view_y;
|
||||
int viewportRight = viewport->view_x + viewport->view_width;
|
||||
|
|
|
@ -1464,6 +1464,8 @@ void window_zoom_out(rct_window *w)
|
|||
*/
|
||||
void window_draw(rct_drawpixelinfo *dpi, rct_window *w, int left, int top, int right, int bottom)
|
||||
{
|
||||
if (!window_is_visible(w)) return;
|
||||
|
||||
// Split window into only the regions that require drawing
|
||||
if (window_draw_split(dpi, w, left, top, right, bottom))
|
||||
return;
|
||||
|
@ -1476,8 +1478,6 @@ void window_draw(rct_drawpixelinfo *dpi, rct_window *w, int left, int top, int r
|
|||
if (left >= right) return;
|
||||
if (top >= bottom) return;
|
||||
|
||||
if (!window_is_visible(w)) return;
|
||||
|
||||
// Draw the window in this region
|
||||
for (rct_window *v = w; v < RCT2_NEW_WINDOW; v++) {
|
||||
// Don't draw overlapping opaque windows, they won't have changed
|
||||
|
@ -2482,10 +2482,16 @@ void window_update_textbox()
|
|||
|
||||
bool window_is_visible(rct_window* w)
|
||||
{
|
||||
// w->visibility is used to prevent repeat calculations within an iteration by caching the result
|
||||
|
||||
if (w->visibility == VC_VISIBLE) return true;
|
||||
if (w->visibility == VC_COVERED) return false;
|
||||
|
||||
// only consider viewports, consider the main window always visible
|
||||
if (w == NULL || w->viewport == NULL || w->classification == WC_MAIN_WINDOW)
|
||||
{
|
||||
// default to previous behavior
|
||||
// default to previous behaviour
|
||||
w->visibility = VC_VISIBLE;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -2498,10 +2504,14 @@ bool window_is_visible(rct_window* w)
|
|||
&& w_other->x + w_other->width >= w->x + w->width
|
||||
&& w_other->y + w_other->height >= w->y + w->height)
|
||||
{
|
||||
w->visibility = VC_COVERED;
|
||||
w->viewport->visibility = VC_COVERED;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// default to previous behavior
|
||||
// default to previous behaviour
|
||||
w->visibility = VC_VISIBLE;
|
||||
w->viewport->visibility = VC_VISIBLE;
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -85,6 +85,7 @@ typedef struct rct_viewport {
|
|||
uint8 zoom; // 0x10
|
||||
uint8 var_11;
|
||||
uint16 flags; // 0x12
|
||||
uint8 visibility; // VISIBILITY_CACHE
|
||||
} rct_viewport;
|
||||
|
||||
/**
|
||||
|
@ -288,6 +289,7 @@ typedef struct rct_window {
|
|||
sint8 var_4B8;
|
||||
sint8 var_4B9;
|
||||
uint8 colours[6]; // 0x4BA
|
||||
uint8 visibility; // VISIBILITY_CACHE
|
||||
} rct_window;
|
||||
|
||||
#define RCT_WINDOW_RIGHT(w) (w->x + w->width)
|
||||
|
@ -493,6 +495,13 @@ enum {
|
|||
MODAL_RESULT_OK
|
||||
};
|
||||
|
||||
enum VISIBILITY_CACHE
|
||||
{
|
||||
VC_UNKNOWN = 0,
|
||||
VC_VISIBLE = 1,
|
||||
VC_COVERED = 2
|
||||
};
|
||||
|
||||
typedef void (*modal_callback)(int result);
|
||||
typedef void (*scenarioselect_callback)(const utf8 *path);
|
||||
|
||||
|
|
Loading…
Reference in New Issue