mirror of https://github.com/OpenRCT2/OpenRCT2.git
Refactor centre_2d_coordinates to use screenCoords.
This commit is contained in:
parent
463ef9d218
commit
d4c15cd774
|
@ -648,24 +648,26 @@ static void window_player_update_viewport(rct_window* w, bool scroll)
|
||||||
LocationXYZ16 coord = network_get_player_last_action_coord(playerIndex);
|
LocationXYZ16 coord = network_get_player_last_action_coord(playerIndex);
|
||||||
if (coord.x != 0 || coord.y != 0 || coord.z != 0)
|
if (coord.x != 0 || coord.y != 0 || coord.z != 0)
|
||||||
{
|
{
|
||||||
int32_t viewX, viewY;
|
auto centreLoc = centre_2d_coordinates({ coord.x, coord.y, coord.z }, viewport);
|
||||||
centre_2d_coordinates(coord.x, coord.y, coord.z, &viewX, &viewY, viewport);
|
if (!centreLoc)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
// Don't scroll if the view was originally undefined
|
// Don't scroll if the view was originally undefined
|
||||||
if (w->var_492 == -1)
|
if (w->var_492 == -1)
|
||||||
{
|
{
|
||||||
scroll = false;
|
scroll = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!scroll || w->saved_view_x != viewX || w->saved_view_y != viewY)
|
if (!scroll || w->saved_view_x != centreLoc->x || w->saved_view_y != centreLoc->y)
|
||||||
{
|
{
|
||||||
w->flags |= WF_SCROLLING_TO_LOCATION;
|
w->flags |= WF_SCROLLING_TO_LOCATION;
|
||||||
w->saved_view_x = viewX;
|
w->saved_view_x = centreLoc->x;
|
||||||
w->saved_view_y = viewY;
|
w->saved_view_y = centreLoc->y;
|
||||||
if (!scroll)
|
if (!scroll)
|
||||||
{
|
{
|
||||||
w->viewport->view_x = viewX;
|
w->viewport->view_x = centreLoc->x;
|
||||||
w->viewport->view_y = viewY;
|
w->viewport->view_y = centreLoc->y;
|
||||||
}
|
}
|
||||||
widget_invalidate(w, WIDX_VIEWPORT);
|
widget_invalidate(w, WIDX_VIEWPORT);
|
||||||
}
|
}
|
||||||
|
|
|
@ -102,7 +102,6 @@ void viewport_init_all()
|
||||||
textinput_cancel();
|
textinput_cancel();
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Return ScreenCoords, takein CoordsXYZ
|
|
||||||
/**
|
/**
|
||||||
* Converts between 3d point of a sprite to 2d coordinates for centring on that
|
* Converts between 3d point of a sprite to 2d coordinates for centring on that
|
||||||
* sprite
|
* sprite
|
||||||
|
@ -113,26 +112,21 @@ void viewport_init_all()
|
||||||
* out_x : ax
|
* out_x : ax
|
||||||
* out_y : bx
|
* out_y : bx
|
||||||
*/
|
*/
|
||||||
void centre_2d_coordinates(int32_t x, int32_t y, int32_t z, int32_t* out_x, int32_t* out_y, rct_viewport* viewport)
|
std::optional<ScreenCoordsXY> centre_2d_coordinates(CoordsXYZ loc, rct_viewport* viewport)
|
||||||
{
|
{
|
||||||
int32_t start_x = x;
|
auto screenCoord = translate_3d_to_2d_with_z(get_current_rotation(), loc);
|
||||||
|
|
||||||
CoordsXYZ coord_3d = { x, y, z };
|
|
||||||
|
|
||||||
auto coord_2d = translate_3d_to_2d_with_z(get_current_rotation(), coord_3d);
|
|
||||||
|
|
||||||
// If the start location was invalid
|
// If the start location was invalid
|
||||||
// propagate the invalid location to the output.
|
// propagate the invalid location to the output.
|
||||||
// This fixes a bug that caused the game to enter an infinite loop.
|
// This fixes a bug that caused the game to enter an infinite loop.
|
||||||
if (start_x == LOCATION_NULL)
|
if (loc.x == LOCATION_NULL)
|
||||||
{
|
{
|
||||||
*out_x = LOCATION_NULL;
|
return std::nullopt;
|
||||||
*out_y = 0;
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
*out_x = coord_2d.x - viewport->view_width / 2;
|
screenCoord.x -= viewport->view_width / 2;
|
||||||
*out_y = coord_2d.y - viewport->view_height / 2;
|
screenCoord.y -= viewport->view_height / 2;
|
||||||
|
return { screenCoord };
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -203,13 +197,16 @@ void viewport_create(
|
||||||
w->viewport_target_sprite = SPRITE_INDEX_NULL;
|
w->viewport_target_sprite = SPRITE_INDEX_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t view_x, view_y;
|
auto centreLoc = centre_2d_coordinates({ centre_x, centre_y, centre_z }, viewport);
|
||||||
centre_2d_coordinates(centre_x, centre_y, centre_z, &view_x, &view_y, viewport);
|
if (!centreLoc)
|
||||||
|
{
|
||||||
w->saved_view_x = view_x;
|
log_error("Invalid location for viewport.");
|
||||||
w->saved_view_y = view_y;
|
return;
|
||||||
viewport->view_x = view_x;
|
}
|
||||||
viewport->view_y = view_y;
|
w->saved_view_x = centreLoc->x;
|
||||||
|
w->saved_view_y = centreLoc->y;
|
||||||
|
viewport->view_x = centreLoc->x;
|
||||||
|
viewport->view_y = centreLoc->y;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -592,11 +589,12 @@ void viewport_update_position(rct_window* window)
|
||||||
|
|
||||||
if (at_map_edge)
|
if (at_map_edge)
|
||||||
{
|
{
|
||||||
int32_t _2d_x, _2d_y;
|
auto centreLoc = centre_2d_coordinates({ mapCoord, 0 }, viewport);
|
||||||
centre_2d_coordinates(mapCoord.x, mapCoord.y, 0, &_2d_x, &_2d_y, viewport);
|
if (centreLoc)
|
||||||
|
{
|
||||||
window->saved_view_x = _2d_x;
|
window->saved_view_x = centreLoc->x;
|
||||||
window->saved_view_y = _2d_y;
|
window->saved_view_y = centreLoc->y;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
x = window->saved_view_x;
|
x = window->saved_view_x;
|
||||||
|
@ -651,12 +649,13 @@ void viewport_update_sprite_follow(rct_window* window)
|
||||||
|
|
||||||
viewport_set_underground_flag(underground, window, window->viewport);
|
viewport_set_underground_flag(underground, window, window->viewport);
|
||||||
|
|
||||||
int32_t centre_x, centre_y;
|
auto centreLoc = centre_2d_coordinates({ sprite->generic.x, sprite->generic.y, sprite->generic.z }, window->viewport);
|
||||||
centre_2d_coordinates(sprite->generic.x, sprite->generic.y, sprite->generic.z, ¢re_x, ¢re_y, window->viewport);
|
if (centreLoc)
|
||||||
|
{
|
||||||
window->saved_view_x = centre_x;
|
window->saved_view_x = centreLoc->x;
|
||||||
window->saved_view_y = centre_y;
|
window->saved_view_y = centreLoc->y;
|
||||||
viewport_move(centre_x, centre_y, window, window->viewport);
|
viewport_move(centreLoc->x, centreLoc->y, window, window->viewport);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#ifndef _VIEWPORT_H_
|
#ifndef _VIEWPORT_H_
|
||||||
#define _VIEWPORT_H_
|
#define _VIEWPORT_H_
|
||||||
|
|
||||||
|
#include "../core/Optional.hpp"
|
||||||
#include "../world/Location.hpp"
|
#include "../world/Location.hpp"
|
||||||
#include "Window.h"
|
#include "Window.h"
|
||||||
|
|
||||||
|
@ -120,7 +121,7 @@ extern paint_entry* gNextFreePaintStruct;
|
||||||
extern uint8_t gCurrentRotation;
|
extern uint8_t gCurrentRotation;
|
||||||
|
|
||||||
void viewport_init_all();
|
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);
|
std::optional<ScreenCoordsXY> centre_2d_coordinates(CoordsXYZ loc, rct_viewport* viewport);
|
||||||
void viewport_create(
|
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,
|
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, uint16_t sprite);
|
int32_t centre_z, char flags, uint16_t sprite);
|
||||||
|
|
|
@ -935,13 +935,15 @@ void window_rotate_camera(rct_window* w, int32_t direction)
|
||||||
|
|
||||||
gCurrentRotation = (get_current_rotation() + direction) & 3;
|
gCurrentRotation = (get_current_rotation() + direction) & 3;
|
||||||
|
|
||||||
int32_t new_x, new_y;
|
auto centreLoc = centre_2d_coordinates({ coords, z }, viewport);
|
||||||
centre_2d_coordinates(coords.x, coords.y, z, &new_x, &new_y, viewport);
|
|
||||||
|
|
||||||
w->saved_view_x = new_x;
|
if (centreLoc)
|
||||||
w->saved_view_y = new_y;
|
{
|
||||||
viewport->view_x = new_x;
|
w->saved_view_x = centreLoc->x;
|
||||||
viewport->view_y = new_y;
|
w->saved_view_y = centreLoc->y;
|
||||||
|
viewport->view_x = centreLoc->x;
|
||||||
|
viewport->view_y = centreLoc->y;
|
||||||
|
}
|
||||||
|
|
||||||
w->Invalidate();
|
w->Invalidate();
|
||||||
|
|
||||||
|
@ -960,25 +962,35 @@ void window_viewport_get_map_coords_by_cursor(
|
||||||
get_map_coordinates_from_pos(mouse_x, mouse_y, VIEWPORT_INTERACTION_MASK_NONE, map_x, map_y, nullptr, nullptr, nullptr);
|
get_map_coordinates_from_pos(mouse_x, mouse_y, VIEWPORT_INTERACTION_MASK_NONE, map_x, map_y, nullptr, nullptr, nullptr);
|
||||||
|
|
||||||
// Get viewport coordinates centring around the tile.
|
// Get viewport coordinates centring around the tile.
|
||||||
int32_t base_height = tile_element_height({ *map_x, *map_y });
|
int32_t z = tile_element_height({ *map_x, *map_y });
|
||||||
int32_t dest_x, dest_y;
|
|
||||||
centre_2d_coordinates(*map_x, *map_y, base_height, &dest_x, &dest_y, w->viewport);
|
auto centreLoc = centre_2d_coordinates({ *map_x, *map_y, z }, w->viewport);
|
||||||
|
if (!centreLoc)
|
||||||
|
{
|
||||||
|
log_error("Invalid location.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Rebase mouse position onto centre of window, and compensate for zoom level.
|
// Rebase mouse position onto centre of window, and compensate for zoom level.
|
||||||
int32_t rebased_x = ((w->width >> 1) - mouse_x) * (1 << w->viewport->zoom),
|
int32_t rebased_x = ((w->width >> 1) - mouse_x) * (1 << w->viewport->zoom),
|
||||||
rebased_y = ((w->height >> 1) - mouse_y) * (1 << w->viewport->zoom);
|
rebased_y = ((w->height >> 1) - mouse_y) * (1 << w->viewport->zoom);
|
||||||
|
|
||||||
// Compute cursor offset relative to tile.
|
// Compute cursor offset relative to tile.
|
||||||
*offset_x = (w->saved_view_x - (dest_x + rebased_x)) * (1 << w->viewport->zoom);
|
*offset_x = (w->saved_view_x - (centreLoc->x + rebased_x)) * (1 << w->viewport->zoom);
|
||||||
*offset_y = (w->saved_view_y - (dest_y + rebased_y)) * (1 << w->viewport->zoom);
|
*offset_y = (w->saved_view_y - (centreLoc->y + rebased_y)) * (1 << w->viewport->zoom);
|
||||||
}
|
}
|
||||||
|
|
||||||
void window_viewport_centre_tile_around_cursor(rct_window* w, int16_t map_x, int16_t map_y, int16_t offset_x, int16_t offset_y)
|
void window_viewport_centre_tile_around_cursor(rct_window* w, int16_t map_x, int16_t map_y, int16_t offset_x, int16_t offset_y)
|
||||||
{
|
{
|
||||||
// Get viewport coordinates centring around the tile.
|
// Get viewport coordinates centring around the tile.
|
||||||
int32_t dest_x, dest_y;
|
int32_t z = tile_element_height({ map_x, map_y });
|
||||||
int32_t base_height = tile_element_height({ map_x, map_y });
|
auto centreLoc = centre_2d_coordinates({ map_x, map_y, z }, w->viewport);
|
||||||
centre_2d_coordinates(map_x, map_y, base_height, &dest_x, &dest_y, w->viewport);
|
|
||||||
|
if (!centreLoc)
|
||||||
|
{
|
||||||
|
log_error("Invalid location.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Get mouse position to offset against.
|
// Get mouse position to offset against.
|
||||||
int32_t mouse_x, mouse_y;
|
int32_t mouse_x, mouse_y;
|
||||||
|
@ -989,8 +1001,8 @@ void window_viewport_centre_tile_around_cursor(rct_window* w, int16_t map_x, int
|
||||||
rebased_y = ((w->height >> 1) - mouse_y) * (1 << w->viewport->zoom);
|
rebased_y = ((w->height >> 1) - mouse_y) * (1 << w->viewport->zoom);
|
||||||
|
|
||||||
// Apply offset to the viewport.
|
// Apply offset to the viewport.
|
||||||
w->saved_view_x = dest_x + rebased_x + (offset_x / (1 << w->viewport->zoom));
|
w->saved_view_x = centreLoc->x + rebased_x + (offset_x / (1 << w->viewport->zoom));
|
||||||
w->saved_view_y = dest_y + rebased_y + (offset_y / (1 << w->viewport->zoom));
|
w->saved_view_y = centreLoc->y + rebased_y + (offset_y / (1 << w->viewport->zoom));
|
||||||
}
|
}
|
||||||
|
|
||||||
void window_zoom_set(rct_window* w, int32_t zoomLevel, bool atCursor)
|
void window_zoom_set(rct_window* w, int32_t zoomLevel, bool atCursor)
|
||||||
|
|
Loading…
Reference in New Issue