1
0
mirror of https://github.com/OpenRCT2/OpenRCT2 synced 2026-01-15 11:03:00 +01:00

Merge pull request #6329 from JeroenDStout/railway-crossings-fix-clip

Fix railway/path clipping when on same height
This commit is contained in:
Ted John
2017-11-16 23:00:40 +00:00
committed by GitHub
21 changed files with 264 additions and 19 deletions

View File

@@ -277,5 +277,78 @@
},
{
"path": "track/mini/booster_2.png"
},
{
"path": "track/railway/quarter_turn_3_tiles_sw_se_part_3.png",
"x_offset": -8,
"y_offset": 1
},
{
"path": "track/railway/gravel_sw_ne.png",
"x_offset": -33,
"y_offset": -2
},
{
"path": "track/railway/gravel_nw_se.png",
"x_offset": -21,
"y_offset": -2
},
{
"path": "track/railway/grooved_sw_ne.png",
"x_offset": -28,
"y_offset": -1
},
{
"path": "track/railway/grooved_nw_se.png",
"x_offset": -14,
"y_offset": -2
},
{
"path": "track/railway/grooved_sw_ne_trans.png",
"x_offset": -28,
"y_offset": -1,
"palette": "keep"
},
{
"path": "track/railway/grooved_nw_se_trans.png",
"x_offset": -14,
"y_offset": -2,
"palette": "keep"
},
{
"path": "track/railway/grooved_end_ne_trans.png",
"x_offset": -28,
"y_offset": -1,
"palette": "keep"
},
{
"path": "track/railway/grooved_end_se_trans.png",
"x_offset": -14,
"y_offset": -2,
"palette": "keep"
},
{
"path": "track/railway/grooved_end_nw_trans.png",
"x_offset": -14,
"y_offset": -2,
"palette": "keep"
},
{
"path": "track/railway/grooved_end_sw_trans.png",
"x_offset": -26,
"y_offset": -2,
"palette": "keep"
},
{
"path": "track/railway/grooved_end_sw_ne_trans.png",
"x_offset": -28,
"y_offset": -1,
"palette": "keep"
},
{
"path": "track/railway/grooved_end_nw_se_trans.png",
"x_offset": -14,
"y_offset": -2,
"palette": "keep"
}
]

Binary file not shown.

After

Width:  |  Height:  |  Size: 643 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 681 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 883 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 877 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 877 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 885 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 883 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 885 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 935 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 885 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 958 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 888 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 604 B

View File

@@ -170,7 +170,9 @@ typedef struct paint_session
tunnel_entry RightTunnels[TUNNEL_MAX_COUNT];
uint8 RightTunnelCount;
uint8 VerticalTunnelHeight;
rct_tile_element * SurfaceElement;
rct_tile_element * SurfaceElement;
rct_tile_element * PathElementOnSameHeight;
rct_tile_element * TrackElementOnSameHeight;
bool DidPassSurface;
uint8 Unk141E9DB;
uint16 Unk141E9DC;

View File

@@ -84,6 +84,8 @@ void litter_paint(paint_session * session, rct_litter *litter, sint32 imageDirec
imageDirection &= litter_sprites[litter->type].direction_mask;
uint32 image_id = imageDirection + litter_sprites[litter->type].base_id;
sub_98197C(session, image_id, 0, 0, 4, 4, -1, litter->z, -4, -4, litter->z + 2, get_current_rotation());
// In the following call to sub_98197C, we add 4 (instead of 2) to the
// bound_box_offset_z to make sure litter is drawn on top of railways
sub_98197C(session, image_id, 0, 0, 4, 4, -1, litter->z, -4, -4, litter->z + 4, get_current_rotation());
}

View File

