mirror of
https://github.com/OpenRCT2/OpenRCT2
synced 2026-01-17 20:13:07 +01:00
Add clip selection
This allows the user to select an area of tiles. Anything outside of this area won't be drawn.
This commit is contained in:
@@ -3315,7 +3315,7 @@ static void top_toolbar_init_view_menu(rct_window* w, rct_widget* widget) {
|
||||
dropdown_set_checked(11, true);
|
||||
if (mainViewport->flags & VIEWPORT_FLAG_PATH_HEIGHTS)
|
||||
dropdown_set_checked(12, true);
|
||||
if (mainViewport->flags & VIEWPORT_FLAG_PAINT_CLIP_TO_HEIGHT)
|
||||
if (mainViewport->flags & VIEWPORT_FLAG_CLIP_VIEW)
|
||||
dropdown_set_checked(DDIDX_VIEW_CLIPPING, true);
|
||||
if (mainViewport->flags & VIEWPORT_FLAG_HIGHLIGHT_PATH_ISSUES)
|
||||
dropdown_set_checked(DDIDX_HIGHLIGHT_PATH_ISSUES, true);
|
||||
@@ -3370,7 +3370,7 @@ static void top_toolbar_view_menu_dropdown(sint16 dropdownIndex)
|
||||
context_open_window(WC_VIEW_CLIPPING);
|
||||
} else {
|
||||
// If window is already open, toggle the view clipping on/off
|
||||
w->viewport->flags ^= VIEWPORT_FLAG_PAINT_CLIP_TO_HEIGHT;
|
||||
w->viewport->flags ^= VIEWPORT_FLAG_CLIP_VIEW;
|
||||
}
|
||||
break;
|
||||
case DDIDX_HIGHLIGHT_PATH_ISSUES:
|
||||
|
||||
@@ -15,14 +15,15 @@
|
||||
#pragma endregion
|
||||
|
||||
#include <cmath>
|
||||
|
||||
#include <openrct2/config/Config.h>
|
||||
#include <openrct2-ui/windows/Window.h>
|
||||
|
||||
#include <openrct2-ui/interface/Widget.h>
|
||||
#include <openrct2-ui/interface/Viewport.h>
|
||||
#include <openrct2-ui/interface/Widget.h>
|
||||
#include <openrct2-ui/windows/Window.h>
|
||||
#include <openrct2/Input.h>
|
||||
#include <openrct2/config/Config.h>
|
||||
#include <openrct2/drawing/Drawing.h>
|
||||
#include <openrct2/localisation/Localisation.h>
|
||||
#include <openrct2/paint/Paint.h>
|
||||
#include <openrct2/world/Location.hpp>
|
||||
|
||||
enum WINDOW_VIEW_CLIPPING_WIDGET_IDX {
|
||||
WIDX_BACKGROUND,
|
||||
@@ -32,7 +33,8 @@ enum WINDOW_VIEW_CLIPPING_WIDGET_IDX {
|
||||
WIDX_CLIP_HEIGHT_VALUE,
|
||||
WIDX_CLIP_HEIGHT_INCREASE,
|
||||
WIDX_CLIP_HEIGHT_DECREASE,
|
||||
WIDX_CLIP_HEIGHT_SLIDER
|
||||
WIDX_CLIP_HEIGHT_SLIDER,
|
||||
WIDX_CLIP_SELECTOR,
|
||||
};
|
||||
|
||||
enum class DISPLAY_TYPE {
|
||||
@@ -56,16 +58,26 @@ static rct_widget window_view_clipping_widgets[] = {
|
||||
{ WWT_BUTTON, 0, 138, 148, 35, 39, STR_NUMERIC_UP, STR_NONE }, // clip height increase
|
||||
{ WWT_BUTTON, 0, 138, 148, 40, 44, STR_NUMERIC_DOWN, STR_NONE }, // clip height decrease
|
||||
{ WWT_SCROLL, 0, 11, 149, 49, 61, SCROLL_HORIZONTAL, STR_VIEW_CLIPPING_HEIGHT_SCROLL_TIP }, // clip height scrollbar
|
||||
{ WWT_BUTTON, 0, 11, 149, 61, 73, STR_NONE, STR_NONE }, // selector
|
||||
{ WIDGETS_END }
|
||||
};
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#pragma region Members
|
||||
|
||||
static LocationXY16 _selectionStart;
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#pragma region Events
|
||||
|
||||
static void window_view_clipping_close_button(rct_window *w);
|
||||
static void window_view_clipping_mouseup(rct_window *w, rct_widgetindex widgetIndex);
|
||||
static void window_view_clipping_update(rct_window *w);
|
||||
static void window_view_clipping_tool_down(rct_window *w, rct_widgetindex widgetIndex, sint32 x, sint32 y);
|
||||
static void window_view_clipping_tool_drag(rct_window *w, rct_widgetindex widgetIndex, sint32 x, sint32 y);
|
||||
static void window_view_clipping_tool_up(struct rct_window*, rct_widgetindex, sint32, sint32);
|
||||
static void window_view_clipping_invalidate(rct_window *w);
|
||||
static void window_view_clipping_paint(rct_window *w, rct_drawpixelinfo *dpi);
|
||||
static void window_view_clipping_scrollgetsize(rct_window *w, int scrollIndex, int *width, int *height);
|
||||
@@ -82,9 +94,9 @@ static rct_window_event_list window_view_clipping_events = {
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
window_view_clipping_tool_down,
|
||||
window_view_clipping_tool_drag,
|
||||
window_view_clipping_tool_up,
|
||||
nullptr,
|
||||
nullptr,
|
||||
window_view_clipping_scrollgetsize,
|
||||
@@ -133,7 +145,8 @@ rct_window * window_view_clipping_open()
|
||||
(1ULL << WIDX_CLIP_HEIGHT_VALUE) |
|
||||
(1ULL << WIDX_CLIP_HEIGHT_INCREASE) |
|
||||
(1ULL << WIDX_CLIP_HEIGHT_DECREASE) |
|
||||
(1ULL << WIDX_CLIP_HEIGHT_SLIDER);
|
||||
(1ULL << WIDX_CLIP_HEIGHT_SLIDER) |
|
||||
(1ULL << WIDX_CLIP_SELECTOR);
|
||||
|
||||
window_init_scroll_widgets(window);
|
||||
|
||||
@@ -144,7 +157,7 @@ rct_window * window_view_clipping_open()
|
||||
|
||||
// Turn on view clipping when the window is opened.
|
||||
if (mainWindow != nullptr) {
|
||||
mainWindow->viewport->flags |= VIEWPORT_FLAG_PAINT_CLIP_TO_HEIGHT;
|
||||
mainWindow->viewport->flags |= VIEWPORT_FLAG_CLIP_VIEW;
|
||||
window_invalidate(mainWindow);
|
||||
}
|
||||
|
||||
@@ -156,7 +169,7 @@ static void window_view_clipping_close()
|
||||
// Turn off view clipping when the window is closed.
|
||||
rct_window *mainWindow = window_get_main();
|
||||
if (mainWindow != nullptr) {
|
||||
mainWindow->viewport->flags &= ~VIEWPORT_FLAG_PAINT_CLIP_TO_HEIGHT;
|
||||
mainWindow->viewport->flags &= ~VIEWPORT_FLAG_CLIP_VIEW;
|
||||
window_invalidate(mainWindow);
|
||||
}
|
||||
|
||||
@@ -180,7 +193,7 @@ static void window_view_clipping_mouseup(rct_window *w, rct_widgetindex widgetIn
|
||||
// Toggle height clipping.
|
||||
mainWindow = window_get_main();
|
||||
if (mainWindow != nullptr) {
|
||||
mainWindow->viewport->flags ^= VIEWPORT_FLAG_PAINT_CLIP_TO_HEIGHT;
|
||||
mainWindow->viewport->flags ^= VIEWPORT_FLAG_CLIP_VIEW;
|
||||
window_invalidate(mainWindow);
|
||||
}
|
||||
window_invalidate(w);
|
||||
@@ -211,9 +224,30 @@ static void window_view_clipping_mouseup(rct_window *w, rct_widgetindex widgetIn
|
||||
}
|
||||
window_invalidate(w);
|
||||
break;
|
||||
case WIDX_CLIP_SELECTOR:
|
||||
// Activate the selection tool
|
||||
tool_set(w, WIDX_BACKGROUND, TOOL_CROSSHAIR);
|
||||
|
||||
// Reset clip selection to show all tiles
|
||||
gClipXMin = 0;
|
||||
gClipXMax = MAXIMUM_MAP_SIZE_TECHNICAL - 1;
|
||||
gClipYMin = 0;
|
||||
gClipYMax = MAXIMUM_MAP_SIZE_TECHNICAL - 1;
|
||||
gfx_invalidate_screen();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Returns true when the tool is active
|
||||
static bool window_view_clipping_tool_is_active()
|
||||
{
|
||||
if (!(input_test_flag(INPUT_FLAG_TOOL_ACTIVE)))
|
||||
return false;
|
||||
if (gCurrentToolWidget.window_classification != WC_VIEW_CLIPPING)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
static void window_view_clipping_update(rct_window *w)
|
||||
{
|
||||
const rct_widget *const widget = &window_view_clipping_widgets[WIDX_CLIP_HEIGHT_SLIDER];
|
||||
@@ -229,16 +263,63 @@ static void window_view_clipping_update(rct_window *w)
|
||||
window_invalidate(mainWindow);
|
||||
}
|
||||
}
|
||||
|
||||
if (window_view_clipping_tool_is_active())
|
||||
{
|
||||
// TODO: Deactivate selection tool and restore previous selection
|
||||
}
|
||||
|
||||
widget_invalidate(w, WIDX_CLIP_HEIGHT_SLIDER);
|
||||
}
|
||||
|
||||
static void window_view_clipping_tool_down(rct_window* w, rct_widgetindex widgetIndex, sint32 x, sint32 y)
|
||||
{
|
||||
sint16 mapX = x;
|
||||
sint16 mapY = y;
|
||||
sint32 direction;
|
||||
screen_pos_to_map_pos(&mapX, &mapY, &direction);
|
||||
if (mapX != LOCATION_NULL)
|
||||
{
|
||||
_selectionStart = { mapX, mapY };
|
||||
}
|
||||
}
|
||||
|
||||
static void window_view_clipping_tool_drag(rct_window* w, rct_widgetindex widgetIndex, sint32 x, sint32 y)
|
||||
{
|
||||
sint16 mapX = x;
|
||||
sint16 mapY = y;
|
||||
sint32 direction;
|
||||
screen_pos_to_map_pos(&mapX, &mapY, &direction);
|
||||
if (mapX != LOCATION_NULL)
|
||||
{
|
||||
map_invalidate_selection_rect();
|
||||
gMapSelectFlags |= MAP_SELECT_FLAG_ENABLE;
|
||||
gMapSelectPositionA.x = std::min(_selectionStart.x, mapX);
|
||||
gMapSelectPositionB.x = std::max(_selectionStart.x, mapX);
|
||||
gMapSelectPositionA.y = std::min(_selectionStart.y, mapY);
|
||||
gMapSelectPositionB.y = std::max(_selectionStart.y, mapY);
|
||||
gMapSelectType = MAP_SELECT_TYPE_FULL;
|
||||
map_invalidate_selection_rect();
|
||||
}
|
||||
}
|
||||
|
||||
static void window_view_clipping_tool_up(struct rct_window*, rct_widgetindex, sint32, sint32)
|
||||
{
|
||||
gClipXMin = gMapSelectPositionA.x / 32;
|
||||
gClipXMax = gMapSelectPositionB.x / 32;
|
||||
gClipYMin = gMapSelectPositionA.y / 32;
|
||||
gClipYMax = gMapSelectPositionB.y / 32;
|
||||
tool_cancel();
|
||||
gfx_invalidate_screen();
|
||||
}
|
||||
|
||||
static void window_view_clipping_invalidate(rct_window *w)
|
||||
{
|
||||
widget_scroll_update_thumbs(w, WIDX_CLIP_HEIGHT_SLIDER);
|
||||
|
||||
rct_window *mainWindow = window_get_main();
|
||||
if (mainWindow != nullptr) {
|
||||
widget_set_checkbox_value(w, WIDX_CLIP_HEIGHT_CHECKBOX, mainWindow->viewport->flags & VIEWPORT_FLAG_PAINT_CLIP_TO_HEIGHT);
|
||||
widget_set_checkbox_value(w, WIDX_CLIP_HEIGHT_CHECKBOX, mainWindow->viewport->flags & VIEWPORT_FLAG_CLIP_VIEW);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -879,7 +879,7 @@ static void viewport_paint_column(rct_drawpixelinfo * dpi, uint32 viewFlags)
|
||||
{
|
||||
gCurrentViewportFlags = viewFlags;
|
||||
|
||||
if (viewFlags & (VIEWPORT_FLAG_HIDE_VERTICAL | VIEWPORT_FLAG_HIDE_BASE | VIEWPORT_FLAG_UNDERGROUND_INSIDE | VIEWPORT_FLAG_PAINT_CLIP_TO_HEIGHT)) {
|
||||
if (viewFlags & (VIEWPORT_FLAG_HIDE_VERTICAL | VIEWPORT_FLAG_HIDE_BASE | VIEWPORT_FLAG_UNDERGROUND_INSIDE | VIEWPORT_FLAG_CLIP_VIEW)) {
|
||||
uint8 colour = 10;
|
||||
if (viewFlags & VIEWPORT_FLAG_INVISIBLE_SPRITES) {
|
||||
colour = 0;
|
||||
|
||||
@@ -48,7 +48,7 @@ enum {
|
||||
VIEWPORT_FLAG_INVISIBLE_SPRITES = (1 << 14),
|
||||
VIEWPORT_FLAG_15 = (1 << 15),
|
||||
VIEWPORT_FLAG_SEETHROUGH_PATHS = (1 << 16),
|
||||
VIEWPORT_FLAG_PAINT_CLIP_TO_HEIGHT = (1 << 17),
|
||||
VIEWPORT_FLAG_CLIP_VIEW = (1 << 17),
|
||||
VIEWPORT_FLAG_HIGHLIGHT_PATH_ISSUES = (1 << 18),
|
||||
};
|
||||
|
||||
|
||||
@@ -24,8 +24,12 @@
|
||||
#include "sprite/Sprite.h"
|
||||
#include "tile_element/TileElement.h"
|
||||
|
||||
// Global for paint clipping height
|
||||
// Globals for paint clipping
|
||||
uint8 gClipHeight = 128; // Default to middle value
|
||||
uint8 gClipXMin = 0;
|
||||
uint8 gClipXMax = MAXIMUM_MAP_SIZE_TECHNICAL - 1;
|
||||
uint8 gClipYMin = 0;
|
||||
uint8 gClipYMax = MAXIMUM_MAP_SIZE_TECHNICAL - 1;
|
||||
|
||||
paint_session gPaintSession;
|
||||
static bool _paintSessionInUse;
|
||||
@@ -1208,4 +1212,4 @@ void paint_draw_money_structs(rct_drawpixelinfo * dpi, paint_string_struct * ps)
|
||||
|
||||
gfx_draw_string_with_y_offsets(&dpi2, buffer, COLOUR_BLACK, ps->x, ps->y, (sint8 *)ps->y_offsets, forceSpriteFont);
|
||||
} while ((ps = ps->next) != nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -170,8 +170,12 @@ struct paint_session
|
||||
|
||||
extern paint_session gPaintSession;
|
||||
|
||||
// Global for paint clipping height.
|
||||
// Globals for paint clipping
|
||||
extern uint8 gClipHeight;
|
||||
extern uint8 gClipXMin;
|
||||
extern uint8 gClipXMax;
|
||||
extern uint8 gClipYMin;
|
||||
extern uint8 gClipYMax;
|
||||
|
||||
/** rct2: 0x00993CC4. The white ghost that indicates not-yet-built elements. */
|
||||
#define CONSTRUCTION_MARKER (COLOUR_DARK_GREEN << 19 | COLOUR_GREY << 24 | IMAGE_TYPE_REMAP);
|
||||
|
||||
@@ -69,11 +69,19 @@ void sprite_paint_setup(paint_session * session, const uint16 eax, const uint16
|
||||
}
|
||||
}
|
||||
|
||||
// Only paint sprites that are below the clip height.
|
||||
// Only paint sprites that are below the clip height and inside the clip selection.
|
||||
// Here converting from land/path/etc height scale to pixel height scale.
|
||||
// Note: peeps/scenery on slopes will be above the base
|
||||
// height of the slope element, and consequently clipped.
|
||||
if ((gCurrentViewportFlags & VIEWPORT_FLAG_PAINT_CLIP_TO_HEIGHT) && (spr->unknown.z > (gClipHeight * 8) )) continue;
|
||||
if ((gCurrentViewportFlags & VIEWPORT_FLAG_CLIP_VIEW))
|
||||
{
|
||||
if (spr->unknown.z > (gClipHeight * 8))
|
||||
continue;
|
||||
if (spr->unknown.x / 32 < gClipXMin || spr->unknown.x / 32 > gClipXMax)
|
||||
continue;
|
||||
if (spr->unknown.y / 32 < gClipYMin || spr->unknown.y / 32 > gClipYMax)
|
||||
continue;
|
||||
}
|
||||
|
||||
dpi = session->Unk140E9A8;
|
||||
|
||||
|
||||
@@ -144,6 +144,14 @@ static void sub_68B3FB(paint_session * session, sint32 x, sint32 y)
|
||||
{
|
||||
rct_drawpixelinfo *dpi = session->Unk140E9A8;
|
||||
|
||||
if ((gCurrentViewportFlags & VIEWPORT_FLAG_CLIP_VIEW))
|
||||
{
|
||||
if (x / 32 < gClipXMin || x / 32 > gClipXMax)
|
||||
return;
|
||||
if (y / 32 < gClipYMin || y / 32 > gClipYMax)
|
||||
return;
|
||||
}
|
||||
|
||||
session->LeftTunnelCount = 0;
|
||||
session->RightTunnelCount = 0;
|
||||
session->LeftTunnels[0] = {0xFF, 0xFF};
|
||||
@@ -247,7 +255,7 @@ static void sub_68B3FB(paint_session * session, sint32 x, sint32 y)
|
||||
sint32 previousHeight = 0;
|
||||
do {
|
||||
// Only paint tile_elements below the clip height.
|
||||
if ((gCurrentViewportFlags & VIEWPORT_FLAG_PAINT_CLIP_TO_HEIGHT) && (tile_element->base_height > gClipHeight))
|
||||
if ((gCurrentViewportFlags & VIEWPORT_FLAG_CLIP_VIEW) && (tile_element->base_height > gClipHeight))
|
||||
continue;
|
||||
|
||||
sint32 direction = tile_element_get_direction_with_offset(tile_element, rotation);
|
||||
@@ -362,7 +370,7 @@ static void sub_68B3FB(paint_session * session, sint32 x, sint32 y)
|
||||
}
|
||||
|
||||
// Only draw supports below the clipping height.
|
||||
if ((gCurrentViewportFlags & VIEWPORT_FLAG_PAINT_CLIP_TO_HEIGHT) && (segmentHeight > gClipHeight)) continue;
|
||||
if ((gCurrentViewportFlags & VIEWPORT_FLAG_CLIP_VIEW) && (segmentHeight > gClipHeight)) continue;
|
||||
|
||||
sint32 xOffset = sy * 10;
|
||||
sint32 yOffset = -22 + sx * 10;
|
||||
|
||||
Reference in New Issue
Block a user