mirror of https://github.com/OpenRCT2/OpenRCT2.git
Fix #15439: Ride viewport is partially grey
The ride viewport does not work the same as other viewports due to the selection of views that it has. After refactoring the focus system to use a more streamlined approach the ride viewport lost its invalidation on resizing. If the ride window was to use the same viewport update code as say the guest window then the viewport focus still ends up incorrect due to it no longer centring the focus. Therefore the best approach was to lose the focus on resize and force a recalculation of it. Also renamed Focus2 to Focus as Focus2 was meant to just be fill in whilst removing the original focus structs.
This commit is contained in:
parent
c56810e6a5
commit
a268350615
|
@ -274,7 +274,7 @@ rct_window* WindowCreate(
|
|||
w->min_height = height;
|
||||
w->max_height = height;
|
||||
|
||||
w->focus2 = std::nullopt;
|
||||
w->focus = std::nullopt;
|
||||
w->page = 0;
|
||||
w->var_48C = 0;
|
||||
w->var_492 = 0;
|
||||
|
|
|
@ -786,8 +786,7 @@ namespace OpenRCT2::Ui::Windows
|
|||
auto wheight = viewportWidget->height() - 1;
|
||||
if (viewport == nullptr)
|
||||
{
|
||||
const auto focus = Focus2(CoordsXYZ(0, 0, 0));
|
||||
viewport_create(this, { left, top }, wwidth, wheight, focus);
|
||||
viewport_create(this, { left, top }, wwidth, wheight, Focus(CoordsXYZ(0, 0, 0)));
|
||||
flags |= WF_NO_SCROLLING;
|
||||
Invalidate();
|
||||
}
|
||||
|
|
|
@ -79,10 +79,9 @@ private:
|
|||
void CreateViewport()
|
||||
{
|
||||
rct_widget* viewportWidget = &window_banner_widgets[WIDX_VIEWPORT];
|
||||
const auto focus = Focus2(_bannerViewPos);
|
||||
viewport_create(
|
||||
this, windowPos + ScreenCoordsXY{ viewportWidget->left + 1, viewportWidget->top + 1 },
|
||||
(viewportWidget->width()) - 1, (viewportWidget->height()) - 1, focus);
|
||||
(viewportWidget->width()) - 1, (viewportWidget->height()) - 1, Focus(_bannerViewPos));
|
||||
|
||||
if (viewport != nullptr)
|
||||
viewport->flags = gConfigGeneral.always_show_gridlines ? VIEWPORT_FLAG_GRIDLINES : 0;
|
||||
|
|
|
@ -40,8 +40,7 @@ rct_window* window_editor_main_open()
|
|||
&window_editor_main_events, WC_MAIN_WINDOW, WF_STICK_TO_BACK);
|
||||
window->widgets = window_editor_main_widgets;
|
||||
|
||||
const auto focus = Focus2(CoordsXYZ(0x0FFF, 0x0FFF, 0));
|
||||
viewport_create(window, window->windowPos, window->width, window->height, focus);
|
||||
viewport_create(window, window->windowPos, window->width, window->height, Focus(CoordsXYZ(0x0FFF, 0x0FFF, 0)));
|
||||
window->viewport->flags |= 0x0400;
|
||||
|
||||
gCurrentRotation = 0;
|
||||
|
|
|
@ -732,7 +732,7 @@ void window_guest_viewport_init(rct_window* w)
|
|||
uint16_t origViewportFlags{};
|
||||
if (w->viewport != nullptr)
|
||||
{
|
||||
if (w->focus2.has_value())
|
||||
if (w->focus.has_value())
|
||||
return;
|
||||
|
||||
origViewportFlags = w->viewport->flags;
|
||||
|
@ -750,7 +750,7 @@ void window_guest_viewport_init(rct_window* w)
|
|||
int32_t width = view_widget->width() - 1;
|
||||
int32_t height = view_widget->height() - 1;
|
||||
|
||||
viewport_create(w, screenPos, width, height, w->focus2.value());
|
||||
viewport_create(w, screenPos, width, height, w->focus.value());
|
||||
if (w->viewport != nullptr && reCreateViewport)
|
||||
{
|
||||
w->viewport->flags = origViewportFlags;
|
||||
|
|
|
@ -41,8 +41,7 @@ rct_window* window_main_open()
|
|||
WF_STICK_TO_BACK);
|
||||
window->widgets = window_main_widgets;
|
||||
|
||||
const auto focus = Focus2(CoordsXYZ(0x0FFF, 0x0FFF, 0));
|
||||
viewport_create(window, window->windowPos, window->width, window->height, focus);
|
||||
viewport_create(window, window->windowPos, window->width, window->height, Focus(CoordsXYZ(0x0FFF, 0x0FFF, 0)));
|
||||
window->viewport->flags |= VIEWPORT_FLAG_SOUND_ON;
|
||||
gCurrentRotation = 0;
|
||||
gShowGridLinesRefCount = 0;
|
||||
|
|
|
@ -740,11 +740,11 @@ static void window_park_init_viewport(rct_window* w)
|
|||
if (w->page != WINDOW_PARK_PAGE_ENTRANCE)
|
||||
return;
|
||||
|
||||
std::optional<Focus2> focus = std::nullopt;
|
||||
std::optional<Focus> focus = std::nullopt;
|
||||
if (!gParkEntrances.empty())
|
||||
{
|
||||
const auto& entrance = gParkEntrances[0];
|
||||
focus = Focus2(CoordsXYZ{ entrance.x + 16, entrance.y + 16, entrance.z + 32 });
|
||||
focus = Focus(CoordsXYZ{ entrance.x + 16, entrance.y + 16, entrance.z + 32 });
|
||||
}
|
||||
|
||||
if (w->viewport == nullptr)
|
||||
|
@ -760,7 +760,7 @@ static void window_park_init_viewport(rct_window* w)
|
|||
// Call invalidate event
|
||||
window_event_invalidate_call(w);
|
||||
|
||||
w->focus2 = focus;
|
||||
w->focus = focus;
|
||||
|
||||
if (focus.has_value())
|
||||
{
|
||||
|
|
|
@ -547,7 +547,7 @@ static void window_player_set_page(rct_window* w, int32_t page)
|
|||
{
|
||||
if (w->viewport == nullptr)
|
||||
{
|
||||
const auto focus = Focus2(TileCoordsXYZ(128, 128, 0).ToCoordsXYZ());
|
||||
const auto focus = Focus(TileCoordsXYZ(128, 128, 0).ToCoordsXYZ());
|
||||
viewport_create(w, w->windowPos, w->width, w->height, focus);
|
||||
w->flags |= WF_NO_SCROLLING;
|
||||
window_event_invalidate_call(w);
|
||||
|
|
|
@ -1589,7 +1589,7 @@ static void window_ride_init_viewport(rct_window* w)
|
|||
|
||||
int32_t viewSelectionIndex = w->ride.view - 1;
|
||||
|
||||
std::optional<Focus2> focus;
|
||||
std::optional<Focus> focus;
|
||||
|
||||
if (viewSelectionIndex >= 0 && viewSelectionIndex < ride->num_vehicles && ride->lifecycle_flags & RIDE_LIFECYCLE_ON_TRACK)
|
||||
{
|
||||
|
@ -1609,7 +1609,7 @@ static void window_ride_init_viewport(rct_window* w)
|
|||
}
|
||||
if (vehId != SPRITE_INDEX_NULL)
|
||||
{
|
||||
focus = Focus2(vehId);
|
||||
focus = Focus(vehId);
|
||||
}
|
||||
}
|
||||
else if (viewSelectionIndex >= ride->num_vehicles && viewSelectionIndex < (ride->num_vehicles + ride->num_stations))
|
||||
|
@ -1618,7 +1618,7 @@ static void window_ride_init_viewport(rct_window* w)
|
|||
if (stationIndex)
|
||||
{
|
||||
const auto location = ride->stations[*stationIndex].GetStart();
|
||||
focus = Focus2(location);
|
||||
focus = Focus(location);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -1630,14 +1630,14 @@ static void window_ride_init_viewport(rct_window* w)
|
|||
if (w->number < ride_overall_views.size())
|
||||
{
|
||||
const auto& view = ride_overall_views[w->number];
|
||||
focus = Focus2(view.loc, view.zoom);
|
||||
focus = Focus(view.loc, view.zoom);
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t viewport_flags = 0;
|
||||
if (w->viewport != nullptr)
|
||||
{
|
||||
if (focus == w->focus2)
|
||||
if (focus == w->focus)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -1651,7 +1651,7 @@ static void window_ride_init_viewport(rct_window* w)
|
|||
|
||||
window_event_invalidate_call(w);
|
||||
|
||||
w->focus2 = focus;
|
||||
w->focus = focus;
|
||||
|
||||
// rct2: 0x006aec9c only used here so brought it into the function
|
||||
if (!w->viewport && !ride->overall_view.IsNull())
|
||||
|
@ -1662,7 +1662,7 @@ static void window_ride_init_viewport(rct_window* w)
|
|||
int32_t width = view_widget->width() - 1;
|
||||
int32_t height = view_widget->height() - 1;
|
||||
|
||||
viewport_create(w, screenPos, width, height, w->focus2.value());
|
||||
viewport_create(w, screenPos, width, height, w->focus.value());
|
||||
|
||||
w->flags |= WF_NO_SCROLLING;
|
||||
w->Invalidate();
|
||||
|
@ -1796,6 +1796,8 @@ static void window_ride_main_resize(rct_window* w)
|
|||
|
||||
w->flags |= WF_RESIZABLE;
|
||||
window_set_resize(w, 316, minHeight, 500, 450);
|
||||
// Unlike with other windows, the focus needs to be recentred so it’s best to just reset it.
|
||||
w->focus = std::nullopt;
|
||||
window_ride_init_viewport(w);
|
||||
}
|
||||
|
||||
|
|
|
@ -127,10 +127,9 @@ public:
|
|||
|
||||
// Create viewport
|
||||
rct_widget& viewportWidget = window_sign_widgets[WIDX_VIEWPORT];
|
||||
const auto focus = Focus2(CoordsXYZ{ signViewPosition, viewZ });
|
||||
viewport_create(
|
||||
this, windowPos + ScreenCoordsXY{ viewportWidget.left + 1, viewportWidget.top + 1 }, viewportWidget.width() - 1,
|
||||
viewportWidget.height() - 1, focus);
|
||||
viewportWidget.height() - 1, Focus(CoordsXYZ{ signViewPosition, viewZ }));
|
||||
|
||||
viewport->flags = gConfigGeneral.always_show_gridlines ? VIEWPORT_FLAG_GRIDLINES : 0;
|
||||
Invalidate();
|
||||
|
@ -300,10 +299,9 @@ public:
|
|||
|
||||
// Create viewport
|
||||
rct_widget* viewportWidget = &window_sign_widgets[WIDX_VIEWPORT];
|
||||
const auto focus = Focus2(CoordsXYZ{ signViewPos });
|
||||
viewport_create(
|
||||
this, windowPos + ScreenCoordsXY{ viewportWidget->left + 1, viewportWidget->top + 1 }, viewportWidget->width() - 1,
|
||||
viewportWidget->height() - 1, focus);
|
||||
viewportWidget->height() - 1, Focus(CoordsXYZ{ signViewPos }));
|
||||
if (viewport != nullptr)
|
||||
viewport->flags = gConfigGeneral.always_show_gridlines ? VIEWPORT_FLAG_GRIDLINES : 0;
|
||||
Invalidate();
|
||||
|
|
|
@ -1346,7 +1346,7 @@ void window_staff_viewport_init(rct_window* w)
|
|||
if (w->page != WINDOW_STAFF_OVERVIEW)
|
||||
return;
|
||||
|
||||
std::optional<Focus2> focus;
|
||||
std::optional<Focus> focus;
|
||||
|
||||
const auto peep = GetStaff(w);
|
||||
if (peep == nullptr)
|
||||
|
@ -1356,14 +1356,14 @@ void window_staff_viewport_init(rct_window* w)
|
|||
|
||||
if (peep->State != PeepState::Picked)
|
||||
{
|
||||
focus = Focus2(peep->sprite_index);
|
||||
focus = Focus(peep->sprite_index);
|
||||
}
|
||||
|
||||
uint16_t viewport_flags;
|
||||
|
||||
if (w->viewport)
|
||||
{
|
||||
if (focus == w->focus2)
|
||||
if (focus == w->focus)
|
||||
return;
|
||||
|
||||
viewport_flags = w->viewport->flags;
|
||||
|
@ -1378,7 +1378,7 @@ void window_staff_viewport_init(rct_window* w)
|
|||
|
||||
window_event_invalidate_call(w);
|
||||
|
||||
w->focus2 = focus;
|
||||
w->focus = focus;
|
||||
|
||||
if (peep->State != PeepState::Picked)
|
||||
{
|
||||
|
|
|
@ -227,7 +227,7 @@ void window_title_command_editor_open(TitleSequence* sequence, int32_t index, bo
|
|||
WindowInitScrollWidgets(window);
|
||||
|
||||
rct_widget* const viewportWidget = &window_title_command_editor_widgets[WIDX_VIEWPORT];
|
||||
const auto focus = Focus2(CoordsXYZ{ 0, 0, 0 });
|
||||
const auto focus = Focus(CoordsXYZ{ 0, 0, 0 });
|
||||
viewport_create(
|
||||
window, window->windowPos + ScreenCoordsXY{ viewportWidget->left + 1, viewportWidget->top + 1 },
|
||||
viewportWidget->width() - 1, viewportWidget->height() - 1, focus);
|
||||
|
|
|
@ -76,8 +76,7 @@ public:
|
|||
enabled_widgets = (1ULL << WIDX_CLOSE) | (1ULL << WIDX_ZOOM_IN) | (1ULL << WIDX_ZOOM_OUT) | (1ULL << WIDX_LOCATE);
|
||||
|
||||
// Create viewport
|
||||
const auto focus = Focus2(TileCoordsXYZ(128, 128, 0).ToCoordsXYZ());
|
||||
viewport_create(this, windowPos, width, height, focus);
|
||||
viewport_create(this, windowPos, width, height, Focus(TileCoordsXYZ(128, 128, 0).ToCoordsXYZ()));
|
||||
if (viewport == nullptr)
|
||||
{
|
||||
Close();
|
||||
|
|
|
@ -117,14 +117,14 @@ std::optional<ScreenCoordsXY> centre_2d_coordinates(const CoordsXYZ& loc, rct_vi
|
|||
return { screenCoord };
|
||||
}
|
||||
|
||||
CoordsXYZ Focus2::GetPos() const
|
||||
CoordsXYZ Focus::GetPos() const
|
||||
{
|
||||
return std::visit(
|
||||
[](auto&& arg) {
|
||||
using T = std::decay_t<decltype(arg)>;
|
||||
if constexpr (std::is_same_v<T, Focus2::CoordinateFocus>)
|
||||
if constexpr (std::is_same_v<T, Focus::CoordinateFocus>)
|
||||
return arg;
|
||||
else if constexpr (std::is_same_v<T, Focus2::EntityFocus>)
|
||||
else if constexpr (std::is_same_v<T, Focus::EntityFocus>)
|
||||
{
|
||||
auto* centreEntity = GetEntity(arg);
|
||||
if (centreEntity != nullptr)
|
||||
|
@ -158,7 +158,7 @@ CoordsXYZ Focus2::GetPos() const
|
|||
* flags: edx top most 2 bits 0b_X1 for zoom clear see below for 2nd bit.
|
||||
* w: esi
|
||||
*/
|
||||
void viewport_create(rct_window* w, const ScreenCoordsXY& screenCoords, int32_t width, int32_t height, const Focus2& focus)
|
||||
void viewport_create(rct_window* w, const ScreenCoordsXY& screenCoords, int32_t width, int32_t height, const Focus& focus)
|
||||
{
|
||||
rct_viewport* viewport = nullptr;
|
||||
if (_viewports.size() >= MAX_VIEWPORT_COUNT)
|
||||
|
@ -188,9 +188,9 @@ void viewport_create(rct_window* w, const ScreenCoordsXY& screenCoords, int32_t
|
|||
w->viewport_target_sprite = std::visit(
|
||||
[](auto&& arg) {
|
||||
using T = std::decay_t<decltype(arg)>;
|
||||
if constexpr (std::is_same_v<T, Focus2::CoordinateFocus>)
|
||||
if constexpr (std::is_same_v<T, Focus::CoordinateFocus>)
|
||||
return SPRITE_INDEX_NULL;
|
||||
else if constexpr (std::is_same_v<T, Focus2::EntityFocus>)
|
||||
else if constexpr (std::is_same_v<T, Focus::EntityFocus>)
|
||||
return arg;
|
||||
},
|
||||
focus.data);
|
||||
|
@ -702,7 +702,7 @@ void viewport_update_smart_sprite_follow(rct_window* window)
|
|||
break;
|
||||
|
||||
default: // All other types don't need any "smart" following; steam particle, duck, money effect, etc.
|
||||
window->focus2 = Focus2(window->viewport_smart_follow_sprite);
|
||||
window->focus = Focus(window->viewport_smart_follow_sprite);
|
||||
window->viewport_target_sprite = window->viewport_smart_follow_sprite;
|
||||
break;
|
||||
}
|
||||
|
@ -710,14 +710,14 @@ void viewport_update_smart_sprite_follow(rct_window* window)
|
|||
|
||||
void viewport_update_smart_guest_follow(rct_window* window, const Guest* peep)
|
||||
{
|
||||
Focus2 focus = Focus2(peep->sprite_index);
|
||||
Focus focus = Focus(peep->sprite_index);
|
||||
window->viewport_target_sprite = peep->sprite_index;
|
||||
|
||||
if (peep->State == PeepState::Picked)
|
||||
{
|
||||
window->viewport_smart_follow_sprite = SPRITE_INDEX_NULL;
|
||||
window->viewport_target_sprite = SPRITE_INDEX_NULL;
|
||||
window->focus2 = std::nullopt; // No focus
|
||||
window->focus = std::nullopt; // No focus
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -734,7 +734,7 @@ void viewport_update_smart_guest_follow(rct_window* window, const Guest* peep)
|
|||
const auto car = train->GetCar(peep->CurrentCar);
|
||||
if (car != nullptr)
|
||||
{
|
||||
focus = Focus2(car->sprite_index);
|
||||
focus = Focus(car->sprite_index);
|
||||
overallFocus = false;
|
||||
window->viewport_target_sprite = car->sprite_index;
|
||||
}
|
||||
|
@ -752,12 +752,12 @@ void viewport_update_smart_guest_follow(rct_window* window, const Guest* peep)
|
|||
coordFocus.x = xy.x;
|
||||
coordFocus.y = xy.y;
|
||||
coordFocus.z = tile_element_height(xy) + (4 * COORDS_Z_STEP);
|
||||
focus = Focus2(coordFocus);
|
||||
focus = Focus(coordFocus);
|
||||
window->viewport_target_sprite = SPRITE_INDEX_NULL;
|
||||
}
|
||||
}
|
||||
|
||||
window->focus2 = focus;
|
||||
window->focus = focus;
|
||||
}
|
||||
|
||||
void viewport_update_smart_staff_follow(rct_window* window, const Staff* peep)
|
||||
|
@ -766,17 +766,17 @@ void viewport_update_smart_staff_follow(rct_window* window, const Staff* peep)
|
|||
{
|
||||
window->viewport_smart_follow_sprite = SPRITE_INDEX_NULL;
|
||||
window->viewport_target_sprite = SPRITE_INDEX_NULL;
|
||||
window->focus2 = std::nullopt;
|
||||
window->focus = std::nullopt;
|
||||
return;
|
||||
}
|
||||
|
||||
window->focus2 = Focus2(window->viewport_smart_follow_sprite);
|
||||
window->focus = Focus(window->viewport_smart_follow_sprite);
|
||||
window->viewport_target_sprite = window->viewport_smart_follow_sprite;
|
||||
}
|
||||
|
||||
void viewport_update_smart_vehicle_follow(rct_window* window)
|
||||
{
|
||||
window->focus2 = Focus2(window->viewport_smart_follow_sprite);
|
||||
window->focus = Focus(window->viewport_smart_follow_sprite);
|
||||
window->viewport_target_sprite = window->viewport_smart_follow_sprite;
|
||||
}
|
||||
|
||||
|
|
|
@ -104,7 +104,7 @@ extern uint8_t gCurrentRotation;
|
|||
|
||||
void viewport_init_all();
|
||||
std::optional<ScreenCoordsXY> centre_2d_coordinates(const CoordsXYZ& loc, rct_viewport* viewport);
|
||||
void viewport_create(rct_window* w, const ScreenCoordsXY& screenCoords, int32_t width, int32_t height, const Focus2& focus);
|
||||
void viewport_create(rct_window* w, const ScreenCoordsXY& screenCoords, int32_t width, int32_t height, const Focus& focus);
|
||||
void viewport_remove(rct_viewport* viewport);
|
||||
void viewports_invalidate(int32_t left, int32_t top, int32_t right, int32_t bottom, int32_t maxZoom = -1);
|
||||
void viewport_update_position(rct_window* window);
|
||||
|
|
|
@ -195,7 +195,7 @@ struct rct_scroll
|
|||
|
||||
constexpr auto WINDOW_SCROLL_UNDEFINED = std::numeric_limits<uint16_t>::max();
|
||||
|
||||
struct Focus2
|
||||
struct Focus
|
||||
{
|
||||
using CoordinateFocus = CoordsXYZ;
|
||||
using EntityFocus = uint16_t;
|
||||
|
@ -203,7 +203,7 @@ struct Focus2
|
|||
uint8_t zoom = 0;
|
||||
std::variant<CoordinateFocus, EntityFocus> data;
|
||||
|
||||
template<typename T> constexpr explicit Focus2(T newValue, uint8_t newZoom = 0)
|
||||
template<typename T> constexpr explicit Focus(T newValue, uint8_t newZoom = 0)
|
||||
{
|
||||
data = newValue;
|
||||
zoom = newZoom;
|
||||
|
@ -211,7 +211,7 @@ struct Focus2
|
|||
|
||||
CoordsXYZ GetPos() const;
|
||||
|
||||
constexpr bool operator==(const Focus2& other) const
|
||||
constexpr bool operator==(const Focus& other) const
|
||||
{
|
||||
if (zoom != other.zoom)
|
||||
{
|
||||
|
@ -219,7 +219,7 @@ struct Focus2
|
|||
}
|
||||
return data == other.data;
|
||||
}
|
||||
constexpr bool operator!=(const Focus2& other) const
|
||||
constexpr bool operator!=(const Focus& other) const
|
||||
{
|
||||
return !(*this == other);
|
||||
}
|
||||
|
|
|
@ -12,10 +12,10 @@ void rct_window::SetLocation(const CoordsXYZ& coords)
|
|||
|
||||
void rct_window::ScrollToViewport()
|
||||
{
|
||||
if (viewport == nullptr || !focus2.has_value())
|
||||
if (viewport == nullptr || !focus.has_value())
|
||||
return;
|
||||
|
||||
CoordsXYZ newCoords = focus2.value().GetPos();
|
||||
CoordsXYZ newCoords = focus.value().GetPos();
|
||||
|
||||
auto mainWindow = window_get_main();
|
||||
if (mainWindow != nullptr)
|
||||
|
|
|
@ -55,7 +55,7 @@ struct rct_window
|
|||
uint32_t list_item_positions[1024]{};
|
||||
uint16_t no_list_items{}; // 0 for no items
|
||||
int16_t selected_list_item{}; // -1 for none selected
|
||||
std::optional<Focus2> focus2;
|
||||
std::optional<Focus> focus;
|
||||
union
|
||||
{
|
||||
campaign_variables campaign;
|
||||
|
|
Loading…
Reference in New Issue