@@ -77,26 +77,28 @@ void peep_paint(paint_session * session, rct_peep * peep, sint32 imageDirection)
spriteType = peep->next_action_sprite_type;
imageOffset = 0;
}
// In the following 4 calls to sub_98197C/sub_98199C, we add 5 (instead of 3) to the
// bound_box_offset_z to make sure peeps are drawn on top of railways
uint32 baseImageId = (imageDirection >> 3) + sprite.sprite_animation[spriteType].base_image + imageOffset * 4;
uint32 imageId = baseImageId | peep->tshirt_colour << 19 | peep->trousers_colour << 24 | IMAGE_TYPE_REMAP | IMAGE_TYPE_REMAP_2_PLUS;
sub_98197C(session, imageId, 0, 0, 1, 1, 11, peep->z, 0, 0, peep->z + 3, get_current_rotation());
sub_98197C(session, imageId, 0, 0, 1, 1, 11, peep->z, 0, 0, peep->z + 5, get_current_rotation());
if (baseImageId >= 10717 && baseImageId < 10749) {
imageId = (baseImageId + 32) | peep->hat_colour << 19 | IMAGE_TYPE_REMAP;
sub_98199C(session, imageId, 0, 0, 1, 1, 11, peep->z, 0, 0, peep->z + 3, get_current_rotation());
sub_98199C(session, imageId, 0, 0, 1, 1, 11, peep->z, 0, 0, peep->z + 5, get_current_rotation());
return;
}
if (baseImageId >= 10781 && baseImageId < 10813) {
imageId = (baseImageId + 32) | peep->balloon_colour << 19 | IMAGE_TYPE_REMAP;
sub_98199C(session, imageId, 0, 0, 1, 1, 11, peep->z, 0, 0, peep->z + 3, get_current_rotation());
sub_98199C(session, imageId, 0, 0, 1, 1, 11, peep->z, 0, 0, peep->z + 5, get_current_rotation());
return;
}
if (baseImageId >= 11197 && baseImageId < 11229) {
imageId = (baseImageId + 32) | peep->umbrella_colour << 19 | IMAGE_TYPE_REMAP;
sub_98199C(session, imageId, 0, 0, 1, 1, 11, peep->z, 0, 0, peep->z + 3, get_current_rotation());
sub_98199C(session, imageId, 0, 0, 1, 1, 11, peep->z, 0, 0, peep->z + 5, get_current_rotation());
return;
}
}

View File

