From fe6d50f942246a6a0545b43f893178cd6f525b45 Mon Sep 17 00:00:00 2001 From: Alexander Overvoorde Date: Mon, 15 Feb 2016 02:03:03 +0100 Subject: [PATCH 1/3] Fix overall view position using z coordinate of arbitrary element in same column (fixes #2636) --- src/windows/ride.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/windows/ride.c b/src/windows/ride.c index 4e66432297..d4f9c1ec8f 100644 --- a/src/windows/ride.c +++ b/src/windows/ride.c @@ -1531,7 +1531,7 @@ static void window_ride_init_viewport(rct_window *w) focus.coordinate.y = (ride->overall_view & 0xFF00) >> 3; focus.coordinate.x += 16; focus.coordinate.y += 16; - focus.coordinate.z = map_element_height(focus.coordinate.x, focus.coordinate.y) & 0xFFFF; + focus.coordinate.z = ride->station_heights[0] * 8; focus.sprite.type |= 0x40; focus.coordinate.zoom = 1; if (ride_type_has_flag(ride->type, RIDE_TYPE_FLAG_HAS_NO_TRACK)) From 4a42b09bb30402d9156bcb9e8b998afbac7a8c08 Mon Sep 17 00:00:00 2001 From: Alexander Overvoorde Date: Tue, 16 Feb 2016 23:28:35 +0100 Subject: [PATCH 2/3] Add new overall view logic --- src/windows/ride.c | 53 +++++++++++++++++++++++++++++++++++++++------- 1 file changed, 45 insertions(+), 8 deletions(-) diff --git a/src/windows/ride.c b/src/windows/ride.c index d4f9c1ec8f..a694741890 100644 --- a/src/windows/ride.c +++ b/src/windows/ride.c @@ -1476,6 +1476,48 @@ static void window_ride_anchor_border_widgets(rct_window *w) #pragma region Main +static void window_ride_calculate_overall_view(uint8 ride_index, sint16 *cx, sint16 *cy, sint16 *cz, uint8 *zoom) { + map_element_iterator it; + + map_element_iterator_begin(&it); + + int minx = INT_MAX, miny = INT_MAX, minz = INT_MAX; + int maxx = INT_MIN, maxy = INT_MIN, maxz = INT_MIN; + + while (map_element_iterator_next(&it)) { + if (map_element_get_type(it.element) != MAP_ELEMENT_TYPE_TRACK) + continue; + + if (it.element->properties.track.ride_index != ride_index) + continue; + + int x = it.x * 32; + int y = it.y * 32; + int z1 = it.element->base_height * 8; + int z2 = it.element->clearance_height * 8; + + minx = min(minx, x); + miny = min(miny, y); + minz = min(minz, z1); + + maxx = max(maxx, x); + maxy = max(maxy, y); + maxz = max(maxz, z2); + } + + *cx = (minx + maxx) / 2; + *cy = (miny + maxy) / 2; + *cz = (minz + maxz) / 2 + 8; + + int dx = maxx - minx; + int dy = maxy - miny; + int dz = maxz - minz; + + int size = (int) sqrt(dx*dx + dy*dy + dz*dz); + + *zoom = max(0, ceil(log(size / 64)) - 1); +} + /** * * rct2: 0x006AF994 @@ -1527,15 +1569,10 @@ static void window_ride_init_viewport(rct_window *w) if (eax > 0){ w->viewport_focus_coordinates.var_480 = 0; } - focus.coordinate.x = (ride->overall_view & 0xFF) << 5; - focus.coordinate.y = (ride->overall_view & 0xFF00) >> 3; - focus.coordinate.x += 16; - focus.coordinate.y += 16; - focus.coordinate.z = ride->station_heights[0] * 8; + + window_ride_calculate_overall_view((uint8) w->number, &focus.coordinate.x, &focus.coordinate.y, &focus.coordinate.z, &focus.coordinate.zoom); + focus.sprite.type |= 0x40; - focus.coordinate.zoom = 1; - if (ride_type_has_flag(ride->type, RIDE_TYPE_FLAG_HAS_NO_TRACK)) - focus.coordinate.zoom = 0; } focus.coordinate.var_480 = w->viewport_focus_coordinates.var_480; From 6311b5588dae18652085cc6058ded79944a0b6aa Mon Sep 17 00:00:00 2001 From: Alexander Overvoorde Date: Thu, 18 Feb 2016 21:38:05 +0100 Subject: [PATCH 3/3] Fix ride overall views being recalculated constantly --- src/windows/ride.c | 107 +++++++++++++++++++++++++++------------------ 1 file changed, 64 insertions(+), 43 deletions(-) diff --git a/src/windows/ride.c b/src/windows/ride.c index a694741890..dac089b0e0 100644 --- a/src/windows/ride.c +++ b/src/windows/ride.c @@ -951,6 +951,15 @@ static rct_window_event_list *window_ride_page_events[] = { #pragma endregion +// Cached overall view for each ride +// (Re)calculated when the ride window is opened +typedef struct ride_overall_view_t { + sint16 x, y, z; + uint8 zoom; +} ride_overall_view; + +ride_overall_view ride_overall_views[MAX_RIDES] = {0}; + const int window_ride_tab_animation_divisor[] = { 0, 0, 2, 2, 4, 2, 8, 8, 2, 0 }; const int window_ride_tab_animation_frames[] = { 0, 0, 4, 16, 8, 16, 8, 8, 8, 0 }; @@ -1168,6 +1177,53 @@ void window_ride_disable_tabs(rct_window *w) w->disabled_widgets = disabled_tabs; } +static void window_ride_update_overall_view(uint8 ride_index) { + // Calculate x, y, z bounds of the entire ride using its track elements + map_element_iterator it; + + map_element_iterator_begin(&it); + + int minx = INT_MAX, miny = INT_MAX, minz = INT_MAX; + int maxx = INT_MIN, maxy = INT_MIN, maxz = INT_MIN; + + while (map_element_iterator_next(&it)) { + if (map_element_get_type(it.element) != MAP_ELEMENT_TYPE_TRACK) + continue; + + if (it.element->properties.track.ride_index != ride_index) + continue; + + int x = it.x * 32; + int y = it.y * 32; + int z1 = it.element->base_height * 8; + int z2 = it.element->clearance_height * 8; + + minx = min(minx, x); + miny = min(miny, y); + minz = min(minz, z1); + + maxx = max(maxx, x); + maxy = max(maxy, y); + maxz = max(maxz, z2); + } + + ride_overall_view *view = &ride_overall_views[ride_index]; + view->x = (minx + maxx) / 2; + view->y = (miny + maxy) / 2; + view->z = (minz + maxz) / 2 + 8; + + // Calculate size to determine from how far away to view the ride + int dx = maxx - minx; + int dy = maxy - miny; + int dz = maxz - minz; + + int size = (int) sqrt(dx*dx + dy*dy + dz*dz); + + // Each farther zoom level shows twice as many tiles (log) + // Appropriate zoom is lowered by one to fill the entire view with the ride + view->zoom = (uint8) max(0, ceil(log(size / 80)) - 1); +} + /** * * rct2: 0x006AEAB4 @@ -1196,6 +1252,8 @@ rct_window *window_ride_open(int rideIndex) w->max_width = 500; w->max_height = 450; + window_ride_update_overall_view((uint8) rideIndex); + ride = get_ride(rideIndex); numSubTypes = 0; rideEntryIndexPtr = get_ride_entry_indices_for_ride_type(ride->type); @@ -1476,48 +1534,6 @@ static void window_ride_anchor_border_widgets(rct_window *w) #pragma region Main -static void window_ride_calculate_overall_view(uint8 ride_index, sint16 *cx, sint16 *cy, sint16 *cz, uint8 *zoom) { - map_element_iterator it; - - map_element_iterator_begin(&it); - - int minx = INT_MAX, miny = INT_MAX, minz = INT_MAX; - int maxx = INT_MIN, maxy = INT_MIN, maxz = INT_MIN; - - while (map_element_iterator_next(&it)) { - if (map_element_get_type(it.element) != MAP_ELEMENT_TYPE_TRACK) - continue; - - if (it.element->properties.track.ride_index != ride_index) - continue; - - int x = it.x * 32; - int y = it.y * 32; - int z1 = it.element->base_height * 8; - int z2 = it.element->clearance_height * 8; - - minx = min(minx, x); - miny = min(miny, y); - minz = min(minz, z1); - - maxx = max(maxx, x); - maxy = max(maxy, y); - maxz = max(maxz, z2); - } - - *cx = (minx + maxx) / 2; - *cy = (miny + maxy) / 2; - *cz = (minz + maxz) / 2 + 8; - - int dx = maxx - minx; - int dy = maxy - miny; - int dz = maxz - minz; - - int size = (int) sqrt(dx*dx + dy*dy + dz*dz); - - *zoom = max(0, ceil(log(size / 64)) - 1); -} - /** * * rct2: 0x006AF994 @@ -1570,7 +1586,12 @@ static void window_ride_init_viewport(rct_window *w) w->viewport_focus_coordinates.var_480 = 0; } - window_ride_calculate_overall_view((uint8) w->number, &focus.coordinate.x, &focus.coordinate.y, &focus.coordinate.z, &focus.coordinate.zoom); + ride_overall_view *view = &ride_overall_views[w->number]; + + focus.coordinate.x = view->x; + focus.coordinate.y = view->y; + focus.coordinate.z = view->z; + focus.coordinate.zoom = view->zoom; focus.sprite.type |= 0x40; }