From c7879d08cdf77b9bbcfb534724c7ce322bc82cda Mon Sep 17 00:00:00 2001 From: jensj12 Date: Wed, 31 Aug 2016 17:55:13 +0200 Subject: [PATCH 1/3] Fix #2081: prevent infinite loop in ride_find_track_gap Adds an extra iterator that steps forward at half the speed of the normal iterator. If they ever meet, there's a loop in the track and the track is classified as incomplete. --- src/ride/ride.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/ride/ride.c b/src/ride/ride.c index c6a0bf74a3..d44800d882 100644 --- a/src/ride/ride.c +++ b/src/ride/ride.c @@ -743,7 +743,7 @@ int ride_find_track_gap(rct_xy_element *input, rct_xy_element *output) { rct_window *w; rct_ride *ride; - track_circuit_iterator it; + track_circuit_iterator it, slowIt; int rideIndex; rideIndex = input->element->properties.track.ride_index; @@ -756,12 +756,27 @@ int ride_find_track_gap(rct_xy_element *input, rct_xy_element *output) if (w != NULL && _rideConstructionState != RIDE_CONSTRUCTION_STATE_0 && _currentRideIndex == rideIndex) sub_6C9627(); + bool counter = true; track_circuit_iterator_begin(&it, *input); + slowIt = it; while (track_circuit_iterator_next(&it)) { if (!track_is_connected_by_shape(it.last.element, it.current.element)) { *output = it.current; return 1; } + //#2081: prevent an infinite loop + counter = !counter; + if (counter) { + track_circuit_iterator_next(&slowIt); + if (slowIt.currentZ == it.currentZ && + slowIt.currentDirection == it.currentDirection && + slowIt.current.x == it.current.x && + slowIt.current.y == it.current.y) { + *output = it.current; + return 1; + } + } + } if (!it.looped) { *output = it.last; From b5456f961a02e07cf3cfb20bd10193d451943ddf Mon Sep 17 00:00:00 2001 From: jensj12 Date: Wed, 31 Aug 2016 18:01:50 +0200 Subject: [PATCH 2/3] Update changelog --- distribution/changelog.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/distribution/changelog.txt b/distribution/changelog.txt index 83c99e51a1..6a6af9eb05 100644 --- a/distribution/changelog.txt +++ b/distribution/changelog.txt @@ -6,6 +6,7 @@ - Feature: Implementation of the user-defined currency - Feature: Add ability to rotate map elements with the tile inspector. - Feature: Add ride console command for diagnostics and changing vehicle type. +- Feature: Allow selecting corners when using the mountain tool. - Feature: Allow setting ownership of map edges. - Feature: Allow up to 255 cars per train. - Feature: Importing SV4 and SC4 files with rides. @@ -28,6 +29,7 @@ - Removed: BMP screenshots. - Removed: Intamin and Phoenix easter eggs. - Fix: [#1038] Guest List is out of order. +- Fix: [#2081] Game hangs when track has infinite loop. - Fix: [#2754] Dragging scrollview fails when scaled. - Fix: [#3210] Scenery window scrolls too far. - Fix: [#3282] Launched Freefall ride ratings are fixed for Downward Launch (original bug). From 5500e9e5cdb6cd949478e3a52f8a05cdf3f295f7 Mon Sep 17 00:00:00 2001 From: jensj12 Date: Sat, 3 Sep 2016 16:53:04 +0200 Subject: [PATCH 3/3] Fix backwards loop in vehicle.c --- src/ride/vehicle.c | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/src/ride/vehicle.c b/src/ride/vehicle.c index 8169dcd00d..0ba53770bb 100644 --- a/src/ride/vehicle.c +++ b/src/ride/vehicle.c @@ -5753,7 +5753,11 @@ static void vehicle_update_block_breaks_open_previous_section(rct_vehicle *vehic int x = vehicle->track_x; int y = vehicle->track_y; int z = vehicle->track_z; - track_begin_end trackBeginEnd; + track_begin_end trackBeginEnd, slowTrackBeginEnd; + rct_map_element slowMapElement = *mapElement; + bool counter = true; + int slowX = x; + int slowY = y; do { if (!track_block_get_previous(x, y, mapElement, &trackBeginEnd)) { return; @@ -5768,6 +5772,21 @@ static void vehicle_update_block_breaks_open_previous_section(rct_vehicle *vehic y = trackBeginEnd.end_y; z = trackBeginEnd.begin_z; mapElement = trackBeginEnd.begin_element; + + //#2081: prevent infinite loop + counter = !counter; + if (counter) { + track_block_get_previous(slowX, slowY, &slowMapElement, &slowTrackBeginEnd); + slowX = slowTrackBeginEnd.end_x; + slowY = slowTrackBeginEnd.end_y; + slowMapElement = *(slowTrackBeginEnd.begin_element); + if (slowX == x && + slowY == y && + slowMapElement.base_height == mapElement->base_height && + slowMapElement.type == mapElement->type ) { + return; + } + } } while (!track_element_is_block_start(trackBeginEnd.begin_element)); // Get the start of the track block instead of the end