@@ -827,8 +827,21 @@ void path_paint_pole_support(paint_session * session, rct_tile_element * tileEle
boundBoxSize.y = 26;
}
// By default, add 1 to the z bounding box to always clip above the surface
uint8 boundingBoxZOffset = 1;
// If we are on the same tile as a straight track, add the offset 2 so we
// can clip above gravel part of the track sprite
if (session->TrackElementOnSameHeight)
{
if (session->TrackElementOnSameHeight->properties.track.type == TRACK_ELEM_FLAT)
{
boundingBoxZOffset = 2;
}
}
if (!hasFences || !session->DidPassSurface) {
sub_98197C(session, imageId | imageFlags, 0, 0, boundBoxSize.x, boundBoxSize.y, 0, height, boundBoxOffset.x, boundBoxOffset.y, height + 1, get_current_rotation());
sub_98197C(session, imageId | imageFlags, 0, 0, boundBoxSize.x, boundBoxSize.y, 0, height, boundBoxOffset.x, boundBoxOffset.y, height + boundingBoxZOffset, get_current_rotation());
} else {
uint32 image_id;
if (footpath_element_is_sloped(tileElement)) {
@@ -837,12 +850,12 @@ void path_paint_pole_support(paint_session * session, rct_tile_element * tileEle
image_id = byte_98D8A4[edges] + footpathEntry->bridge_image + 49;
}
sub_98197C(session, image_id | imageFlags, 0, 0, boundBoxSize.x, boundBoxSize.y, 0, height, boundBoxOffset.x, boundBoxOffset.y, height + 1, get_current_rotation());
sub_98197C(session, image_id | imageFlags, 0, 0, boundBoxSize.x, boundBoxSize.y, 0, height, boundBoxOffset.x, boundBoxOffset.y, height + boundingBoxZOffset, get_current_rotation());
if (!footpath_element_is_queue(tileElement) && !(footpathEntry->flags & FOOTPATH_ENTRY_FLAG_HAS_PATH_BASE_SPRITE)) {
// don't draw
} else {
sub_98199C(session, imageId | imageFlags, 0, 0, boundBoxSize.x, boundBoxSize.y, 0, height, boundBoxOffset.x, boundBoxOffset.y, height + 1, get_current_rotation());
sub_98199C(session, imageId | imageFlags, 0, 0, boundBoxSize.x, boundBoxSize.y, 0, height, boundBoxOffset.x, boundBoxOffset.y, height + boundingBoxZOffset, get_current_rotation());
}
}
@@ -941,8 +954,21 @@ void path_paint_box_support(paint_session * session, rct_tile_element* tileEleme
boundBoxSize.y = 26;
}
// By default, add 1 to the z bounding box to always clip above the surface
uint8 boundingBoxZOffset = 1;
// If we are on the same tile as a straight track, add the offset 2 so we
// can clip above gravel part of the track sprite
if (session->TrackElementOnSameHeight)
{
if (session->TrackElementOnSameHeight->properties.track.type == TRACK_ELEM_FLAT)
{
boundingBoxZOffset = 2;
}
}
if (!hasFences || !session->DidPassSurface) {
sub_98197C(session, imageId | imageFlags, 0, 0, boundBoxSize.x, boundBoxSize.y, 0, height, boundBoxOffset.x, boundBoxOffset.y, height + 1, get_current_rotation());
sub_98197C(session, imageId | imageFlags, 0, 0, boundBoxSize.x, boundBoxSize.y, 0, height, boundBoxOffset.x, boundBoxOffset.y, height + boundingBoxZOffset, get_current_rotation());
}
else {
uint32 bridgeImage;
@@ -954,10 +980,10 @@ void path_paint_box_support(paint_session * session, rct_tile_element* tileEleme
bridgeImage |= imageFlags;
}
sub_98197C(session, bridgeImage | imageFlags, 0, 0, boundBoxSize.x, boundBoxSize.y, 0, height, boundBoxOffset.x, boundBoxOffset.y, height + 1, get_current_rotation());
sub_98197C(session, bridgeImage | imageFlags, 0, 0, boundBoxSize.x, boundBoxSize.y, 0, height, boundBoxOffset.x, boundBoxOffset.y, height + boundingBoxZOffset, get_current_rotation());
if (footpath_element_is_queue(tileElement) || (footpathEntry->flags & FOOTPATH_ENTRY_FLAG_HAS_PATH_BASE_SPRITE)) {
sub_98199C(session, imageId | imageFlags, 0, 0, boundBoxSize.x, boundBoxSize.y, 0, height, boundBoxOffset.x, boundBoxOffset.y, height + 1, get_current_rotation());
sub_98199C(session, imageId | imageFlags, 0, 0, boundBoxSize.x, boundBoxSize.y, 0, height, boundBoxOffset.x, boundBoxOffset.y, height + boundingBoxZOffset, get_current_rotation());
}
}

View File

@@ -234,6 +234,7 @@ static void sub_68B3FB(paint_session * session, sint32 x, sint32 y)
session->SpritePosition.x = x;
session->SpritePosition.y = y;
session->DidPassSurface = false;
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)) break;
@@ -241,6 +242,41 @@ static void sub_68B3FB(paint_session * session, sint32 x, sint32 y)
sint32 direction = tile_element_get_direction_with_offset(tile_element, rotation);
sint32 height = tile_element->base_height * 8;
// If we are on a new height level, look through elements on the
// same height and store any types might be relevant to others
if (height != previousHeight)
{
previousHeight = height;
session->PathElementOnSameHeight = 0;
session->TrackElementOnSameHeight = 0;
rct_tile_element * tile_element_sub_iterator = tile_element;
while (!tile_element_is_last_for_tile(tile_element_sub_iterator++))
{
if (tile_element_sub_iterator->base_height != tile_element->base_height)
{
break;
}
switch (tile_element_get_type(tile_element_sub_iterator))
{
case TILE_ELEMENT_TYPE_PATH:
session->PathElementOnSameHeight = tile_element_sub_iterator;
break;
case TILE_ELEMENT_TYPE_TRACK:
session->TrackElementOnSameHeight = tile_element_sub_iterator;
break;
case TILE_ELEMENT_TYPE_CORRUPT:
// To preserve regular behaviour, make an element hidden by
// corruption also invisible to this method.
if (tile_element_is_last_for_tile(tile_element))
{
break;
}
tile_element_sub_iterator++;
break;
}
}
}
LocationXY16 dword_9DE574 = session->MapPosition;
session->CurrentlyDrawnItem = tile_element;
// Setup the painting of for example: the underground, signs, rides, scenery, etc.

View File

@@ -18,6 +18,7 @@
#include "../../interface/viewport.h"
#include "../../paint/paint.h"
#include "../../paint/supports.h"
#include "../../sprites.h"
#include "../../world/map.h"
#include "../ride_data.h"
#include "../Track.h"
@@ -547,27 +548,106 @@ static const uint32 miniature_railway_track_pieces_diag_25_deg_up[4] = {
SPR_MINIATURE_RAILWAY_DIAG_25_DEG_UP_S_N,
};
static uint32 miniature_railway_track_to_gravel(uint32 imageId)
{
return imageId - SPR_MINIATURE_RAILWAY_FLAT_SW_NE + SPR_G2_MINIATURE_RAILWAY_GRAVEL_SW_NE;
}
static uint32 miniature_railway_track_to_grooved(uint32 imageId)
{
return imageId - SPR_MINIATURE_RAILWAY_FLAT_SW_NE + SPR_G2_MINIATURE_RAILWAY_GROOVED_SW_NE;
}
static uint32 miniature_railway_track_to_grooved_indent(uint32 imageId, rct_tile_element *path, uint8 direction)
{
if (!path)
{
return 0;
}
uint32 imageIdAlt = SPR_G2_MINIATURE_RAILWAY_GROOVED_SW_NE;
uint8 correctedEdges = path->properties.path.edges;
correctedEdges |= correctedEdges << 4;
correctedEdges >>= 4 - get_current_rotation();
correctedEdges &= 0x0F;
if (direction & 0x1)
{
uint32 imageIds[2][2] = { { SPR_G2_MINIATURE_RAILWAY_INSET_NW_SE, SPR_G2_MINIATURE_RAILWAY_INSET_END_NW },
{ SPR_G2_MINIATURE_RAILWAY_INSET_END_SE, SPR_G2_MINIATURE_RAILWAY_INSET_END_NW_SE } };
imageIdAlt = imageIds[(correctedEdges & 0x2)? 0 : 1][(correctedEdges & 0x8)? 0 : 1];
}
else
{
uint32 imageIds[2][2] = { { SPR_G2_MINIATURE_RAILWAY_INSET_SW_NE, SPR_G2_MINIATURE_RAILWAY_INSET_END_SW },
{ SPR_G2_MINIATURE_RAILWAY_INSET_END_NE, SPR_G2_MINIATURE_RAILWAY_INSET_END_SW_NE } };
imageIdAlt = imageIds[(correctedEdges & 0x1)? 0 : 1][(correctedEdges & 0x4)? 0 : 1];
}
return imageIdAlt;
}
/** rct2: 0x008AD0C0 */
static void paint_miniature_railway_track_flat(paint_session * session, uint8 rideIndex, uint8 trackSequence, uint8 direction,
sint32 height, rct_tile_element * tileElement)
{
bool paintAsGravel = false;
bool paintGrooved = false;
bool isSupported =
wooden_a_supports_paint_setup(session, direction & 1, 0, height, session->TrackColours[SCHEME_SUPPORTS], NULL);
uint32 imageId;
if (session->PathElementOnSameHeight)
{
paintAsGravel = true;
paintGrooved = true;
}
bool isSupported = wooden_a_supports_paint_setup(session, direction & 1, 0, height, session->TrackColours[SCHEME_SUPPORTS], NULL);
uint32 imageId, imageIdAlt;
// In the following 3 calls to sub_98197C_rotated/sub_98199C_rotated, we add 1 to the
// bound_box_offset_z argument to make straight tracks draw above footpaths
if (isSupported)
{
imageId = miniature_railway_track_floor[direction] | session->TrackColours[SCHEME_SUPPORTS];
sub_98197C_rotated(session, direction, imageId, 0, 0, 32, 20, 2, height, 0, 6, height);
imageId = miniature_railway_track_pieces_flat[direction] | session->TrackColours[SCHEME_TRACK];
sub_98199C_rotated(session, direction, imageId, 0, 6, 32, 20, 2, height, 0, 6, height);
if (!paintAsGravel)
{
sub_98199C_rotated(session, direction, imageId, 0, 6, 32, 20, 2, height, 0, 6, height);
}
else
{
imageIdAlt = miniature_railway_track_to_gravel(imageId);
sub_98199C_rotated(session, direction, imageIdAlt, 0, 6, 32, 20, 2, height, 0, 6, height);
}
if (paintGrooved)
{
imageIdAlt = miniature_railway_track_to_grooved(imageId);
sub_98199C_rotated(session, direction, imageIdAlt, 0, 6, 32, 20, 2, height, 0, 6, height + 2);
imageIdAlt = miniature_railway_track_to_grooved_indent(imageId, session->PathElementOnSameHeight, direction);
sub_98199C_rotated(session, direction, (imageIdAlt & 0x7FFFF) | IMAGE_TYPE_REMAP | IMAGE_TYPE_TRANSPARENT | (PALETTE_DARKEN_2 << 19), 0, 6, 32, 20, 2, height, 0, 6, height + 2);
}
}
else
{
imageId = miniature_railway_track_pieces_flat[direction] | session->TrackColours[SCHEME_TRACK];
sub_98197C_rotated(session, direction, imageId, 0, 6, 32, 20, 2, height, 0, 6, height);
if (!paintAsGravel)
{
sub_98197C_rotated(session, direction, imageId, 0, 6, 32, 20, 2, height, 0, 6, height);
}
else
{
imageIdAlt = miniature_railway_track_to_gravel(imageId);
sub_98197C_rotated(session, direction, imageIdAlt, 0, 6, 32, 20, 2, height, 0, 6, height);
}
if (paintGrooved)
{
imageIdAlt = miniature_railway_track_to_grooved(imageId);
sub_98197C_rotated(session, direction, imageIdAlt, 0, 6, 32, 20, 2, height, 0, 6, height + 2);
imageIdAlt = miniature_railway_track_to_grooved_indent(imageId, session->PathElementOnSameHeight, direction);
sub_98197C_rotated(session, direction, (imageIdAlt & 0x7FFFF) | IMAGE_TYPE_REMAP | IMAGE_TYPE_TRANSPARENT | (PALETTE_DARKEN_2 << 19), 0, 6, 32, 20, 2, height, 0, 6, height + 2);
}
}
paint_util_push_tunnel_rotated(session, direction, height, TUNNEL_6);
@@ -1163,6 +1243,13 @@ static void paint_miniature_railway_track_right_quarter_turn_3_tiles(paint_sessi
session, 3, height, direction, trackSequence, session->TrackColours[SCHEME_TRACK],
miniature_railway_track_pieces_flat_quarter_turn_3_tiles, defaultRightQuarterTurn3TilesOffsets,
defaultRightQuarterTurn3TilesBoundLengths, NULL, get_current_rotation());
// The following piece was missing in vanilla RCT2
if (trackSequence == 1 && direction == 0)
{
uint32 imageId = SPR_G2_MINIATURE_RAILWAY_QUARTER_TURN_3_TILES_SW_SE_PART_3 | session->TrackColours[SCHEME_TRACK];
sub_98197C(session, imageId, 0, 0, 8, 8, 2, height, 0, 0, height, get_current_rotation());
}
}
else
{

View File

@@ -802,6 +802,23 @@ enum {
SPR_G2_MINI_RC_BOOSTER_NE_SW = SPR_G2_BEGIN + 91,
SPR_G2_MINI_RC_BOOSTER_NW_SE = SPR_G2_BEGIN + 92,
SPR_G2_MINIATURE_RAILWAY_QUARTER_TURN_3_TILES_SW_SE_PART_3 = SPR_G2_BEGIN + 93,
SPR_G2_MINIATURE_RAILWAY_BEGIN = SPR_G2_BEGIN + 94,
SPR_G2_MINIATURE_RAILWAY_GRAVEL_SW_NE = SPR_G2_MINIATURE_RAILWAY_BEGIN + 0,
SPR_G2_MINIATURE_RAILWAY_GRAVEL_NW_SE = SPR_G2_MINIATURE_RAILWAY_BEGIN + 1,
SPR_G2_MINIATURE_RAILWAY_GROOVED_SW_NE = SPR_G2_MINIATURE_RAILWAY_BEGIN + 2,
SPR_G2_MINIATURE_RAILWAY_GROOVED_NW_SE = SPR_G2_MINIATURE_RAILWAY_BEGIN + 3,
SPR_G2_MINIATURE_RAILWAY_INSET_SW_NE = SPR_G2_MINIATURE_RAILWAY_BEGIN + 4,
SPR_G2_MINIATURE_RAILWAY_INSET_NW_SE = SPR_G2_MINIATURE_RAILWAY_BEGIN + 5,
SPR_G2_MINIATURE_RAILWAY_INSET_END_NE = SPR_G2_MINIATURE_RAILWAY_BEGIN + 6,
SPR_G2_MINIATURE_RAILWAY_INSET_END_SE = SPR_G2_MINIATURE_RAILWAY_BEGIN + 7,
SPR_G2_MINIATURE_RAILWAY_INSET_END_NW = SPR_G2_MINIATURE_RAILWAY_BEGIN + 8,
SPR_G2_MINIATURE_RAILWAY_INSET_END_SW = SPR_G2_MINIATURE_RAILWAY_BEGIN + 9,
SPR_G2_MINIATURE_RAILWAY_INSET_END_SW_NE = SPR_G2_MINIATURE_RAILWAY_BEGIN + 10,
SPR_G2_MINIATURE_RAILWAY_INSET_END_NW_SE = SPR_G2_MINIATURE_RAILWAY_BEGIN + 11,
SPR_G2_MINIATURE_RAILWAY_LAST = SPR_G2_BEGIN + 105,
// 0x60000, chosen because it's a round hex number
// of the last possible range of image ID values that is large enough to fit all csg1 sprites.