Update viewport positions in two stages
This commit is contained in:
@@ -251,7 +251,8 @@ struct SelectGameWindow : public Window {
|
|||||||
/* Update the viewport position. */
|
/* Update the viewport position. */
|
||||||
mw->viewport->dest_scrollpos_x = mw->viewport->scrollpos_x = pos.x;
|
mw->viewport->dest_scrollpos_x = mw->viewport->scrollpos_x = pos.x;
|
||||||
mw->viewport->dest_scrollpos_y = mw->viewport->scrollpos_y = pos.y;
|
mw->viewport->dest_scrollpos_y = mw->viewport->scrollpos_y = pos.y;
|
||||||
UpdateViewportPosition(mw);
|
UpdateNextViewportPosition(mw);
|
||||||
|
ApplyNextViewportPosition(mw);
|
||||||
mw->SetDirty(); // Required during panning, otherwise logo graphics disappears
|
mw->SetDirty(); // Required during panning, otherwise logo graphics disappears
|
||||||
|
|
||||||
/* If there is only one command, we just executed it and don't need to do any more */
|
/* If there is only one command, we just executed it and don't need to do any more */
|
||||||
|
@@ -4023,10 +4023,10 @@ static inline void ClampViewportToMap(const Viewport *vp, int *scroll_x, int *sc
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update the viewport position being displayed.
|
* Update the next viewport position being displayed.
|
||||||
* @param w %Window owning the viewport.
|
* @param w %Window owning the viewport.
|
||||||
*/
|
*/
|
||||||
void UpdateViewportPosition(Window *w)
|
void UpdateNextViewportPosition(Window *w)
|
||||||
{
|
{
|
||||||
const Viewport *vp = w->viewport;
|
const Viewport *vp = w->viewport;
|
||||||
|
|
||||||
@@ -4034,9 +4034,9 @@ void UpdateViewportPosition(Window *w)
|
|||||||
const Vehicle *veh = Vehicle::Get(w->viewport->follow_vehicle);
|
const Vehicle *veh = Vehicle::Get(w->viewport->follow_vehicle);
|
||||||
Point pt = MapXYZToViewport(vp, veh->x_pos, veh->y_pos, veh->z_pos);
|
Point pt = MapXYZToViewport(vp, veh->x_pos, veh->y_pos, veh->z_pos);
|
||||||
|
|
||||||
w->viewport->scrollpos_x = pt.x;
|
w->viewport->next_scrollpos_x = pt.x;
|
||||||
w->viewport->scrollpos_y = pt.y;
|
w->viewport->next_scrollpos_y = pt.y;
|
||||||
SetViewportPosition(w, pt.x, pt.y, false);
|
w->viewport->force_update_overlay_pending = false;
|
||||||
} else {
|
} else {
|
||||||
/* Ensure the destination location is within the map */
|
/* Ensure the destination location is within the map */
|
||||||
ClampViewportToMap(vp, &w->viewport->dest_scrollpos_x, &w->viewport->dest_scrollpos_y);
|
ClampViewportToMap(vp, &w->viewport->dest_scrollpos_x, &w->viewport->dest_scrollpos_y);
|
||||||
@@ -4044,29 +4044,40 @@ void UpdateViewportPosition(Window *w)
|
|||||||
int delta_x = w->viewport->dest_scrollpos_x - w->viewport->scrollpos_x;
|
int delta_x = w->viewport->dest_scrollpos_x - w->viewport->scrollpos_x;
|
||||||
int delta_y = w->viewport->dest_scrollpos_y - w->viewport->scrollpos_y;
|
int delta_y = w->viewport->dest_scrollpos_y - w->viewport->scrollpos_y;
|
||||||
|
|
||||||
|
w->viewport->next_scrollpos_x = w->viewport->scrollpos_x;
|
||||||
|
w->viewport->next_scrollpos_y = w->viewport->scrollpos_y;
|
||||||
|
|
||||||
bool update_overlay = false;
|
bool update_overlay = false;
|
||||||
if (delta_x != 0 || delta_y != 0) {
|
if (delta_x != 0 || delta_y != 0) {
|
||||||
if (_settings_client.gui.smooth_scroll) {
|
if (_settings_client.gui.smooth_scroll) {
|
||||||
int max_scroll = ScaleByMapSize1D(512 * ZOOM_LVL_BASE);
|
int max_scroll = ScaleByMapSize1D(512 * ZOOM_LVL_BASE);
|
||||||
/* Not at our desired position yet... */
|
/* Not at our desired position yet... */
|
||||||
w->viewport->scrollpos_x += Clamp(DivAwayFromZero(delta_x, 4), -max_scroll, max_scroll);
|
w->viewport->next_scrollpos_x += Clamp(DivAwayFromZero(delta_x, 4), -max_scroll, max_scroll);
|
||||||
w->viewport->scrollpos_y += Clamp(DivAwayFromZero(delta_y, 4), -max_scroll, max_scroll);
|
w->viewport->next_scrollpos_y += Clamp(DivAwayFromZero(delta_y, 4), -max_scroll, max_scroll);
|
||||||
} else {
|
} else {
|
||||||
w->viewport->scrollpos_x = w->viewport->dest_scrollpos_x;
|
w->viewport->next_scrollpos_x = w->viewport->dest_scrollpos_x;
|
||||||
w->viewport->scrollpos_y = w->viewport->dest_scrollpos_y;
|
w->viewport->next_scrollpos_y = w->viewport->dest_scrollpos_y;
|
||||||
}
|
}
|
||||||
update_overlay = (w->viewport->scrollpos_x == w->viewport->dest_scrollpos_x &&
|
update_overlay = (w->viewport->next_scrollpos_x == w->viewport->dest_scrollpos_x &&
|
||||||
w->viewport->scrollpos_y == w->viewport->dest_scrollpos_y);
|
w->viewport->next_scrollpos_y == w->viewport->dest_scrollpos_y);
|
||||||
}
|
}
|
||||||
|
w->viewport->force_update_overlay_pending = update_overlay;
|
||||||
|
|
||||||
ClampViewportToMap(vp, &w->viewport->scrollpos_x, &w->viewport->scrollpos_y);
|
ClampViewportToMap(vp, &w->viewport->next_scrollpos_x, &w->viewport->next_scrollpos_y);
|
||||||
|
|
||||||
if (_scrolling_viewport == w) UpdateActiveScrollingViewport(w);
|
if (_scrolling_viewport == w) UpdateActiveScrollingViewport(w);
|
||||||
|
|
||||||
SetViewportPosition(w, w->viewport->scrollpos_x, w->viewport->scrollpos_y, update_overlay);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Apply the next viewport position being displayed.
|
||||||
|
* @param w %Window owning the viewport.
|
||||||
|
*/
|
||||||
|
void ApplyNextViewportPosition(Window *w)
|
||||||
|
{
|
||||||
|
SetViewportPosition(w, w->viewport->next_scrollpos_x, w->viewport->next_scrollpos_y, w->viewport->force_update_overlay_pending);
|
||||||
|
}
|
||||||
|
|
||||||
void UpdateViewportSizeZoom(Viewport *vp)
|
void UpdateViewportSizeZoom(Viewport *vp)
|
||||||
{
|
{
|
||||||
vp->dirty_blocks_per_column = CeilDiv(vp->height, vp->GetDirtyBlockHeight());
|
vp->dirty_blocks_per_column = CeilDiv(vp->height, vp->GetDirtyBlockHeight());
|
||||||
|
@@ -33,7 +33,8 @@ void InitializeWindowViewport(Window *w, int x, int y, int width, int height, ui
|
|||||||
Viewport *IsPtInWindowViewport(const Window *w, int x, int y);
|
Viewport *IsPtInWindowViewport(const Window *w, int x, int y);
|
||||||
Point TranslateXYToTileCoord(const Viewport *vp, int x, int y, bool clamp_to_map = true);
|
Point TranslateXYToTileCoord(const Viewport *vp, int x, int y, bool clamp_to_map = true);
|
||||||
Point GetTileBelowCursor();
|
Point GetTileBelowCursor();
|
||||||
void UpdateViewportPosition(Window *w);
|
void UpdateNextViewportPosition(Window *w);
|
||||||
|
void ApplyNextViewportPosition(Window *w);
|
||||||
void UpdateViewportSizeZoom(Viewport *vp);
|
void UpdateViewportSizeZoom(Viewport *vp);
|
||||||
|
|
||||||
void MarkViewportDirty(Viewport * const vp, int left, int top, int right, int bottom, ViewportMarkDirtyFlags flags);
|
void MarkViewportDirty(Viewport * const vp, int left, int top, int right, int bottom, ViewportMarkDirtyFlags flags);
|
||||||
|
@@ -3365,11 +3365,16 @@ void UpdateWindows()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (Window *w : Window::Iterate()) {
|
||||||
|
/* Update viewport only if window is not shaded. */
|
||||||
|
if (w->viewport != nullptr && !w->IsShaded()) UpdateNextViewportPosition(w);
|
||||||
|
}
|
||||||
|
|
||||||
DrawDirtyBlocks();
|
DrawDirtyBlocks();
|
||||||
|
|
||||||
for (Window *w : Window::Iterate()) {
|
for (Window *w : Window::Iterate()) {
|
||||||
/* Update viewport only if window is not shaded. */
|
/* Update viewport only if window is not shaded. */
|
||||||
if (w->viewport != nullptr && !w->IsShaded()) UpdateViewportPosition(w);
|
if (w->viewport != nullptr && !w->IsShaded()) ApplyNextViewportPosition(w);
|
||||||
}
|
}
|
||||||
ViewportDoDrawProcessAllPending();
|
ViewportDoDrawProcessAllPending();
|
||||||
NetworkDrawChatMessage();
|
NetworkDrawChatMessage();
|
||||||
|
@@ -211,7 +211,7 @@ static const int WHITE_BORDER_DURATION = 3; ///< The initial timeout value for W
|
|||||||
* A viewport is either following a vehicle (its id in then in #follow_vehicle), or it aims to display a specific
|
* A viewport is either following a vehicle (its id in then in #follow_vehicle), or it aims to display a specific
|
||||||
* location #dest_scrollpos_x, #dest_scrollpos_y (#follow_vehicle is then #INVALID_VEHICLE).
|
* location #dest_scrollpos_x, #dest_scrollpos_y (#follow_vehicle is then #INVALID_VEHICLE).
|
||||||
* The actual location being shown is #scrollpos_x, #scrollpos_y.
|
* The actual location being shown is #scrollpos_x, #scrollpos_y.
|
||||||
* @see InitializeViewport(), UpdateViewportPosition(), UpdateViewportCoordinates().
|
* @see InitializeViewport(), UpdateNextViewportPosition(), ApplyNextViewportPosition(), UpdateViewportCoordinates().
|
||||||
*/
|
*/
|
||||||
struct ViewportData : Viewport {
|
struct ViewportData : Viewport {
|
||||||
VehicleID follow_vehicle; ///< VehicleID to follow if following a vehicle, #INVALID_VEHICLE otherwise.
|
VehicleID follow_vehicle; ///< VehicleID to follow if following a vehicle, #INVALID_VEHICLE otherwise.
|
||||||
@@ -219,6 +219,9 @@ struct ViewportData : Viewport {
|
|||||||
int32 scrollpos_y; ///< Currently shown y coordinate (virtual screen coordinate of topleft corner of the viewport).
|
int32 scrollpos_y; ///< Currently shown y coordinate (virtual screen coordinate of topleft corner of the viewport).
|
||||||
int32 dest_scrollpos_x; ///< Current destination x coordinate to display (virtual screen coordinate of topleft corner of the viewport).
|
int32 dest_scrollpos_x; ///< Current destination x coordinate to display (virtual screen coordinate of topleft corner of the viewport).
|
||||||
int32 dest_scrollpos_y; ///< Current destination y coordinate to display (virtual screen coordinate of topleft corner of the viewport).
|
int32 dest_scrollpos_y; ///< Current destination y coordinate to display (virtual screen coordinate of topleft corner of the viewport).
|
||||||
|
int32 next_scrollpos_x; ///< Next x coordinate to display (virtual screen coordinate of topleft corner of the viewport).
|
||||||
|
int32 next_scrollpos_y; ///< Next y coordinate to display (virtual screen coordinate of topleft corner of the viewport).
|
||||||
|
bool force_update_overlay_pending; ///< Forced overlay update is pending (see SetViewportPosition)
|
||||||
};
|
};
|
||||||
|
|
||||||
struct QueryString;
|
struct QueryString;
|
||||||
|
Reference in New Issue
Block a user