mirror of https://github.com/OpenRCT2/OpenRCT2.git
Remove focus union and replace with typed focus (#15426)
* Remove focus union and replace with typed focus This if for the NSF to allow for CoordsXYZ * Remove legacy structures * Rework viewport_create to deduplicate logic * Simplify yet further * Apply review comments * Remove intermediate
This commit is contained in:
parent
c05068e8d1
commit
fa57b6aea0
|
@ -274,11 +274,7 @@ rct_window* WindowCreate(
|
|||
w->min_height = height;
|
||||
w->max_height = height;
|
||||
|
||||
w->viewport_focus_coordinates.var_480 = 0;
|
||||
w->viewport_focus_coordinates.x = 0;
|
||||
w->viewport_focus_coordinates.y = 0;
|
||||
w->viewport_focus_coordinates.z = 0;
|
||||
w->viewport_focus_coordinates.rotation = 0;
|
||||
w->focus2 = std::nullopt;
|
||||
w->page = 0;
|
||||
w->var_48C = 0;
|
||||
w->var_492 = 0;
|
||||
|
|
|
@ -786,12 +786,8 @@ namespace OpenRCT2::Ui::Windows
|
|||
auto wheight = viewportWidget->height() - 1;
|
||||
if (viewport == nullptr)
|
||||
{
|
||||
auto mapX = 0;
|
||||
auto mapY = 0;
|
||||
auto mapZ = 0;
|
||||
viewport_create(
|
||||
this, { left, top }, wwidth, wheight, 0, { mapX, mapY, mapZ }, VIEWPORT_FOCUS_TYPE_COORDINATE,
|
||||
SPRITE_INDEX_NULL);
|
||||
const auto focus = Focus2(CoordsXYZ(0, 0, 0));
|
||||
viewport_create(this, { left, top }, wwidth, wheight, focus);
|
||||
flags |= WF_NO_SCROLLING;
|
||||
Invalidate();
|
||||
}
|
||||
|
|
|
@ -79,9 +79,10 @@ 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, 0, _bannerViewPos, 0, SPRITE_INDEX_NULL);
|
||||
(viewportWidget->width()) - 1, (viewportWidget->height()) - 1, focus);
|
||||
|
||||
if (viewport != nullptr)
|
||||
viewport->flags = gConfigGeneral.always_show_gridlines ? VIEWPORT_FLAG_GRIDLINES : 0;
|
||||
|
|
|
@ -40,7 +40,8 @@ rct_window* window_editor_main_open()
|
|||
&window_editor_main_events, WC_MAIN_WINDOW, WF_STICK_TO_BACK);
|
||||
window->widgets = window_editor_main_widgets;
|
||||
|
||||
viewport_create(window, window->windowPos, window->width, window->height, 0, { 0x0FFF, 0x0FFF, 0 }, 0x1, SPRITE_INDEX_NULL);
|
||||
const auto focus = Focus2(CoordsXYZ(0x0FFF, 0x0FFF, 0));
|
||||
viewport_create(window, window->windowPos, window->width, window->height, focus);
|
||||
window->viewport->flags |= 0x0400;
|
||||
|
||||
gCurrentRotation = 0;
|
||||
|
|
|
@ -398,7 +398,6 @@ rct_window* window_guest_open(Peep* peep)
|
|||
window->enabled_widgets = window_guest_page_enabled_widgets[0];
|
||||
window->number = peep->sprite_index;
|
||||
window->page = 0;
|
||||
window->viewport_focus_coordinates.y = 0;
|
||||
window->frame_no = 0;
|
||||
window->list_information_type = 0;
|
||||
window->picked_peep_frame = 0;
|
||||
|
@ -410,8 +409,6 @@ rct_window* window_guest_open(Peep* peep)
|
|||
window->max_height = 450;
|
||||
window->no_list_items = 0;
|
||||
window->selected_list_item = -1;
|
||||
|
||||
window->viewport_focus_coordinates.y = -1;
|
||||
}
|
||||
|
||||
window->page = 0;
|
||||
|
@ -730,16 +727,12 @@ void window_guest_viewport_init(rct_window* w)
|
|||
return;
|
||||
}
|
||||
|
||||
auto focus = viewport_update_smart_guest_follow(w, peep);
|
||||
viewport_update_smart_guest_follow(w, peep);
|
||||
bool reCreateViewport = false;
|
||||
uint16_t origViewportFlags{};
|
||||
if (w->viewport != nullptr)
|
||||
{
|
||||
// Check all combos, for now skipping y and rot
|
||||
if (focus.coordinate.x == w->viewport_focus_coordinates.x
|
||||
&& (focus.coordinate.y & VIEWPORT_FOCUS_Y_MASK) == w->viewport_focus_coordinates.y
|
||||
&& focus.coordinate.z == w->viewport_focus_coordinates.z
|
||||
&& focus.coordinate.rotation == w->viewport_focus_coordinates.rotation)
|
||||
if (w->focus2.has_value())
|
||||
return;
|
||||
|
||||
origViewportFlags = w->viewport->flags;
|
||||
|
@ -750,11 +743,6 @@ void window_guest_viewport_init(rct_window* w)
|
|||
|
||||
window_event_invalidate_call(w);
|
||||
|
||||
w->viewport_focus_coordinates.x = focus.coordinate.x;
|
||||
w->viewport_focus_coordinates.y = focus.coordinate.y;
|
||||
w->viewport_focus_coordinates.z = focus.coordinate.z;
|
||||
w->viewport_focus_coordinates.rotation = focus.coordinate.rotation;
|
||||
|
||||
if (peep->State != PeepState::Picked && w->viewport == nullptr)
|
||||
{
|
||||
auto view_widget = &w->widgets[WIDX_VIEWPORT];
|
||||
|
@ -762,10 +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, 0,
|
||||
{ focus.coordinate.x, focus.coordinate.y & VIEWPORT_FOCUS_Y_MASK, focus.coordinate.z },
|
||||
focus.sprite.type & VIEWPORT_FOCUS_TYPE_MASK, focus.sprite.sprite_id);
|
||||
viewport_create(w, screenPos, width, height, w->focus2.value());
|
||||
if (w->viewport != nullptr && reCreateViewport)
|
||||
{
|
||||
w->viewport->flags = origViewportFlags;
|
||||
|
|
|
@ -41,7 +41,8 @@ rct_window* window_main_open()
|
|||
WF_STICK_TO_BACK);
|
||||
window->widgets = window_main_widgets;
|
||||
|
||||
viewport_create(window, window->windowPos, window->width, window->height, 0, { 0x0FFF, 0x0FFF, 0 }, 0x1, SPRITE_INDEX_NULL);
|
||||
const auto focus = Focus2(CoordsXYZ(0x0FFF, 0x0FFF, 0));
|
||||
viewport_create(window, window->windowPos, window->width, window->height, focus);
|
||||
window->viewport->flags |= VIEWPORT_FLAG_SOUND_ON;
|
||||
gCurrentRotation = 0;
|
||||
gShowGridLinesRefCount = 0;
|
||||
|
|
|
@ -415,7 +415,6 @@ static rct_window* window_park_open()
|
|||
w->enabled_widgets = window_park_page_enabled_widgets[WINDOW_PARK_PAGE_ENTRANCE];
|
||||
w->number = 0;
|
||||
w->page = WINDOW_PARK_PAGE_ENTRANCE;
|
||||
w->viewport_focus_coordinates.y = 0;
|
||||
w->frame_no = 0;
|
||||
w->list_information_type = std::numeric_limits<uint16_t>::max();
|
||||
w->numberOfStaff = -1;
|
||||
|
@ -459,8 +458,6 @@ rct_window* window_park_entrance_open()
|
|||
if (window == nullptr)
|
||||
{
|
||||
window = window_park_open();
|
||||
window->viewport_focus_coordinates.y = -1;
|
||||
window->viewport_focus_coordinates.x = -1;
|
||||
}
|
||||
|
||||
window->page = WINDOW_PARK_PAGE_ENTRANCE;
|
||||
|
@ -738,22 +735,16 @@ static void window_park_entrance_paint(rct_window* w, rct_drawpixelinfo* dpi)
|
|||
*/
|
||||
static void window_park_init_viewport(rct_window* w)
|
||||
{
|
||||
int32_t x, y, z, r, xy, zr, viewportFlags;
|
||||
x = y = z = r = xy = zr = 0;
|
||||
int32_t viewportFlags;
|
||||
|
||||
if (w->page != WINDOW_PARK_PAGE_ENTRANCE)
|
||||
return;
|
||||
|
||||
std::optional<Focus2> focus = std::nullopt;
|
||||
if (!gParkEntrances.empty())
|
||||
{
|
||||
const auto& entrance = gParkEntrances[0];
|
||||
x = entrance.x + 16;
|
||||
y = entrance.y + 16;
|
||||
z = entrance.z + 32;
|
||||
r = get_current_rotation();
|
||||
|
||||
xy = IMAGE_TYPE_TRANSPARENT | (y << 16) | x;
|
||||
zr = (z << 16) | (r << 8);
|
||||
focus = Focus2(CoordsXYZ{ entrance.x + 16, entrance.y + 16, entrance.z + 32 });
|
||||
}
|
||||
|
||||
if (w->viewport == nullptr)
|
||||
|
@ -769,13 +760,9 @@ static void window_park_init_viewport(rct_window* w)
|
|||
// Call invalidate event
|
||||
window_event_invalidate_call(w);
|
||||
|
||||
w->viewport_focus_coordinates.x = x;
|
||||
w->viewport_focus_coordinates.y = y;
|
||||
w->viewport_focus_sprite.type |= VIEWPORT_FOCUS_TYPE_COORDINATE;
|
||||
w->viewport_focus_coordinates.z = z;
|
||||
w->viewport_focus_coordinates.rotation = r;
|
||||
w->focus2 = focus;
|
||||
|
||||
if (zr != 0xFFFF)
|
||||
if (focus.has_value())
|
||||
{
|
||||
// Create viewport
|
||||
if (w->viewport == nullptr)
|
||||
|
@ -783,8 +770,7 @@ static void window_park_init_viewport(rct_window* w)
|
|||
rct_widget* viewportWidget = &window_park_entrance_widgets[WIDX_VIEWPORT];
|
||||
viewport_create(
|
||||
w, w->windowPos + ScreenCoordsXY{ viewportWidget->left + 1, viewportWidget->top + 1 },
|
||||
viewportWidget->width() - 1, viewportWidget->height() - 1, 0, { x, y, z },
|
||||
w->viewport_focus_sprite.type & VIEWPORT_FOCUS_TYPE_MASK, SPRITE_INDEX_NULL);
|
||||
viewportWidget->width() - 1, viewportWidget->height() - 1, focus.value());
|
||||
w->flags |= (1 << 2);
|
||||
w->Invalidate();
|
||||
}
|
||||
|
@ -811,8 +797,6 @@ rct_window* window_park_rating_open()
|
|||
if (window == nullptr)
|
||||
{
|
||||
window = window_park_open();
|
||||
window->viewport_focus_coordinates.x = -1;
|
||||
window->viewport_focus_coordinates.y = -1;
|
||||
}
|
||||
|
||||
if (input_test_flag(INPUT_FLAG_TOOL_ACTIVE))
|
||||
|
@ -947,8 +931,6 @@ rct_window* window_park_guests_open()
|
|||
if (window == nullptr)
|
||||
{
|
||||
window = window_park_open();
|
||||
window->viewport_focus_coordinates.x = -1;
|
||||
window->viewport_focus_coordinates.y = -1;
|
||||
}
|
||||
|
||||
if (input_test_flag(INPUT_FLAG_TOOL_ACTIVE))
|
||||
|
@ -1356,8 +1338,6 @@ rct_window* window_park_objective_open()
|
|||
if (window == nullptr)
|
||||
{
|
||||
window = window_park_open();
|
||||
window->viewport_focus_coordinates.x = -1;
|
||||
window->viewport_focus_coordinates.y = -1;
|
||||
}
|
||||
|
||||
if (input_test_flag(INPUT_FLAG_TOOL_ACTIVE))
|
||||
|
@ -1549,8 +1529,6 @@ rct_window* window_park_awards_open()
|
|||
if (window == nullptr)
|
||||
{
|
||||
window = window_park_open();
|
||||
window->viewport_focus_coordinates.x = -1;
|
||||
window->viewport_focus_coordinates.y = -1;
|
||||
}
|
||||
|
||||
if (input_test_flag(INPUT_FLAG_TOOL_ACTIVE))
|
||||
|
|
|
@ -155,7 +155,6 @@ rct_window* window_player_open(uint8_t id)
|
|||
window = WindowCreateAutoPos(240, 170, &window_player_overview_events, WC_PLAYER, WF_RESIZABLE);
|
||||
window->number = id;
|
||||
window->page = 0;
|
||||
window->viewport_focus_coordinates.y = 0;
|
||||
window->frame_no = 0;
|
||||
window->list_information_type = 0;
|
||||
window->picked_peep_frame = 0;
|
||||
|
@ -164,10 +163,9 @@ rct_window* window_player_open(uint8_t id)
|
|||
window->min_height = 134;
|
||||
window->max_width = 500;
|
||||
window->max_height = 450;
|
||||
|
||||
window->no_list_items = 0;
|
||||
window->selected_list_item = -1;
|
||||
|
||||
window->viewport_focus_coordinates.y = -1;
|
||||
}
|
||||
|
||||
window->page = 0;
|
||||
|
@ -549,8 +547,8 @@ static void window_player_set_page(rct_window* w, int32_t page)
|
|||
{
|
||||
if (w->viewport == nullptr)
|
||||
{
|
||||
viewport_create(
|
||||
w, w->windowPos, w->width, w->height, 0, TileCoordsXYZ(128, 128, 0).ToCoordsXYZ(), 1, SPRITE_INDEX_NULL);
|
||||
const auto focus = Focus2(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);
|
||||
window_player_update_viewport(w, false);
|
||||
|
|
|
@ -1591,42 +1591,29 @@ static void window_ride_init_viewport(rct_window* w)
|
|||
if (ride == nullptr)
|
||||
return;
|
||||
|
||||
int32_t viewSelectionIndex = w->viewport_focus_coordinates.var_480 - 1;
|
||||
int32_t viewSelectionIndex = w->ride.view - 1;
|
||||
|
||||
union
|
||||
{
|
||||
sprite_focus sprite;
|
||||
coordinate_focus coordinate;
|
||||
} focus;
|
||||
|
||||
focus.coordinate.x = 0;
|
||||
focus.coordinate.y = 0;
|
||||
focus.coordinate.z = 0;
|
||||
focus.sprite.sprite_id = SPRITE_INDEX_NULL;
|
||||
focus.coordinate.zoom = 0;
|
||||
focus.coordinate.rotation = get_current_rotation();
|
||||
focus.coordinate.width = 0;
|
||||
focus.coordinate.height = 0;
|
||||
std::optional<Focus2> focus;
|
||||
|
||||
if (viewSelectionIndex >= 0 && viewSelectionIndex < ride->num_vehicles && ride->lifecycle_flags & RIDE_LIFECYCLE_ON_TRACK)
|
||||
{
|
||||
focus.sprite.sprite_id = ride->vehicles[viewSelectionIndex];
|
||||
uint16_t vehId = ride->vehicles[viewSelectionIndex];
|
||||
rct_ride_entry* ride_entry = ride->GetRideEntry();
|
||||
if (ride_entry && ride_entry->tab_vehicle != 0)
|
||||
{
|
||||
Vehicle* vehicle = GetEntity<Vehicle>(focus.sprite.sprite_id);
|
||||
Vehicle* vehicle = GetEntity<Vehicle>(vehId);
|
||||
if (vehicle == nullptr)
|
||||
{
|
||||
focus.sprite.sprite_id = SPRITE_INDEX_NULL;
|
||||
vehId = SPRITE_INDEX_NULL;
|
||||
}
|
||||
else if (vehicle->next_vehicle_on_train != SPRITE_INDEX_NULL)
|
||||
{
|
||||
focus.sprite.sprite_id = vehicle->next_vehicle_on_train;
|
||||
vehId = vehicle->next_vehicle_on_train;
|
||||
}
|
||||
}
|
||||
if (focus.sprite.sprite_id != SPRITE_INDEX_NULL)
|
||||
if (vehId != SPRITE_INDEX_NULL)
|
||||
{
|
||||
focus.sprite.type |= VIEWPORT_FOCUS_TYPE_SPRITE;
|
||||
focus = Focus2(vehId);
|
||||
}
|
||||
}
|
||||
else if (viewSelectionIndex >= ride->num_vehicles && viewSelectionIndex < (ride->num_vehicles + ride->num_stations))
|
||||
|
@ -1634,41 +1621,28 @@ static void window_ride_init_viewport(rct_window* w)
|
|||
auto stationIndex = GetStationIndexFromViewSelection(*w);
|
||||
if (stationIndex)
|
||||
{
|
||||
auto location = ride->stations[*stationIndex].GetStart();
|
||||
focus.coordinate.x = location.x;
|
||||
focus.coordinate.y = location.y;
|
||||
focus.coordinate.z = location.z;
|
||||
focus.sprite.type |= VIEWPORT_FOCUS_TYPE_COORDINATE;
|
||||
const auto location = ride->stations[*stationIndex].GetStart();
|
||||
focus = Focus2(location);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (viewSelectionIndex > 0)
|
||||
{
|
||||
w->viewport_focus_coordinates.var_480 = 0;
|
||||
w->ride.view = 0;
|
||||
}
|
||||
if (w->number < ride_overall_views.size())
|
||||
{
|
||||
const auto& 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 |= VIEWPORT_FOCUS_TYPE_COORDINATE;
|
||||
CoordsXYZ loc = { view.x, view.y, view.z };
|
||||
focus = Focus2(loc, view.zoom);
|
||||
}
|
||||
}
|
||||
focus.coordinate.var_480 = w->viewport_focus_coordinates.var_480;
|
||||
|
||||
uint16_t viewport_flags = 0;
|
||||
|
||||
if (w->viewport != nullptr)
|
||||
{
|
||||
if (focus.coordinate.x == w->viewport_focus_coordinates.x
|
||||
&& (focus.coordinate.y & VIEWPORT_FOCUS_Y_MASK) == w->viewport_focus_coordinates.y
|
||||
&& focus.coordinate.z == w->viewport_focus_coordinates.z
|
||||
&& focus.coordinate.rotation == w->viewport_focus_coordinates.rotation
|
||||
&& focus.coordinate.zoom == w->viewport_focus_coordinates.zoom && focus.coordinate.width == w->width
|
||||
&& focus.coordinate.height == w->height)
|
||||
if (focus == w->focus2)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -1682,13 +1656,7 @@ static void window_ride_init_viewport(rct_window* w)
|
|||
|
||||
window_event_invalidate_call(w);
|
||||
|
||||
w->viewport_focus_coordinates.x = focus.coordinate.x;
|
||||
w->viewport_focus_coordinates.y = focus.coordinate.y;
|
||||
w->viewport_focus_coordinates.z = focus.coordinate.z;
|
||||
w->viewport_focus_coordinates.rotation = focus.coordinate.rotation;
|
||||
w->viewport_focus_coordinates.zoom = focus.coordinate.zoom;
|
||||
w->viewport_focus_coordinates.width = w->width;
|
||||
w->viewport_focus_coordinates.height = w->height;
|
||||
w->focus2 = focus;
|
||||
|
||||
// rct2: 0x006aec9c only used here so brought it into the function
|
||||
if (!w->viewport && !ride->overall_view.IsNull())
|
||||
|
@ -1698,10 +1666,8 @@ static void window_ride_init_viewport(rct_window* w)
|
|||
auto screenPos = w->windowPos + ScreenCoordsXY{ view_widget->left + 1, view_widget->top + 1 };
|
||||
int32_t width = view_widget->width() - 1;
|
||||
int32_t height = view_widget->height() - 1;
|
||||
viewport_create(
|
||||
w, screenPos, width, height, focus.coordinate.zoom,
|
||||
{ focus.coordinate.x, focus.coordinate.y & VIEWPORT_FOCUS_Y_MASK, focus.coordinate.z },
|
||||
focus.sprite.type & VIEWPORT_FOCUS_TYPE_MASK, focus.sprite.sprite_id);
|
||||
|
||||
viewport_create(w, screenPos, width, height, w->focus2.value());
|
||||
|
||||
w->flags |= WF_NO_SCROLLING;
|
||||
w->Invalidate();
|
||||
|
|
|
@ -196,7 +196,6 @@ rct_window* window_scenarioselect_open(std::function<void(std::string_view)> cal
|
|||
initialise_list_items(window);
|
||||
|
||||
WindowInitScrollWidgets(window);
|
||||
window->viewport_focus_coordinates.var_480 = -1;
|
||||
window->highlighted_scenario = nullptr;
|
||||
|
||||
return window;
|
||||
|
|
|
@ -127,10 +127,10 @@ 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, 0, { signViewPosition, viewZ }, 0, SPRITE_INDEX_NULL);
|
||||
viewportWidget.height() - 1, focus);
|
||||
|
||||
viewport->flags = gConfigGeneral.always_show_gridlines ? VIEWPORT_FLAG_GRIDLINES : 0;
|
||||
Invalidate();
|
||||
|
@ -300,9 +300,10 @@ 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, 0, signViewPos, 0, SPRITE_INDEX_NULL);
|
||||
viewportWidget->height() - 1, focus);
|
||||
if (viewport != nullptr)
|
||||
viewport->flags = gConfigGeneral.always_show_gridlines ? VIEWPORT_FLAG_GRIDLINES : 0;
|
||||
Invalidate();
|
||||
|
|
|
@ -267,7 +267,6 @@ rct_window* window_staff_open(Peep* peep)
|
|||
|
||||
w->number = peep->sprite_index;
|
||||
w->page = 0;
|
||||
w->viewport_focus_coordinates.y = 0;
|
||||
w->frame_no = 0;
|
||||
w->highlighted_item = 0;
|
||||
|
||||
|
@ -1347,9 +1346,7 @@ void window_staff_viewport_init(rct_window* w)
|
|||
if (w->page != WINDOW_STAFF_OVERVIEW)
|
||||
return;
|
||||
|
||||
sprite_focus focus = {};
|
||||
|
||||
focus.sprite_id = w->number;
|
||||
std::optional<Focus2> focus;
|
||||
|
||||
const auto peep = GetStaff(w);
|
||||
if (peep == nullptr)
|
||||
|
@ -1357,23 +1354,16 @@ void window_staff_viewport_init(rct_window* w)
|
|||
return;
|
||||
}
|
||||
|
||||
if (peep->State == PeepState::Picked)
|
||||
if (peep->State != PeepState::Picked)
|
||||
{
|
||||
focus.sprite_id = SPRITE_INDEX_NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
focus.type |= VIEWPORT_FOCUS_TYPE_SPRITE | VIEWPORT_FOCUS_TYPE_COORDINATE;
|
||||
focus.rotation = get_current_rotation();
|
||||
focus = Focus2(peep->sprite_index);
|
||||
}
|
||||
|
||||
uint16_t viewport_flags;
|
||||
|
||||
if (w->viewport)
|
||||
{
|
||||
// Check all combos, for now skipping y and rot
|
||||
if (focus.sprite_id == w->viewport_focus_sprite.sprite_id && focus.type == w->viewport_focus_sprite.type
|
||||
&& focus.rotation == w->viewport_focus_sprite.rotation)
|
||||
if (focus == w->focus2)
|
||||
return;
|
||||
|
||||
viewport_flags = w->viewport->flags;
|
||||
|
@ -1388,9 +1378,7 @@ void window_staff_viewport_init(rct_window* w)
|
|||
|
||||
window_event_invalidate_call(w);
|
||||
|
||||
w->viewport_focus_sprite.sprite_id = focus.sprite_id;
|
||||
w->viewport_focus_sprite.type = focus.type;
|
||||
w->viewport_focus_sprite.rotation = focus.rotation;
|
||||
w->focus2 = focus;
|
||||
|
||||
if (peep->State != PeepState::Picked)
|
||||
{
|
||||
|
@ -1402,8 +1390,7 @@ void window_staff_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, 0, { 0, 0, 0 }, focus.type & VIEWPORT_FOCUS_TYPE_MASK, focus.sprite_id);
|
||||
viewport_create(w, screenPos, width, height, focus.value());
|
||||
w->flags |= WF_NO_SCROLLING;
|
||||
w->Invalidate();
|
||||
}
|
||||
|
|
|
@ -227,9 +227,10 @@ 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 });
|
||||
viewport_create(
|
||||
window, window->windowPos + ScreenCoordsXY{ viewportWidget->left + 1, viewportWidget->top + 1 },
|
||||
viewportWidget->width() - 1, viewportWidget->height() - 1, 0, { 0, 0, 0 }, 0, SPRITE_INDEX_NULL);
|
||||
viewportWidget->width() - 1, viewportWidget->height() - 1, focus);
|
||||
|
||||
_window_title_command_editor_index = index;
|
||||
_window_title_command_editor_insert = insert;
|
||||
|
@ -476,7 +477,8 @@ static void window_title_command_editor_dropdown(rct_window* w, rct_widgetindex
|
|||
_command.SpriteIndex = SPRITE_INDEX_NULL;
|
||||
_command.SpriteName[0] = '\0';
|
||||
window_unfollow_sprite(w);
|
||||
w->viewport->flags &= ~VIEWPORT_FOCUS_TYPE_SPRITE;
|
||||
// This is incorrect
|
||||
w->viewport->flags &= ~VIEWPORT_FLAG_GRIDLINES;
|
||||
break;
|
||||
case TitleScript::Speed:
|
||||
_command.Speed = 1;
|
||||
|
|
|
@ -76,7 +76,8 @@ public:
|
|||
enabled_widgets = (1ULL << WIDX_CLOSE) | (1ULL << WIDX_ZOOM_IN) | (1ULL << WIDX_ZOOM_OUT) | (1ULL << WIDX_LOCATE);
|
||||
|
||||
// Create viewport
|
||||
viewport_create(this, windowPos, width, height, 0, TileCoordsXYZ(128, 128, 0).ToCoordsXYZ(), 1, SPRITE_INDEX_NULL);
|
||||
const auto focus = Focus2(TileCoordsXYZ(128, 128, 0).ToCoordsXYZ());
|
||||
viewport_create(this, windowPos, width, height, focus);
|
||||
if (viewport == nullptr)
|
||||
{
|
||||
Close();
|
||||
|
|
|
@ -117,6 +117,30 @@ std::optional<ScreenCoordsXY> centre_2d_coordinates(const CoordsXYZ& loc, rct_vi
|
|||
return { screenCoord };
|
||||
}
|
||||
|
||||
CoordsXYZ Focus2::GetPos() const
|
||||
{
|
||||
return std::visit(
|
||||
[](auto&& arg) {
|
||||
using T = std::decay_t<decltype(arg)>;
|
||||
if constexpr (std::is_same_v<T, Focus2::CoordinateFocus>)
|
||||
return arg;
|
||||
else if constexpr (std::is_same_v<T, Focus2::EntityFocus>)
|
||||
{
|
||||
auto* centreEntity = GetEntity(arg);
|
||||
if (centreEntity != nullptr)
|
||||
{
|
||||
return CoordsXYZ{ centreEntity->x, centreEntity->y, centreEntity->z };
|
||||
}
|
||||
else
|
||||
{
|
||||
log_error("Invalid entity for focus.");
|
||||
return CoordsXYZ{};
|
||||
}
|
||||
}
|
||||
},
|
||||
data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Viewport will look at sprite or at coordinates as specified in flags 0b_1X
|
||||
* for sprite 0b_0X for coordinates
|
||||
|
@ -134,9 +158,7 @@ std::optional<ScreenCoordsXY> centre_2d_coordinates(const CoordsXYZ& loc, rct_vi
|
|||
* 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, int32_t zoom, CoordsXYZ centrePos,
|
||||
char flags, uint16_t sprite)
|
||||
void viewport_create(rct_window* w, const ScreenCoordsXY& screenCoords, int32_t width, int32_t height, const Focus2& focus)
|
||||
{
|
||||
rct_viewport* viewport = nullptr;
|
||||
if (_viewports.size() >= MAX_VIEWPORT_COUNT)
|
||||
|
@ -151,11 +173,7 @@ void viewport_create(
|
|||
viewport->pos = screenCoords;
|
||||
viewport->width = width;
|
||||
viewport->height = height;
|
||||
|
||||
if (!(flags & VIEWPORT_FOCUS_TYPE_COORDINATE))
|
||||
{
|
||||
zoom = 0;
|
||||
}
|
||||
const auto zoom = focus.zoom;
|
||||
|
||||
viewport->view_width = width << zoom;
|
||||
viewport->view_height = height << zoom;
|
||||
|
@ -166,24 +184,16 @@ void viewport_create(
|
|||
viewport->flags |= VIEWPORT_FLAG_GRIDLINES;
|
||||
w->viewport = viewport;
|
||||
|
||||
if (flags & VIEWPORT_FOCUS_TYPE_SPRITE)
|
||||
{
|
||||
w->viewport_target_sprite = sprite;
|
||||
auto* centreEntity = GetEntity(sprite);
|
||||
if (centreEntity != nullptr)
|
||||
{
|
||||
centrePos = { centreEntity->x, centreEntity->y, centreEntity->z };
|
||||
}
|
||||
else
|
||||
{
|
||||
log_error("Invalid entity for viewport.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
w->viewport_target_sprite = SPRITE_INDEX_NULL;
|
||||
}
|
||||
CoordsXYZ centrePos = focus.GetPos();
|
||||
w->viewport_target_sprite = std::visit(
|
||||
[](auto&& arg) {
|
||||
using T = std::decay_t<decltype(arg)>;
|
||||
if constexpr (std::is_same_v<T, Focus2::CoordinateFocus>)
|
||||
return SPRITE_INDEX_NULL;
|
||||
else if constexpr (std::is_same_v<T, Focus2::EntityFocus>)
|
||||
return arg;
|
||||
},
|
||||
focus.data);
|
||||
|
||||
auto centreLoc = centre_2d_coordinates(centrePos, viewport);
|
||||
if (!centreLoc.has_value())
|
||||
|
@ -692,24 +702,23 @@ 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->viewport_focus_sprite.sprite_id = window->viewport_smart_follow_sprite;
|
||||
window->focus2 = Focus2(window->viewport_smart_follow_sprite);
|
||||
window->viewport_target_sprite = window->viewport_smart_follow_sprite;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
viewport_focus viewport_update_smart_guest_follow(rct_window* window, const Guest* peep)
|
||||
void viewport_update_smart_guest_follow(rct_window* window, const Guest* peep)
|
||||
{
|
||||
viewport_focus focus{};
|
||||
focus.type = VIEWPORT_FOCUS_TYPE_SPRITE;
|
||||
focus.sprite.sprite_id = peep->sprite_index;
|
||||
Focus2 focus = Focus2(peep->sprite_index);
|
||||
window->viewport_target_sprite = peep->sprite_index;
|
||||
|
||||
if (peep->State == PeepState::Picked)
|
||||
{
|
||||
focus.sprite.sprite_id = SPRITE_INDEX_NULL;
|
||||
window->viewport_smart_follow_sprite = SPRITE_INDEX_NULL;
|
||||
window->viewport_target_sprite = SPRITE_INDEX_NULL;
|
||||
return focus;
|
||||
window->focus2 = std::nullopt; // No focus
|
||||
return;
|
||||
}
|
||||
|
||||
bool overallFocus = true;
|
||||
|
@ -725,8 +734,9 @@ viewport_focus viewport_update_smart_guest_follow(rct_window* window, const Gues
|
|||
const auto car = train->GetCar(peep->CurrentCar);
|
||||
if (car != nullptr)
|
||||
{
|
||||
focus.sprite.sprite_id = car->sprite_index;
|
||||
focus = Focus2(car->sprite_index);
|
||||
overallFocus = false;
|
||||
window->viewport_target_sprite = car->sprite_index;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -738,51 +748,36 @@ viewport_focus viewport_update_smart_guest_follow(rct_window* window, const Gues
|
|||
if (ride != nullptr)
|
||||
{
|
||||
auto xy = ride->overall_view.ToTileCentre();
|
||||
focus.type = VIEWPORT_FOCUS_TYPE_COORDINATE;
|
||||
focus.coordinate.x = xy.x;
|
||||
focus.coordinate.y = xy.y;
|
||||
focus.coordinate.z = tile_element_height(xy) + (4 * COORDS_Z_STEP);
|
||||
focus.sprite.type |= VIEWPORT_FOCUS_TYPE_COORDINATE;
|
||||
CoordsXYZ coordFocus;
|
||||
coordFocus.x = xy.x;
|
||||
coordFocus.y = xy.y;
|
||||
coordFocus.z = tile_element_height(xy) + (4 * COORDS_Z_STEP);
|
||||
focus = Focus2(coordFocus);
|
||||
window->viewport_target_sprite = SPRITE_INDEX_NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
focus.sprite.type |= VIEWPORT_FOCUS_TYPE_SPRITE | VIEWPORT_FOCUS_TYPE_COORDINATE;
|
||||
focus.sprite.pad_486 &= 0xFFFF;
|
||||
}
|
||||
focus.coordinate.rotation = get_current_rotation();
|
||||
|
||||
window->viewport_focus_sprite = focus.sprite;
|
||||
window->viewport_target_sprite = window->viewport_focus_sprite.sprite_id;
|
||||
return focus;
|
||||
window->focus2 = focus;
|
||||
}
|
||||
|
||||
void viewport_update_smart_staff_follow(rct_window* window, const Staff* peep)
|
||||
{
|
||||
sprite_focus focus = {};
|
||||
|
||||
focus.sprite_id = window->viewport_smart_follow_sprite;
|
||||
|
||||
if (peep->State == PeepState::Picked)
|
||||
{
|
||||
window->viewport_smart_follow_sprite = SPRITE_INDEX_NULL;
|
||||
window->viewport_target_sprite = SPRITE_INDEX_NULL;
|
||||
window->focus2 = std::nullopt;
|
||||
return;
|
||||
}
|
||||
|
||||
focus.type |= VIEWPORT_FOCUS_TYPE_SPRITE | VIEWPORT_FOCUS_TYPE_COORDINATE;
|
||||
|
||||
window->viewport_focus_sprite = focus;
|
||||
window->viewport_target_sprite = window->viewport_focus_sprite.sprite_id;
|
||||
window->focus2 = Focus2(window->viewport_smart_follow_sprite);
|
||||
window->viewport_target_sprite = window->viewport_smart_follow_sprite;
|
||||
}
|
||||
|
||||
void viewport_update_smart_vehicle_follow(rct_window* window)
|
||||
{
|
||||
sprite_focus focus = {};
|
||||
focus.sprite_id = window->viewport_smart_follow_sprite;
|
||||
|
||||
window->viewport_focus_sprite = focus;
|
||||
window->viewport_target_sprite = window->viewport_focus_sprite.sprite_id;
|
||||
window->focus2 = Focus2(window->viewport_smart_follow_sprite);
|
||||
window->viewport_target_sprite = window->viewport_smart_follow_sprite;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -104,15 +104,13 @@ 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, int32_t zoom, CoordsXYZ centrePos,
|
||||
char flags, uint16_t sprite);
|
||||
void viewport_create(rct_window* w, const ScreenCoordsXY& screenCoords, int32_t width, int32_t height, const Focus2& 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);
|
||||
void viewport_update_sprite_follow(rct_window* window);
|
||||
void viewport_update_smart_sprite_follow(rct_window* window);
|
||||
viewport_focus viewport_update_smart_guest_follow(rct_window* window, const Guest* peep);
|
||||
void viewport_update_smart_guest_follow(rct_window* window, const Guest* peep);
|
||||
void viewport_update_smart_staff_follow(rct_window* window, const Staff* peep);
|
||||
void viewport_update_smart_vehicle_follow(rct_window* window);
|
||||
void viewport_render(
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include <limits>
|
||||
#include <list>
|
||||
#include <memory>
|
||||
#include <variant>
|
||||
|
||||
struct rct_drawpixelinfo;
|
||||
struct rct_window;
|
||||
|
@ -194,51 +195,34 @@ struct rct_scroll
|
|||
|
||||
constexpr auto WINDOW_SCROLL_UNDEFINED = std::numeric_limits<uint16_t>::max();
|
||||
|
||||
/**
|
||||
* Viewport focus structure.
|
||||
* size: 0xA
|
||||
* Use sprite.type to work out type.
|
||||
*/
|
||||
struct coordinate_focus
|
||||
struct Focus2
|
||||
{
|
||||
int16_t var_480;
|
||||
int16_t x; // 0x482
|
||||
int16_t y; // 0x484 & VIEWPORT_FOCUS_Y_MASK
|
||||
int16_t z; // 0x486
|
||||
uint8_t rotation; // 0x488
|
||||
uint8_t zoom; // 0x489
|
||||
int16_t width;
|
||||
int16_t height;
|
||||
};
|
||||
using CoordinateFocus = CoordsXYZ;
|
||||
using EntityFocus = uint16_t;
|
||||
|
||||
// Type is viewport_target_sprite_id & 0x80000000 != 0
|
||||
struct sprite_focus
|
||||
{
|
||||
int16_t var_480;
|
||||
uint16_t sprite_id; // 0x482
|
||||
uint8_t pad_484;
|
||||
uint8_t type; // 0x485 & VIEWPORT_FOCUS_TYPE_MASK
|
||||
uint16_t pad_486;
|
||||
uint8_t rotation; // 0x488
|
||||
uint8_t zoom; // 0x489
|
||||
};
|
||||
uint8_t zoom = 0;
|
||||
std::variant<CoordinateFocus, EntityFocus> data;
|
||||
|
||||
#define VIEWPORT_FOCUS_TYPE_MASK 0xC0
|
||||
enum VIEWPORT_FOCUS_TYPE : uint8_t
|
||||
{
|
||||
VIEWPORT_FOCUS_TYPE_COORDINATE = (1 << 6),
|
||||
VIEWPORT_FOCUS_TYPE_SPRITE = (1 << 7)
|
||||
};
|
||||
#define VIEWPORT_FOCUS_Y_MASK 0x3FFF
|
||||
|
||||
struct viewport_focus
|
||||
{
|
||||
VIEWPORT_FOCUS_TYPE type{};
|
||||
union
|
||||
template<typename T> constexpr explicit Focus2(T newValue, uint8_t newZoom = 0)
|
||||
{
|
||||
sprite_focus sprite;
|
||||
coordinate_focus coordinate;
|
||||
};
|
||||
data = newValue;
|
||||
zoom = newZoom;
|
||||
}
|
||||
|
||||
CoordsXYZ GetPos() const;
|
||||
|
||||
constexpr bool operator==(const Focus2& other) const
|
||||
{
|
||||
if (zoom != other.zoom)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return data == other.data;
|
||||
}
|
||||
constexpr bool operator!=(const Focus2& other) const
|
||||
{
|
||||
return !(*this == other);
|
||||
}
|
||||
};
|
||||
|
||||
struct rct_window_event_list
|
||||
|
|
|
@ -12,28 +12,10 @@ void rct_window::SetLocation(const CoordsXYZ& coords)
|
|||
|
||||
void rct_window::ScrollToViewport()
|
||||
{
|
||||
// In original checked to make sure x and y were not -1 as well.
|
||||
if (viewport == nullptr || viewport_focus_coordinates.y == -1)
|
||||
if (viewport == nullptr || !focus2.has_value())
|
||||
return;
|
||||
|
||||
CoordsXYZ newCoords = {};
|
||||
if (viewport_focus_sprite.type & VIEWPORT_FOCUS_TYPE_SPRITE)
|
||||
{
|
||||
auto* sprite = GetEntity(viewport_focus_sprite.sprite_id);
|
||||
if (sprite == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
newCoords.x = sprite->x;
|
||||
newCoords.y = sprite->y;
|
||||
newCoords.z = sprite->z;
|
||||
}
|
||||
else
|
||||
{
|
||||
newCoords.x = viewport_focus_coordinates.x;
|
||||
newCoords.y = viewport_focus_coordinates.y & VIEWPORT_FOCUS_Y_MASK;
|
||||
newCoords.z = viewport_focus_coordinates.z;
|
||||
}
|
||||
CoordsXYZ newCoords = focus2.value().GetPos();
|
||||
|
||||
auto mainWindow = window_get_main();
|
||||
if (mainWindow != nullptr)
|
||||
|
|
|
@ -55,10 +55,9 @@ 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;
|
||||
union
|
||||
{
|
||||
coordinate_focus viewport_focus_coordinates;
|
||||
sprite_focus viewport_focus_sprite;
|
||||
campaign_variables campaign;
|
||||
new_ride_variables new_ride;
|
||||
news_variables news;
|
||||
|
|
Loading…
Reference in New Issue