From 1e5b83c631ba3705238417f291d2b2e2f763b96d Mon Sep 17 00:00:00 2001 From: zaxcav Date: Fri, 21 Oct 2016 09:46:59 +0200 Subject: [PATCH] Initial prototype of paint clipping. Paint clipping is a possible future feature to assist players building in cluttered areas of a park by controlling which map elements and sprites are rendered, providing a clearer view for construction, inspection, etc. Only clip height is supported in this prototype. Map elements are clipped according to the map element base height (meaning *all* scenery on that map element is currently clipped with it). Sprites are clipped according to their z value being within the "sprite volume" of any non-clipped map element (which means below clip height + 2). Control is only provided through the console in this prototype - use the command: set paint_clip_height _value_ To turn clipping off use the command: set paint_clip_height 255 Clip heights are limited to multiples of two to coincide with the native heights of map elements. Command "get paint_clip_height" prints the clip height as a raw value as well as the equivalent height in ft and m as used when displaying heights in-game. At this time only painting of the main viewport is affected. There is no change to any input control handling. --- src/openrct2/interface/viewport.c | 2 +- src/openrct2/interface/viewport.h | 3 ++- src/openrct2/paint/map_element/map_element.c | 13 +++++++++++++ src/openrct2/paint/paint.c | 5 ++++- src/openrct2/paint/paint.h | 3 +++ src/openrct2/paint/sprite/sprite.c | 6 ++++++ 6 files changed, 29 insertions(+), 3 deletions(-) diff --git a/src/openrct2/interface/viewport.c b/src/openrct2/interface/viewport.c index 60cd632756..5f5e226709 100644 --- a/src/openrct2/interface/viewport.c +++ b/src/openrct2/interface/viewport.c @@ -730,7 +730,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)) { + if (viewFlags & (VIEWPORT_FLAG_HIDE_VERTICAL | VIEWPORT_FLAG_HIDE_BASE | VIEWPORT_FLAG_UNDERGROUND_INSIDE | VIEWPORT_FLAG_PAINT_CLIP_TO_HEIGHT)) { uint8 colour = 10; if (viewFlags & VIEWPORT_FLAG_INVISIBLE_SPRITES) { colour = 0; diff --git a/src/openrct2/interface/viewport.h b/src/openrct2/interface/viewport.h index a4dd45702f..0ddbd55640 100644 --- a/src/openrct2/interface/viewport.h +++ b/src/openrct2/interface/viewport.h @@ -39,7 +39,8 @@ enum { VIEWPORT_FLAG_HIDE_VERTICAL = (1 << 13), VIEWPORT_FLAG_INVISIBLE_SPRITES = (1 << 14), VIEWPORT_FLAG_15 = (1 << 15), - VIEWPORT_FLAG_SEETHROUGH_PATHS = (1 << 16) + VIEWPORT_FLAG_SEETHROUGH_PATHS = (1 << 16), + VIEWPORT_FLAG_PAINT_CLIP_TO_HEIGHT = (1 << 17) // zax }; enum { diff --git a/src/openrct2/paint/map_element/map_element.c b/src/openrct2/paint/map_element/map_element.c index 4c8d0b4685..30505e9662 100644 --- a/src/openrct2/paint/map_element/map_element.c +++ b/src/openrct2/paint/map_element/map_element.c @@ -167,6 +167,13 @@ static void sub_68B3FB(sint32 x, sint32 y) rct_map_element* map_element = map_get_first_element_at(x >> 5, y >> 5); uint8 rotation = get_current_rotation(); + /* Check if the first (lowest) map_element is below the clip + * height. */ + if ((gCurrentViewportFlags & VIEWPORT_FLAG_PAINT_CLIP_TO_HEIGHT) && (map_element->base_height > gClipHeight)) { + blank_tiles_paint(x, y); + return; + } + sint32 dx = 0; switch (rotation) { case 0: @@ -240,6 +247,9 @@ static void sub_68B3FB(sint32 x, sint32 y) gUnk9DE56C = y; gDidPassSurface = false; do { + // Only paint map_elements below the clip height. + if ((gCurrentViewportFlags & VIEWPORT_FLAG_PAINT_CLIP_TO_HEIGHT) && (map_element->base_height > gClipHeight)) break; + sint32 direction = (map_element->type + rotation) & MAP_ELEMENT_DIRECTION_MASK; sint32 height = map_element->base_height * 8; @@ -309,6 +319,9 @@ static void sub_68B3FB(sint32 x, sint32 y) imageColourFlats = 0b111011 << 19 | 0x40000000; } + // Only draw supports above the clipping height. + if ((gCurrentViewportFlags & VIEWPORT_FLAG_PAINT_CLIP_TO_HEIGHT) && (segmentHeight > gClipHeight)) continue; + sint32 xOffset = sy * 10; sint32 yOffset = -22 + sx * 10; paint_struct * ps = sub_98197C(5504 | imageColourFlats, xOffset, yOffset, 10, 10, 1, segmentHeight, xOffset + 1, yOffset + 16, segmentHeight, get_current_rotation()); diff --git a/src/openrct2/paint/paint.c b/src/openrct2/paint/paint.c index b058051cdd..b92ea5d8b6 100644 --- a/src/openrct2/paint/paint.c +++ b/src/openrct2/paint/paint.c @@ -23,6 +23,9 @@ #include "sprite/sprite.h" #include "supports.h" +// zax: globals for paint clipping height +uint8 gClipHeight = 255; + const uint32 construction_markers[] = { COLOUR_DARK_GREEN << 19 | COLOUR_GREY << 24 | IMAGE_TYPE_REMAP, // White PALETTE_DARKEN_2 << 19 | IMAGE_TYPE_TRANSPARENT, // Translucent @@ -199,6 +202,7 @@ static paint_struct * sub_9819_c(uint32 image_id, rct_xyz16 offset, rct_xyz16 bo ps->map_x = gPaintMapPosition.x; ps->map_y = gPaintMapPosition.y; ps->mapElement = g_currently_drawn_item; + return ps; } @@ -366,7 +370,6 @@ paint_struct * sub_98197C( sint16 bound_box_offset_x, sint16 bound_box_offset_y, sint16 bound_box_offset_z, uint32 rotation ) { - g_ps_F1AD28 = 0; g_aps_F1AD2C = NULL; diff --git a/src/openrct2/paint/paint.h b/src/openrct2/paint/paint.h index 0ff5d71246..2ac5ee1308 100644 --- a/src/openrct2/paint/paint.h +++ b/src/openrct2/paint/paint.h @@ -23,6 +23,9 @@ #include "../interface/colour.h" #include "../drawing/drawing.h" +// zax: Global paint clipping height. +extern uint8 gClipHeight; + typedef struct attached_paint_struct attached_paint_struct; typedef struct paint_struct paint_struct; typedef union paint_entry paint_entry; diff --git a/src/openrct2/paint/sprite/sprite.c b/src/openrct2/paint/sprite/sprite.c index 4269b18eb5..07e25b06cb 100644 --- a/src/openrct2/paint/sprite/sprite.c +++ b/src/openrct2/paint/sprite/sprite.c @@ -21,6 +21,7 @@ #include "../../ride/ride_data.h" #include "../../interface/viewport.h" #include "../../ride/vehicle_paint.h" +#include "../../localisation/localisation.h" // zax /** * Paint Quadrant @@ -45,6 +46,11 @@ void sprite_paint_setup(const uint16 eax, const uint16 ecx) { for (rct_sprite* spr = get_sprite(sprite_idx); sprite_idx != SPRITE_INDEX_NULL; sprite_idx = spr->unknown.next_in_quadrant) { spr = get_sprite(sprite_idx); + + // zax: Only paint sprites that are below the clip height. + // Here converting from land/path/etc height scale to pixel height scale. + if ((gCurrentViewportFlags & VIEWPORT_FLAG_PAINT_CLIP_TO_HEIGHT) && (spr->unknown.z >= ((gClipHeight+2) * 8))) continue; + dpi = unk_140E9A8; if (dpi->y + dpi->height <= spr->unknown.sprite_top) continue;