mirror of https://github.com/OpenRCT2/OpenRCT2.git
Merge pull request #8837 from IntelOrca/fix/invalid-reads
Fix more of these backtrace reports
This commit is contained in:
commit
f4526dd2ae
|
@ -153,7 +153,7 @@ rct_window* window_banner_open(rct_windownumber number)
|
|||
viewportWidget = &window_banner_widgets[WIDX_VIEWPORT];
|
||||
viewport_create(
|
||||
w, w->x + viewportWidget->left + 1, w->y + viewportWidget->top + 1, (viewportWidget->right - viewportWidget->left) - 2,
|
||||
(viewportWidget->bottom - viewportWidget->top) - 2, 0, view_x, view_y, view_z, 0, -1);
|
||||
(viewportWidget->bottom - viewportWidget->top) - 2, 0, view_x, view_y, view_z, 0, SPRITE_INDEX_NULL);
|
||||
|
||||
w->viewport->flags = gConfigGeneral.always_show_gridlines ? VIEWPORT_FLAG_GRIDLINES : 0;
|
||||
window_invalidate(w);
|
||||
|
@ -345,7 +345,7 @@ static void window_banner_viewport_rotate(rct_window* w)
|
|||
rct_widget* viewportWidget = &window_banner_widgets[WIDX_VIEWPORT];
|
||||
viewport_create(
|
||||
w, w->x + viewportWidget->left + 1, w->y + viewportWidget->top + 1, (viewportWidget->right - viewportWidget->left) - 1,
|
||||
(viewportWidget->bottom - viewportWidget->top) - 1, 0, view_x, view_y, view_z, 0, -1);
|
||||
(viewportWidget->bottom - viewportWidget->top) - 1, 0, view_x, view_y, view_z, 0, SPRITE_INDEX_NULL);
|
||||
|
||||
w->viewport->flags = gConfigGeneral.always_show_gridlines ? VIEWPORT_FLAG_GRIDLINES : 0;
|
||||
window_invalidate(w);
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include <openrct2/Context.h>
|
||||
#include <openrct2/localisation/StringIds.h>
|
||||
#include <openrct2/world/Footpath.h>
|
||||
#include <openrct2/world/Sprite.h>
|
||||
|
||||
static void window_editor_main_paint(rct_window* w, rct_drawpixelinfo* dpi);
|
||||
|
||||
|
@ -65,7 +66,7 @@ rct_window* window_editor_main_open()
|
|||
WC_MAIN_WINDOW, WF_STICK_TO_BACK);
|
||||
window->widgets = window_editor_main_widgets;
|
||||
|
||||
viewport_create(window, window->x, window->y, window->width, window->height, 0, 0x0FFF, 0x0FFF, 0, 0x1, -1);
|
||||
viewport_create(window, window->x, window->y, window->width, window->height, 0, 0x0FFF, 0x0FFF, 0, 0x1, SPRITE_INDEX_NULL);
|
||||
window->viewport->flags |= 0x0400;
|
||||
|
||||
gCurrentRotation = 0;
|
||||
|
|
|
@ -563,9 +563,6 @@ static void window_footpath_update(rct_window* w)
|
|||
*/
|
||||
static void window_footpath_invalidate(rct_window* w)
|
||||
{
|
||||
int32_t selectedPath;
|
||||
PathSurfaceEntry* pathType;
|
||||
|
||||
// Press / unpress footpath and queue type buttons
|
||||
w->pressed_widgets &= ~(1 << WIDX_FOOTPATH_TYPE);
|
||||
w->pressed_widgets &= ~(1 << WIDX_QUEUELINE_TYPE);
|
||||
|
@ -578,12 +575,15 @@ static void window_footpath_invalidate(rct_window* w)
|
|||
: WWT_EMPTY;
|
||||
|
||||
// Set footpath and queue type button images
|
||||
selectedPath = gFootpathSelectedId;
|
||||
pathType = get_path_surface_entry(selectedPath);
|
||||
|
||||
int32_t pathImage = pathType->preview;
|
||||
// Editor-only paths might lack a queue image
|
||||
int32_t queueImage = (pathType->flags & FOOTPATH_ENTRY_FLAG_SHOW_ONLY_IN_SCENARIO_EDITOR) ? pathImage : pathImage + 1;
|
||||
auto pathImage = (uint32_t)SPR_NONE;
|
||||
auto queueImage = (uint32_t)SPR_NONE;
|
||||
auto pathEntry = get_path_surface_entry(gFootpathSelectedId);
|
||||
if (pathEntry != nullptr)
|
||||
{
|
||||
pathImage = pathEntry->preview;
|
||||
// Editor-only paths might lack a queue image
|
||||
queueImage = (pathEntry->flags & FOOTPATH_ENTRY_FLAG_SHOW_ONLY_IN_SCENARIO_EDITOR) ? pathImage : pathImage + 1;
|
||||
}
|
||||
window_footpath_widgets[WIDX_FOOTPATH_TYPE].image = pathImage;
|
||||
window_footpath_widgets[WIDX_QUEUELINE_TYPE].image = queueImage;
|
||||
}
|
||||
|
|
|
@ -701,98 +701,38 @@ void window_guest_viewport_init(rct_window* w)
|
|||
if (w->page != WINDOW_GUEST_OVERVIEW)
|
||||
return;
|
||||
|
||||
union
|
||||
auto peep = GET_PEEP(w->number);
|
||||
if (peep != nullptr)
|
||||
{
|
||||
sprite_focus sprite;
|
||||
coordinate_focus coordinate;
|
||||
} focus = {}; // The focus will be either a sprite or a coordinate.
|
||||
|
||||
focus.sprite.sprite_id = w->number;
|
||||
|
||||
Peep* peep = GET_PEEP(w->number);
|
||||
|
||||
if (peep->state == PEEP_STATE_PICKED)
|
||||
{
|
||||
focus.sprite.sprite_id = SPRITE_INDEX_NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
uint8_t final_check = 1;
|
||||
if (peep->state == PEEP_STATE_ON_RIDE || peep->state == PEEP_STATE_ENTERING_RIDE
|
||||
|| (peep->state == PEEP_STATE_LEAVING_RIDE && peep->x == LOCATION_NULL))
|
||||
auto focus = viewport_update_smart_guest_follow(w, peep);
|
||||
bool reCreateViewport = false;
|
||||
uint16_t origViewportFlags{};
|
||||
if (w->viewport != nullptr)
|
||||
{
|
||||
Ride* ride = get_ride(peep->current_ride);
|
||||
if (ride->lifecycle_flags & RIDE_LIFECYCLE_ON_TRACK)
|
||||
{
|
||||
rct_vehicle* train = GET_VEHICLE(ride->vehicles[peep->current_train]);
|
||||
int32_t car = peep->current_car;
|
||||
// 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)
|
||||
return;
|
||||
|
||||
for (; car != 0; car--)
|
||||
{
|
||||
train = GET_VEHICLE(train->next_vehicle_on_train);
|
||||
}
|
||||
origViewportFlags = w->viewport->flags;
|
||||
|
||||
focus.sprite.sprite_id = train->sprite_index;
|
||||
final_check = 0;
|
||||
}
|
||||
reCreateViewport = true;
|
||||
w->viewport->width = 0;
|
||||
w->viewport = nullptr;
|
||||
}
|
||||
if (peep->x == LOCATION_NULL && final_check)
|
||||
|
||||
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 != PEEP_STATE_PICKED && w->viewport == nullptr)
|
||||
{
|
||||
Ride* ride = get_ride(peep->current_ride);
|
||||
int32_t x = ride->overall_view.x * 32 + 16;
|
||||
int32_t y = ride->overall_view.y * 32 + 16;
|
||||
int32_t height = tile_element_height(x, y);
|
||||
height += 32;
|
||||
focus.coordinate.x = x;
|
||||
focus.coordinate.y = y;
|
||||
focus.coordinate.z = height;
|
||||
focus.sprite.type |= VIEWPORT_FOCUS_TYPE_COORDINATE;
|
||||
}
|
||||
else
|
||||
{
|
||||
focus.sprite.type |= VIEWPORT_FOCUS_TYPE_SPRITE | VIEWPORT_FOCUS_TYPE_COORDINATE;
|
||||
focus.sprite.pad_486 &= 0xFFFF;
|
||||
}
|
||||
focus.coordinate.rotation = get_current_rotation();
|
||||
}
|
||||
|
||||
uint16_t viewport_flags;
|
||||
|
||||
if (w->viewport)
|
||||
{
|
||||
// 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)
|
||||
return;
|
||||
|
||||
viewport_flags = w->viewport->flags;
|
||||
w->viewport->width = 0;
|
||||
w->viewport = nullptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
viewport_flags = 0;
|
||||
if (gConfigGeneral.always_show_gridlines)
|
||||
{
|
||||
viewport_flags |= VIEWPORT_FLAG_GRIDLINES;
|
||||
}
|
||||
}
|
||||
|
||||
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 != PEEP_STATE_PICKED)
|
||||
{
|
||||
if (!(w->viewport))
|
||||
{
|
||||
rct_widget* view_widget = &w->widgets[WIDX_VIEWPORT];
|
||||
|
||||
auto view_widget = &w->widgets[WIDX_VIEWPORT];
|
||||
int32_t x = view_widget->left + 1 + w->x;
|
||||
int32_t y = view_widget->top + 1 + w->y;
|
||||
int32_t width = view_widget->right - view_widget->left - 1;
|
||||
|
@ -801,15 +741,15 @@ void window_guest_viewport_init(rct_window* w)
|
|||
viewport_create(
|
||||
w, x, y, 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);
|
||||
|
||||
if (w->viewport != nullptr && reCreateViewport)
|
||||
{
|
||||
w->viewport->flags = origViewportFlags;
|
||||
}
|
||||
w->flags |= WF_NO_SCROLLING;
|
||||
window_invalidate(w);
|
||||
}
|
||||
window_invalidate(w);
|
||||
}
|
||||
|
||||
if (w->viewport)
|
||||
w->viewport->flags = viewport_flags;
|
||||
window_invalidate(w);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include <openrct2/Context.h>
|
||||
#include <openrct2/localisation/StringIds.h>
|
||||
#include <openrct2/world/Footpath.h>
|
||||
#include <openrct2/world/Sprite.h>
|
||||
|
||||
// clang-format off
|
||||
static rct_widget window_main_widgets[] = {
|
||||
|
@ -67,7 +68,7 @@ rct_window* window_main_open()
|
|||
WF_STICK_TO_BACK);
|
||||
window->widgets = window_main_widgets;
|
||||
|
||||
viewport_create(window, window->x, window->y, window->width, window->height, 0, 0x0FFF, 0x0FFF, 0, 0x1, -1);
|
||||
viewport_create(window, window->x, window->y, window->width, window->height, 0, 0x0FFF, 0x0FFF, 0, 0x1, SPRITE_INDEX_NULL);
|
||||
window->viewport->flags |= VIEWPORT_FLAG_SOUND_ON;
|
||||
gCurrentRotation = 0;
|
||||
gShowGridLinesRefCount = 0;
|
||||
|
|
|
@ -923,7 +923,7 @@ static void window_park_init_viewport(rct_window* w)
|
|||
viewport_create(
|
||||
w, w->x + viewportWidget->left + 1, w->y + viewportWidget->top + 1,
|
||||
(viewportWidget->right - viewportWidget->left) - 1, (viewportWidget->bottom - viewportWidget->top) - 1, 0, x, y,
|
||||
z, w->viewport_focus_sprite.type & VIEWPORT_FOCUS_TYPE_MASK, -1);
|
||||
z, w->viewport_focus_sprite.type & VIEWPORT_FOCUS_TYPE_MASK, SPRITE_INDEX_NULL);
|
||||
w->flags |= (1 << 2);
|
||||
window_invalidate(w);
|
||||
}
|
||||
|
|
|
@ -565,7 +565,7 @@ static void window_player_set_page(rct_window* w, int32_t page)
|
|||
{
|
||||
if (w->viewport == nullptr)
|
||||
{
|
||||
viewport_create(w, w->x, w->y, w->width, w->height, 0, 128 * 32, 128 * 32, 0, 1, -1);
|
||||
viewport_create(w, w->x, w->y, w->width, w->height, 0, 128 * 32, 128 * 32, 0, 1, SPRITE_INDEX_NULL);
|
||||
w->flags |= WF_NO_SCROLLING;
|
||||
window_event_invalidate_call(w);
|
||||
window_player_update_viewport(w, false);
|
||||
|
|
|
@ -188,7 +188,7 @@ rct_window* window_sign_open(rct_windownumber number)
|
|||
viewportWidget = &window_sign_widgets[WIDX_VIEWPORT];
|
||||
viewport_create(
|
||||
w, w->x + viewportWidget->left + 1, w->y + viewportWidget->top + 1, (viewportWidget->right - viewportWidget->left) - 1,
|
||||
(viewportWidget->bottom - viewportWidget->top) - 1, 0, view_x, view_y, view_z, 0, -1);
|
||||
(viewportWidget->bottom - viewportWidget->top) - 1, 0, view_x, view_y, view_z, 0, SPRITE_INDEX_NULL);
|
||||
|
||||
w->viewport->flags = gConfigGeneral.always_show_gridlines ? VIEWPORT_FLAG_GRIDLINES : 0;
|
||||
window_invalidate(w);
|
||||
|
@ -381,7 +381,7 @@ static void window_sign_viewport_rotate(rct_window* w)
|
|||
rct_widget* viewportWidget = &window_sign_widgets[WIDX_VIEWPORT];
|
||||
viewport_create(
|
||||
w, w->x + viewportWidget->left + 1, w->y + viewportWidget->top + 1, (viewportWidget->right - viewportWidget->left) - 1,
|
||||
(viewportWidget->bottom - viewportWidget->top) - 1, 0, view_x, view_y, view_z, 0, -1);
|
||||
(viewportWidget->bottom - viewportWidget->top) - 1, 0, view_x, view_y, view_z, 0, SPRITE_INDEX_NULL);
|
||||
|
||||
w->viewport->flags = gConfigGeneral.always_show_gridlines ? VIEWPORT_FLAG_GRIDLINES : 0;
|
||||
window_invalidate(w);
|
||||
|
@ -445,7 +445,7 @@ rct_window* window_sign_small_open(rct_windownumber number)
|
|||
viewportWidget = &window_sign_widgets[WIDX_VIEWPORT];
|
||||
viewport_create(
|
||||
w, w->x + viewportWidget->left + 1, w->y + viewportWidget->top + 1, (viewportWidget->right - viewportWidget->left) - 1,
|
||||
(viewportWidget->bottom - viewportWidget->top) - 1, 0, view_x, view_y, view_z, 0, -1);
|
||||
(viewportWidget->bottom - viewportWidget->top) - 1, 0, view_x, view_y, view_z, 0, SPRITE_INDEX_NULL);
|
||||
|
||||
w->viewport->flags = gConfigGeneral.always_show_gridlines ? VIEWPORT_FLAG_GRIDLINES : 0;
|
||||
w->flags |= WF_NO_SCROLLING;
|
||||
|
|
|
@ -251,7 +251,8 @@ void window_title_command_editor_open(TitleSequence* sequence, int32_t index, bo
|
|||
rct_widget* const viewportWidget = &window_title_command_editor_widgets[WIDX_VIEWPORT];
|
||||
viewport_create(
|
||||
window, window->x + viewportWidget->left + 1, window->y + viewportWidget->top + 1,
|
||||
viewportWidget->right - viewportWidget->left - 1, viewportWidget->bottom - viewportWidget->top - 1, 0, 0, 0, 0, 0, -1);
|
||||
viewportWidget->right - viewportWidget->left - 1, viewportWidget->bottom - viewportWidget->top - 1, 0, 0, 0, 0, 0,
|
||||
SPRITE_INDEX_NULL);
|
||||
|
||||
_window_title_command_editor_index = index;
|
||||
_window_title_command_editor_insert = insert;
|
||||
|
|
|
@ -94,7 +94,7 @@ rct_window* window_viewport_open()
|
|||
w->number = _viewportNumber++;
|
||||
|
||||
// Create viewport
|
||||
viewport_create(w, w->x, w->y, w->width, w->height, 0, 128 * 32, 128 * 32, 0, 1, -1);
|
||||
viewport_create(w, w->x, w->y, w->width, w->height, 0, 128 * 32, 128 * 32, 0, 1, SPRITE_INDEX_NULL);
|
||||
rct_window* mainWindow = window_get_main();
|
||||
if (mainWindow != nullptr)
|
||||
{
|
||||
|
|
|
@ -145,7 +145,7 @@ void centre_2d_coordinates(int32_t x, int32_t y, int32_t z, int32_t* out_x, int3
|
|||
*/
|
||||
void viewport_create(
|
||||
rct_window* w, int32_t x, int32_t y, int32_t width, int32_t height, int32_t zoom, int32_t centre_x, int32_t centre_y,
|
||||
int32_t centre_z, char flags, int16_t sprite)
|
||||
int32_t centre_z, char flags, uint16_t sprite)
|
||||
{
|
||||
rct_viewport* viewport = nullptr;
|
||||
for (int32_t i = 0; i < MAX_VIEWPORT_COUNT; i++)
|
||||
|
@ -686,55 +686,53 @@ void viewport_update_smart_sprite_follow(rct_window* window)
|
|||
}
|
||||
}
|
||||
|
||||
void viewport_update_smart_guest_follow(rct_window* window, Peep* peep)
|
||||
viewport_focus viewport_update_smart_guest_follow(rct_window* window, Peep* peep)
|
||||
{
|
||||
union
|
||||
{
|
||||
sprite_focus sprite;
|
||||
coordinate_focus coordinate;
|
||||
} focus = {}; // The focus will be either a sprite or a coordinate.
|
||||
|
||||
focus.sprite.sprite_id = window->viewport_smart_follow_sprite;
|
||||
viewport_focus focus{};
|
||||
focus.type = VIEWPORT_FOCUS_TYPE_SPRITE;
|
||||
focus.sprite.sprite_id = peep->sprite_index;
|
||||
|
||||
if (peep->state == PEEP_STATE_PICKED)
|
||||
{
|
||||
// focus.sprite.sprite_id = SPRITE_INDEX_NULL;
|
||||
focus.sprite.sprite_id = SPRITE_INDEX_NULL;
|
||||
window->viewport_smart_follow_sprite = SPRITE_INDEX_NULL;
|
||||
window->viewport_target_sprite = SPRITE_INDEX_NULL;
|
||||
return;
|
||||
return focus;
|
||||
}
|
||||
else
|
||||
{
|
||||
uint8_t final_check = 1;
|
||||
bool overallFocus = true;
|
||||
if (peep->state == PEEP_STATE_ON_RIDE || peep->state == PEEP_STATE_ENTERING_RIDE
|
||||
|| (peep->state == PEEP_STATE_LEAVING_RIDE && peep->x == LOCATION_NULL))
|
||||
{
|
||||
Ride* ride = get_ride(peep->current_ride);
|
||||
if (ride->lifecycle_flags & RIDE_LIFECYCLE_ON_TRACK)
|
||||
{
|
||||
rct_vehicle* train = GET_VEHICLE(ride->vehicles[peep->current_train]);
|
||||
int32_t car = peep->current_car;
|
||||
|
||||
for (; car != 0; car--)
|
||||
auto train = GET_VEHICLE(ride->vehicles[peep->current_train]);
|
||||
if (train != nullptr)
|
||||
{
|
||||
train = GET_VEHICLE(train->next_vehicle_on_train);
|
||||
auto car = train->GetCar(peep->current_car);
|
||||
if (car != nullptr)
|
||||
{
|
||||
focus.sprite.sprite_id = car->sprite_index;
|
||||
overallFocus = false;
|
||||
}
|
||||
}
|
||||
|
||||
focus.sprite.sprite_id = train->sprite_index;
|
||||
final_check = 0;
|
||||
}
|
||||
}
|
||||
if (peep->x == LOCATION_NULL && final_check)
|
||||
if (peep->x == LOCATION_NULL && overallFocus)
|
||||
{
|
||||
Ride* ride = get_ride(peep->current_ride);
|
||||
int32_t x = ride->overall_view.x * 32 + 16;
|
||||
int32_t y = ride->overall_view.y * 32 + 16;
|
||||
int32_t height = tile_element_height(x, y);
|
||||
height += 32;
|
||||
focus.coordinate.x = x;
|
||||
focus.coordinate.y = y;
|
||||
focus.coordinate.z = height;
|
||||
focus.sprite.type |= VIEWPORT_FOCUS_TYPE_COORDINATE;
|
||||
auto ride = get_ride(peep->current_ride);
|
||||
if (ride != nullptr)
|
||||
{
|
||||
auto x = (int32_t)ride->overall_view.x * 32 + 16;
|
||||
auto y = (int32_t)ride->overall_view.y * 32 + 16;
|
||||
focus.type = VIEWPORT_FOCUS_TYPE_COORDINATE;
|
||||
focus.coordinate.x = x;
|
||||
focus.coordinate.y = y;
|
||||
focus.coordinate.z = tile_element_height(x, y) + 32;
|
||||
focus.sprite.type |= VIEWPORT_FOCUS_TYPE_COORDINATE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -746,6 +744,7 @@ void viewport_update_smart_guest_follow(rct_window* window, Peep* peep)
|
|||
|
||||
window->viewport_focus_sprite = focus.sprite;
|
||||
window->viewport_target_sprite = window->viewport_focus_sprite.sprite_id;
|
||||
return focus;
|
||||
}
|
||||
|
||||
void viewport_update_smart_staff_follow(rct_window* window, Peep* peep)
|
||||
|
|
|
@ -122,11 +122,11 @@ void viewport_init_all();
|
|||
void centre_2d_coordinates(int32_t x, int32_t y, int32_t z, int32_t* out_x, int32_t* out_y, rct_viewport* viewport);
|
||||
void viewport_create(
|
||||
rct_window* w, int32_t x, int32_t y, int32_t width, int32_t height, int32_t zoom, int32_t centre_x, int32_t centre_y,
|
||||
int32_t centre_z, char flags, int16_t sprite);
|
||||
int32_t centre_z, char flags, uint16_t sprite);
|
||||
void viewport_update_position(rct_window* window);
|
||||
void viewport_update_sprite_follow(rct_window* window);
|
||||
void viewport_update_smart_sprite_follow(rct_window* window);
|
||||
void viewport_update_smart_guest_follow(rct_window* window, Peep* peep);
|
||||
viewport_focus viewport_update_smart_guest_follow(rct_window* window, Peep* peep);
|
||||
void viewport_update_smart_staff_follow(rct_window* window, Peep* peep);
|
||||
void viewport_update_smart_vehicle_follow(rct_window* window);
|
||||
void viewport_render(
|
||||
|
|
|
@ -148,13 +148,23 @@ struct sprite_focus
|
|||
};
|
||||
|
||||
#define VIEWPORT_FOCUS_TYPE_MASK 0xC0
|
||||
enum
|
||||
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
|
||||
{
|
||||
sprite_focus sprite;
|
||||
coordinate_focus coordinate;
|
||||
};
|
||||
};
|
||||
|
||||
struct rct_window_event_list
|
||||
{
|
||||
void (*close)(struct rct_window*);
|
||||
|
|
|
@ -4389,11 +4389,14 @@ void Guest::UpdateRideApproachExitWaypoints()
|
|||
|
||||
int16_t shift_multiplier = 20;
|
||||
|
||||
rct_ride_entry* ride_type = get_ride_entry(ride->subtype);
|
||||
rct_ride_entry_vehicle* vehicle_entry = &ride_type->vehicles[ride_type->default_vehicle];
|
||||
if (vehicle_entry->flags & (VEHICLE_ENTRY_FLAG_CHAIRLIFT | VEHICLE_ENTRY_FLAG_GO_KART))
|
||||
auto rideEntry = get_ride_entry(ride->subtype);
|
||||
if (rideEntry != nullptr)
|
||||
{
|
||||
shift_multiplier = 32;
|
||||
auto vehicleEntry = &rideEntry->vehicles[rideEntry->default_vehicle];
|
||||
if (vehicleEntry->flags & (VEHICLE_ENTRY_FLAG_CHAIRLIFT | VEHICLE_ENTRY_FLAG_GO_KART))
|
||||
{
|
||||
shift_multiplier = 32;
|
||||
}
|
||||
}
|
||||
|
||||
x_shift *= shift_multiplier;
|
||||
|
|
|
@ -10002,3 +10002,13 @@ const rct_vehicle* rct_vehicle::GetHead() const
|
|||
{
|
||||
return ((rct_vehicle*)this)->GetHead();
|
||||
}
|
||||
|
||||
const rct_vehicle* rct_vehicle::GetCar(size_t carIndex) const
|
||||
{
|
||||
auto car = this;
|
||||
for (; carIndex != 0; carIndex--)
|
||||
{
|
||||
car = GET_VEHICLE(car->next_vehicle_on_train);
|
||||
}
|
||||
return car;
|
||||
}
|
||||
|
|
|
@ -233,6 +233,7 @@ struct rct_vehicle : rct_sprite_common
|
|||
}
|
||||
rct_vehicle* GetHead();
|
||||
const rct_vehicle* GetHead() const;
|
||||
const rct_vehicle* GetCar(size_t carIndex) const;
|
||||
};
|
||||
|
||||
struct train_ref
|
||||
|
|
|
@ -80,6 +80,10 @@ rct_sprite* try_get_sprite(size_t spriteIndex)
|
|||
|
||||
rct_sprite* get_sprite(size_t sprite_idx)
|
||||
{
|
||||
if (sprite_idx == SPRITE_INDEX_NULL)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
openrct2_assert(sprite_idx < MAX_SPRITES, "Tried getting sprite %u", sprite_idx);
|
||||
return &_spriteList[sprite_idx];
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue