1
0
Fork 0

Codechange: Pass Viewport by reference.

This means we do not have to care what type of pointer is used.
pull/13985/head
Peter Nelson 2025-03-27 18:47:46 +00:00 committed by Peter Nelson
parent 70b4beb8e7
commit 8275bbfb87
16 changed files with 215 additions and 215 deletions

View File

@ -333,9 +333,9 @@ DEF_CONSOLE_CMD(ConZoomToLevel)
IConsolePrint(CC_ERROR, "Current client settings do not allow zooming out beyond level {}.", _settings_client.gui.zoom_max); IConsolePrint(CC_ERROR, "Current client settings do not allow zooming out beyond level {}.", _settings_client.gui.zoom_max);
} else { } else {
Window *w = GetMainWindow(); Window *w = GetMainWindow();
Viewport *vp = w->viewport; Viewport &vp = *w->viewport;
while (vp->zoom > level) DoZoomInOutWindow(ZOOM_IN, w); while (vp.zoom > level) DoZoomInOutWindow(ZOOM_IN, w);
while (vp->zoom < level) DoZoomInOutWindow(ZOOM_OUT, w); while (vp.zoom < level) DoZoomInOutWindow(ZOOM_OUT, w);
} }
return true; return true;
} }

View File

@ -75,7 +75,7 @@ struct IntroGameViewportCommand {
* @param vp Viewport to calculate position for. * @param vp Viewport to calculate position for.
* @return Calculated position in the viewport. * @return Calculated position in the viewport.
*/ */
Point PositionForViewport(const Viewport *vp) Point PositionForViewport(const Viewport &vp)
{ {
if (this->vehicle != VehicleID::Invalid()) { if (this->vehicle != VehicleID::Invalid()) {
const Vehicle *v = Vehicle::Get(this->vehicle); const Vehicle *v = Vehicle::Get(this->vehicle);
@ -85,13 +85,13 @@ struct IntroGameViewportCommand {
Point p; Point p;
switch (this->align_h) { switch (this->align_h) {
case LEFT: p.x = this->position.x; break; case LEFT: p.x = this->position.x; break;
case CENTRE: p.x = this->position.x - vp->virtual_width / 2; break; case CENTRE: p.x = this->position.x - vp.virtual_width / 2; break;
case RIGHT: p.x = this->position.x - vp->virtual_width; break; case RIGHT: p.x = this->position.x - vp.virtual_width; break;
} }
switch (this->align_v) { switch (this->align_v) {
case TOP: p.y = this->position.y; break; case TOP: p.y = this->position.y; break;
case MIDDLE: p.y = this->position.y - vp->virtual_height / 2; break; case MIDDLE: p.y = this->position.y - vp.virtual_height / 2; break;
case BOTTOM: p.y = this->position.y - vp->virtual_height; break; case BOTTOM: p.y = this->position.y - vp.virtual_height; break;
} }
return p; return p;
} }
@ -220,7 +220,6 @@ struct SelectGameWindow : public Window {
IntroGameViewportCommand &vc = intro_viewport_commands[this->cur_viewport_command_index]; IntroGameViewportCommand &vc = intro_viewport_commands[this->cur_viewport_command_index];
Window *mw = GetMainWindow(); Window *mw = GetMainWindow();
Viewport *vp = mw->viewport;
/* Early exit if the current command hasn't elapsed and isn't animated. */ /* Early exit if the current command hasn't elapsed and isn't animated. */
if (!changed_command && !vc.pan_to_next && vc.vehicle == VehicleID::Invalid()) return; if (!changed_command && !vc.pan_to_next && vc.vehicle == VehicleID::Invalid()) return;
@ -232,13 +231,13 @@ struct SelectGameWindow : public Window {
if (changed_command) FixTitleGameZoom(vc.zoom_adjust); if (changed_command) FixTitleGameZoom(vc.zoom_adjust);
/* Calculate current command position (updates followed vehicle coordinates). */ /* Calculate current command position (updates followed vehicle coordinates). */
Point pos = vc.PositionForViewport(vp); Point pos = vc.PositionForViewport(*mw->viewport);
/* Calculate panning (linear interpolation between current and next command position). */ /* Calculate panning (linear interpolation between current and next command position). */
if (vc.pan_to_next) { if (vc.pan_to_next) {
size_t next_command_index = (this->cur_viewport_command_index + 1) % intro_viewport_commands.size(); size_t next_command_index = (this->cur_viewport_command_index + 1) % intro_viewport_commands.size();
IntroGameViewportCommand &nvc = intro_viewport_commands[next_command_index]; IntroGameViewportCommand &nvc = intro_viewport_commands[next_command_index];
Point pos2 = nvc.PositionForViewport(vp); Point pos2 = nvc.PositionForViewport(*mw->viewport);
const double t = this->cur_viewport_command_time / (double)vc.delay; const double t = this->cur_viewport_command_time / (double)vc.delay;
pos.x = pos.x + (int)(t * (pos2.x - pos.x)); pos.x = pos.x + (int)(t * (pos2.x - pos.x));
pos.y = pos.y + (int)(t * (pos2.y - pos.y)); pos.y = pos.y + (int)(t * (pos2.y - pos.y));

View File

@ -414,7 +414,7 @@ bool LinkGraphOverlay::ShowTooltip(Point pt, TooltipCloseCondition close_cond)
Point LinkGraphOverlay::GetStationMiddle(const Station *st) const Point LinkGraphOverlay::GetStationMiddle(const Station *st) const
{ {
if (this->window->viewport != nullptr) { if (this->window->viewport != nullptr) {
return GetViewportStationMiddle(this->window->viewport, st); return GetViewportStationMiddle(*this->window->viewport, st);
} else { } else {
/* assume this is a smallmap */ /* assume this is a smallmap */
return GetSmallMapStationMiddle(this->window, st); return GetSmallMapStationMiddle(this->window, st);

View File

@ -92,44 +92,48 @@ void CcPlaySound_EXPLOSION(Commands, const CommandCost &result, TileIndex tile)
*/ */
bool DoZoomInOutWindow(ZoomStateChange how, Window *w) bool DoZoomInOutWindow(ZoomStateChange how, Window *w)
{ {
Viewport *vp;
assert(w != nullptr); assert(w != nullptr);
vp = w->viewport;
switch (how) { switch (how) {
case ZOOM_NONE: case ZOOM_NONE:
/* On initialisation of the viewport we don't do anything. */ /* On initialisation of the viewport we don't do anything. */
break; break;
case ZOOM_IN: case ZOOM_IN: {
if (vp->zoom <= _settings_client.gui.zoom_min) return false; ViewportData &vp = *w->viewport;
vp->zoom = (ZoomLevel)((int)vp->zoom - 1); if (vp.zoom <= _settings_client.gui.zoom_min) return false;
vp->virtual_width >>= 1; --vp.zoom;
vp->virtual_height >>= 1; vp.virtual_width >>= 1;
vp.virtual_height >>= 1;
w->viewport->scrollpos_x += vp->virtual_width >> 1; vp.scrollpos_x += vp.virtual_width >> 1;
w->viewport->scrollpos_y += vp->virtual_height >> 1; vp.scrollpos_y += vp.virtual_height >> 1;
w->viewport->dest_scrollpos_x = w->viewport->scrollpos_x; vp.dest_scrollpos_x = vp.scrollpos_x;
w->viewport->dest_scrollpos_y = w->viewport->scrollpos_y; vp.dest_scrollpos_y = vp.scrollpos_y;
break; break;
case ZOOM_OUT: }
if (vp->zoom >= _settings_client.gui.zoom_max) return false;
vp->zoom = (ZoomLevel)((int)vp->zoom + 1);
w->viewport->scrollpos_x -= vp->virtual_width >> 1; case ZOOM_OUT: {
w->viewport->scrollpos_y -= vp->virtual_height >> 1; ViewportData &vp = *w->viewport;
w->viewport->dest_scrollpos_x = w->viewport->scrollpos_x; if (vp.zoom >= _settings_client.gui.zoom_max) return false;
w->viewport->dest_scrollpos_y = w->viewport->scrollpos_y; ++vp.zoom;
vp->virtual_width <<= 1; vp.scrollpos_x -= vp.virtual_width >> 1;
vp->virtual_height <<= 1; vp.scrollpos_y -= vp.virtual_height >> 1;
vp.dest_scrollpos_x = vp.scrollpos_x;
vp.dest_scrollpos_y = vp.scrollpos_y;
vp.virtual_width <<= 1;
vp.virtual_height <<= 1;
break; break;
}
} }
if (vp != nullptr) { // the vp can be null when how == ZOOM_NONE
vp->virtual_left = w->viewport->scrollpos_x; if (w->viewport != nullptr) { // the viewport can be null when how == ZOOM_NONE
vp->virtual_top = w->viewport->scrollpos_y; w->viewport->virtual_left = w->viewport->scrollpos_x;
w->viewport->virtual_top = w->viewport->scrollpos_y;
} }
/* Update the windows that have zoom-buttons to perhaps disable their buttons */ /* Update the windows that have zoom-buttons to perhaps disable their buttons */
w->InvalidateData(); w->InvalidateData();
return true; return true;
@ -140,8 +144,7 @@ void ZoomInOrOutToCursorWindow(bool in, Window *w)
assert(w != nullptr); assert(w != nullptr);
if (_game_mode != GM_MENU) { if (_game_mode != GM_MENU) {
Viewport *vp = w->viewport; if ((in && w->viewport->zoom <= _settings_client.gui.zoom_min) || (!in && w->viewport->zoom >= _settings_client.gui.zoom_max)) return;
if ((in && vp->zoom <= _settings_client.gui.zoom_min) || (!in && vp->zoom >= _settings_client.gui.zoom_max)) return;
Point pt = GetTileZoomCenterWindow(in, w); Point pt = GetTileZoomCenterWindow(in, w);
if (pt.x != -1) { if (pt.x != -1) {
@ -156,22 +159,22 @@ void FixTitleGameZoom(int zoom_adjust)
{ {
if (_game_mode != GM_MENU) return; if (_game_mode != GM_MENU) return;
Viewport *vp = GetMainWindow()->viewport; Viewport &vp = *GetMainWindow()->viewport;
/* Adjust the zoom in/out. /* Adjust the zoom in/out.
* Can't simply add, since operator+ is not defined on the ZoomLevel type. */ * Can't simply add, since operator+ is not defined on the ZoomLevel type. */
vp->zoom = _gui_zoom; vp.zoom = _gui_zoom;
while (zoom_adjust < 0 && vp->zoom != _settings_client.gui.zoom_min) { while (zoom_adjust < 0 && vp.zoom != _settings_client.gui.zoom_min) {
vp->zoom--; vp.zoom--;
zoom_adjust++; zoom_adjust++;
} }
while (zoom_adjust > 0 && vp->zoom != _settings_client.gui.zoom_max) { while (zoom_adjust > 0 && vp.zoom != _settings_client.gui.zoom_max) {
vp->zoom++; vp.zoom++;
zoom_adjust--; zoom_adjust--;
} }
vp->virtual_width = ScaleByZoom(vp->width, vp->zoom); vp.virtual_width = ScaleByZoom(vp.width, vp.zoom);
vp->virtual_height = ScaleByZoom(vp->height, vp->zoom); vp.virtual_height = ScaleByZoom(vp.height, vp.zoom);
} }
static constexpr NWidgetPart _nested_main_window_widgets[] = { static constexpr NWidgetPart _nested_main_window_widgets[] = {

View File

@ -60,16 +60,16 @@ void ResetViewportAfterLoadGame()
w->viewport->dest_scrollpos_x = _saved_scrollpos_x; w->viewport->dest_scrollpos_x = _saved_scrollpos_x;
w->viewport->dest_scrollpos_y = _saved_scrollpos_y; w->viewport->dest_scrollpos_y = _saved_scrollpos_y;
Viewport *vp = w->viewport; Viewport &vp = *w->viewport;
vp->zoom = std::min(_saved_scrollpos_zoom, ZOOM_LVL_MAX); vp.zoom = std::min(_saved_scrollpos_zoom, ZOOM_LVL_MAX);
vp->virtual_width = ScaleByZoom(vp->width, vp->zoom); vp.virtual_width = ScaleByZoom(vp.width, vp.zoom);
vp->virtual_height = ScaleByZoom(vp->height, vp->zoom); vp.virtual_height = ScaleByZoom(vp.height, vp.zoom);
/* If zoom_max is ZOOM_LVL_MIN then the setting has not been loaded yet, therefore all levels are allowed. */ /* If zoom_max is ZOOM_LVL_MIN then the setting has not been loaded yet, therefore all levels are allowed. */
if (_settings_client.gui.zoom_max != ZOOM_LVL_MIN) { if (_settings_client.gui.zoom_max != ZOOM_LVL_MIN) {
/* Ensure zoom level is allowed */ /* Ensure zoom level is allowed */
while (vp->zoom < _settings_client.gui.zoom_min) DoZoomInOutWindow(ZOOM_OUT, w); while (vp.zoom < _settings_client.gui.zoom_min) DoZoomInOutWindow(ZOOM_OUT, w);
while (vp->zoom > _settings_client.gui.zoom_max) DoZoomInOutWindow(ZOOM_IN, w); while (vp.zoom > _settings_client.gui.zoom_max) DoZoomInOutWindow(ZOOM_IN, w);
} }
DoZoomInOutWindow(ZOOM_NONE, w); // update button status DoZoomInOutWindow(ZOOM_NONE, w); // update button status

View File

@ -117,7 +117,7 @@ static void LargeWorldCallback(void *userdata, void *buf, uint y, uint pitch, ui
wx = std::min(vp->width - left, 1600); wx = std::min(vp->width - left, 1600);
left += wx; left += wx;
ViewportDoDraw(vp, ViewportDoDraw(*vp,
ScaleByZoom(left - wx - vp->left, vp->zoom) + vp->virtual_left, ScaleByZoom(left - wx - vp->left, vp->zoom) + vp->virtual_left,
ScaleByZoom(y - vp->top, vp->zoom) + vp->virtual_top, ScaleByZoom(y - vp->top, vp->zoom) + vp->virtual_top,
ScaleByZoom(left - vp->left, vp->zoom) + vp->virtual_left, ScaleByZoom(left - vp->left, vp->zoom) + vp->virtual_left,

View File

@ -876,10 +876,10 @@ protected:
void DrawMapIndicators() const void DrawMapIndicators() const
{ {
/* Find main viewport. */ /* Find main viewport. */
const Viewport *vp = GetMainWindow()->viewport; const Viewport &vp = *GetMainWindow()->viewport;
Point upper_left_smallmap_coord = InverseRemapCoords2(vp->virtual_left, vp->virtual_top); Point upper_left_smallmap_coord = InverseRemapCoords2(vp.virtual_left, vp.virtual_top);
Point lower_right_smallmap_coord = InverseRemapCoords2(vp->virtual_left + vp->virtual_width - 1, vp->virtual_top + vp->virtual_height - 1); Point lower_right_smallmap_coord = InverseRemapCoords2(vp.virtual_left + vp.virtual_width - 1, vp.virtual_top + vp.virtual_height - 1);
Point upper_left = this->RemapTile(upper_left_smallmap_coord.x / (int)TILE_SIZE, upper_left_smallmap_coord.y / (int)TILE_SIZE); Point upper_left = this->RemapTile(upper_left_smallmap_coord.x / (int)TILE_SIZE, upper_left_smallmap_coord.y / (int)TILE_SIZE);
upper_left.x -= this->subscroll; upper_left.x -= this->subscroll;
@ -1477,8 +1477,8 @@ public:
*/ */
void SmallMapCenterOnCurrentPos() void SmallMapCenterOnCurrentPos()
{ {
const Viewport *vp = GetMainWindow()->viewport; const Viewport &vp = *GetMainWindow()->viewport;
Point viewport_center = InverseRemapCoords2(vp->virtual_left + vp->virtual_width / 2, vp->virtual_top + vp->virtual_height / 2); Point viewport_center = InverseRemapCoords2(vp.virtual_left + vp.virtual_width / 2, vp.virtual_top + vp.virtual_height / 2);
int sub; int sub;
const NWidgetBase *wid = this->GetWidget<NWidgetBase>(WID_SM_MAP); const NWidgetBase *wid = this->GetWidget<NWidgetBase>(WID_SM_MAP);

View File

@ -203,19 +203,19 @@ static void SndPlayScreenCoordFx(SoundID sound, int left, int right, int top, in
{ {
/* Iterate from back, so that main viewport is checked first */ /* Iterate from back, so that main viewport is checked first */
for (const Window *w : Window::IterateFromBack()) { for (const Window *w : Window::IterateFromBack()) {
const Viewport *vp = w->viewport; if (w->viewport == nullptr) continue;
if (vp != nullptr && const Viewport &vp = *w->viewport;
left < vp->virtual_left + vp->virtual_width && right > vp->virtual_left && if (left < vp.virtual_left + vp.virtual_width && right > vp.virtual_left &&
top < vp->virtual_top + vp->virtual_height && bottom > vp->virtual_top) { top < vp.virtual_top + vp.virtual_height && bottom > vp.virtual_top) {
int screen_x = (left + right) / 2 - vp->virtual_left; int screen_x = (left + right) / 2 - vp.virtual_left;
int width = (vp->virtual_width == 0 ? 1 : vp->virtual_width); int width = (vp.virtual_width == 0 ? 1 : vp.virtual_width);
float panning = (float)screen_x / width; float panning = (float)screen_x / width;
StartSound( StartSound(
sound, sound,
panning, panning,
_vol_factor_by_zoom[vp->zoom] _vol_factor_by_zoom[vp.zoom]
); );
return; return;
} }

View File

@ -2135,7 +2135,7 @@ struct MainToolbarWindow : Window {
void OnInvalidateData([[maybe_unused]] int data = 0, [[maybe_unused]] bool gui_scope = true) override void OnInvalidateData([[maybe_unused]] int data = 0, [[maybe_unused]] bool gui_scope = true) override
{ {
if (!gui_scope) return; if (!gui_scope) return;
HandleZoomMessage(this, GetMainWindow()->viewport, WID_TN_ZOOM_IN, WID_TN_ZOOM_OUT); HandleZoomMessage(this, *GetMainWindow()->viewport, WID_TN_ZOOM_IN, WID_TN_ZOOM_OUT);
} }
static inline HotkeyList hotkeys{"maintoolbar", { static inline HotkeyList hotkeys{"maintoolbar", {
@ -2493,7 +2493,7 @@ struct ScenarioEditorToolbarWindow : Window {
void OnInvalidateData([[maybe_unused]] int data = 0, [[maybe_unused]] bool gui_scope = true) override void OnInvalidateData([[maybe_unused]] int data = 0, [[maybe_unused]] bool gui_scope = true) override
{ {
if (!gui_scope) return; if (!gui_scope) return;
HandleZoomMessage(this, GetMainWindow()->viewport, WID_TE_ZOOM_IN, WID_TE_ZOOM_OUT); HandleZoomMessage(this, *GetMainWindow()->viewport, WID_TE_ZOOM_IN, WID_TE_ZOOM_OUT);
} }
void OnQueryTextFinished(std::optional<std::string> str) override void OnQueryTextFinished(std::optional<std::string> str) override

View File

@ -1239,15 +1239,17 @@ void ViewportAddVehicles(DrawPixelInfo *dpi)
* @param y Y coordinate in the viewport. * @param y Y coordinate in the viewport.
* @return Closest vehicle, or \c nullptr if none found. * @return Closest vehicle, or \c nullptr if none found.
*/ */
Vehicle *CheckClickOnVehicle(const Viewport *vp, int x, int y) Vehicle *CheckClickOnVehicle(const Viewport &vp, int x, int y)
{ {
Vehicle *found = nullptr; Vehicle *found = nullptr;
uint dist, best_dist = UINT_MAX; uint dist, best_dist = UINT_MAX;
if ((uint)(x -= vp->left) >= (uint)vp->width || (uint)(y -= vp->top) >= (uint)vp->height) return nullptr; x -= vp.left;
y -= vp.top;
if (!IsInsideMM(x, 0, vp.width) || !IsInsideMM(y, 0, vp.height)) return nullptr;
x = ScaleByZoom(x, vp->zoom) + vp->virtual_left; x = ScaleByZoom(x, vp.zoom) + vp.virtual_left;
y = ScaleByZoom(y, vp->zoom) + vp->virtual_top; y = ScaleByZoom(y, vp.zoom) + vp.virtual_top;
/* Border size of MAX_VEHICLE_PIXEL_xy */ /* Border size of MAX_VEHICLE_PIXEL_xy */
const int xb = MAX_VEHICLE_PIXEL_X * ZOOM_BASE; const int xb = MAX_VEHICLE_PIXEL_X * ZOOM_BASE;

View File

@ -112,7 +112,7 @@ bool VehicleClicked(VehicleList::const_iterator begin, VehicleList::const_iterat
bool VehicleClicked(const GUIVehicleGroup &vehgroup); bool VehicleClicked(const GUIVehicleGroup &vehgroup);
void StartStopVehicle(const Vehicle *v, bool texteffect); void StartStopVehicle(const Vehicle *v, bool texteffect);
Vehicle *CheckClickOnVehicle(const struct Viewport *vp, int x, int y); Vehicle *CheckClickOnVehicle(const struct Viewport &vp, int x, int y);
void StopGlobalFollowVehicle(const Vehicle *v); void StopGlobalFollowVehicle(const Vehicle *v);
void DrawVehicleImage(const Vehicle *v, const Rect &r, VehicleID selection, EngineImageType image_type, int skip); void DrawVehicleImage(const Vehicle *v, const Rect &r, VehicleID selection, EngineImageType image_type, int skip);

View File

@ -186,7 +186,7 @@ struct ViewportDrawer {
Point foundation_offset[FOUNDATION_PART_END]; ///< Pixel offset for ground sprites on the foundations. Point foundation_offset[FOUNDATION_PART_END]; ///< Pixel offset for ground sprites on the foundations.
}; };
static bool MarkViewportDirty(const Viewport *vp, int left, int top, int right, int bottom); static bool MarkViewportDirty(const Viewport &vp, int left, int top, int right, int bottom);
static ViewportDrawer _vd; static ViewportDrawer _vd;
@ -197,11 +197,11 @@ bool _draw_dirty_blocks = false;
uint _dirty_block_colour = 0; uint _dirty_block_colour = 0;
static VpSpriteSorter _vp_sprite_sorter = nullptr; static VpSpriteSorter _vp_sprite_sorter = nullptr;
static Point MapXYZToViewport(const Viewport *vp, int x, int y, int z) static Point MapXYZToViewport(const Viewport &vp, int x, int y, int z)
{ {
Point p = RemapCoords(x, y, z); Point p = RemapCoords(x, y, z);
p.x -= vp->virtual_width / 2; p.x -= vp.virtual_width / 2;
p.y -= vp->virtual_height / 2; p.y -= vp.virtual_height / 2;
return p; return p;
} }
@ -245,7 +245,7 @@ void InitializeWindowViewport(Window *w, int x, int y,
vp->follow_vehicle = std::get<VehicleID>(focus); vp->follow_vehicle = std::get<VehicleID>(focus);
veh = Vehicle::Get(vp->follow_vehicle); veh = Vehicle::Get(vp->follow_vehicle);
pt = MapXYZToViewport(vp, veh->x_pos, veh->y_pos, veh->z_pos); pt = MapXYZToViewport(*vp, veh->x_pos, veh->y_pos, veh->z_pos);
} else { } else {
TileIndex tile = std::get<TileIndex>(focus); TileIndex tile = std::get<TileIndex>(focus);
if (tile == INVALID_TILE) { if (tile == INVALID_TILE) {
@ -260,7 +260,7 @@ void InitializeWindowViewport(Window *w, int x, int y,
} else { } else {
x = TileX(tile) * TILE_SIZE; x = TileX(tile) * TILE_SIZE;
y = TileY(tile) * TILE_SIZE; y = TileY(tile) * TILE_SIZE;
pt = MapXYZToViewport(vp, x, y, GetSlopePixelZ(x, y)); pt = MapXYZToViewport(*vp, x, y, GetSlopePixelZ(x, y));
} }
vp->follow_vehicle = VehicleID::Invalid(); vp->follow_vehicle = VehicleID::Invalid();
} }
@ -347,22 +347,22 @@ static void DoSetViewportPosition(Window::IteratorToFront it, int left, int top,
static void SetViewportPosition(Window *w, int x, int y) static void SetViewportPosition(Window *w, int x, int y)
{ {
Viewport *vp = w->viewport; Viewport &vp = *w->viewport;
int old_left = vp->virtual_left; int old_left = vp.virtual_left;
int old_top = vp->virtual_top; int old_top = vp.virtual_top;
int i; int i;
int left, top, width, height; int left, top, width, height;
vp->virtual_left = x; vp.virtual_left = x;
vp->virtual_top = y; vp.virtual_top = y;
/* Viewport is bound to its left top corner, so it must be rounded down (UnScaleByZoomLower) /* Viewport is bound to its left top corner, so it must be rounded down (UnScaleByZoomLower)
* else glitch described in FS#1412 will happen (offset by 1 pixel with zoom level > NORMAL) * else glitch described in FS#1412 will happen (offset by 1 pixel with zoom level > NORMAL)
*/ */
old_left = UnScaleByZoomLower(old_left, vp->zoom); old_left = UnScaleByZoomLower(old_left, vp.zoom);
old_top = UnScaleByZoomLower(old_top, vp->zoom); old_top = UnScaleByZoomLower(old_top, vp.zoom);
x = UnScaleByZoomLower(x, vp->zoom); x = UnScaleByZoomLower(x, vp.zoom);
y = UnScaleByZoomLower(y, vp->zoom); y = UnScaleByZoomLower(y, vp.zoom);
old_left -= x; old_left -= x;
old_top -= y; old_top -= y;
@ -372,10 +372,10 @@ static void SetViewportPosition(Window *w, int x, int y)
_vp_move_offs.x = old_left; _vp_move_offs.x = old_left;
_vp_move_offs.y = old_top; _vp_move_offs.y = old_top;
left = vp->left; left = vp.left;
top = vp->top; top = vp.top;
width = vp->width; width = vp.width;
height = vp->height; height = vp.height;
if (left < 0) { if (left < 0) {
width += left; width += left;
@ -412,12 +412,10 @@ static void SetViewportPosition(Window *w, int x, int y)
*/ */
Viewport *IsPtInWindowViewport(const Window *w, int x, int y) Viewport *IsPtInWindowViewport(const Window *w, int x, int y)
{ {
Viewport *vp = w->viewport; if (w->viewport == nullptr) return nullptr;
if (vp != nullptr && const Viewport &vp = *w->viewport;
IsInsideMM(x, vp->left, vp->left + vp->width) && if (IsInsideMM(x, vp.left, vp.left + vp.width) && IsInsideMM(y, vp.top, vp.top + vp.height)) return w->viewport;
IsInsideMM(y, vp->top, vp->top + vp->height))
return vp;
return nullptr; return nullptr;
} }
@ -434,16 +432,16 @@ Viewport *IsPtInWindowViewport(const Window *w, int x, int y)
* @param clamp_to_map Clamp the coordinate outside of the map to the closest, non-void tile within the map * @param clamp_to_map Clamp the coordinate outside of the map to the closest, non-void tile within the map
* @return Tile coordinate or (-1, -1) if given x or y is not within viewport frame * @return Tile coordinate or (-1, -1) if given x or y is not within viewport frame
*/ */
Point TranslateXYToTileCoord(const Viewport *vp, int x, int y, bool clamp_to_map) Point TranslateXYToTileCoord(const Viewport &vp, int x, int y, bool clamp_to_map)
{ {
if (!IsInsideBS(x, vp->left, vp->width) || !IsInsideBS(y, vp->top, vp->height)) { if (!IsInsideBS(x, vp.left, vp.width) || !IsInsideBS(y, vp.top, vp.height)) {
Point pt = { -1, -1 }; Point pt = { -1, -1 };
return pt; return pt;
} }
return InverseRemapCoords2( return InverseRemapCoords2(
ScaleByZoom(x - vp->left, vp->zoom) + vp->virtual_left, ScaleByZoom(x - vp.left, vp.zoom) + vp.virtual_left,
ScaleByZoom(y - vp->top, vp->zoom) + vp->virtual_top, clamp_to_map); ScaleByZoom(y - vp.top, vp.zoom) + vp.virtual_top, clamp_to_map);
} }
/* When used for zooming, check area below current coordinates (x,y) /* When used for zooming, check area below current coordinates (x,y)
@ -451,16 +449,13 @@ Point TranslateXYToTileCoord(const Viewport *vp, int x, int y, bool clamp_to_map
* when you just want the tile, make x = zoom_x and y = zoom_y */ * when you just want the tile, make x = zoom_x and y = zoom_y */
static Point GetTileFromScreenXY(int x, int y, int zoom_x, int zoom_y) static Point GetTileFromScreenXY(int x, int y, int zoom_x, int zoom_y)
{ {
Window *w; if (Window *w = FindWindowFromPt(x, y); w != nullptr) {
Viewport *vp; if (Viewport *vp = IsPtInWindowViewport(w, x, y); vp != nullptr) {
Point pt; return TranslateXYToTileCoord(*vp, zoom_x, zoom_y);
}
}
if ( (w = FindWindowFromPt(x, y)) != nullptr && return {-1, -1};
(vp = IsPtInWindowViewport(w, x, y)) != nullptr)
return TranslateXYToTileCoord(vp, zoom_x, zoom_y);
pt.y = pt.x = -1;
return pt;
} }
Point GetTileBelowCursor() Point GetTileBelowCursor()
@ -472,17 +467,17 @@ Point GetTileBelowCursor()
Point GetTileZoomCenterWindow(bool in, Window * w) Point GetTileZoomCenterWindow(bool in, Window * w)
{ {
int x, y; int x, y;
Viewport *vp = w->viewport; const Viewport &vp = *w->viewport;
if (in) { if (in) {
x = ((_cursor.pos.x - vp->left) >> 1) + (vp->width >> 2); x = ((_cursor.pos.x - vp.left) >> 1) + (vp.width >> 2);
y = ((_cursor.pos.y - vp->top) >> 1) + (vp->height >> 2); y = ((_cursor.pos.y - vp.top) >> 1) + (vp.height >> 2);
} else { } else {
x = vp->width - (_cursor.pos.x - vp->left); x = vp.width - (_cursor.pos.x - vp.left);
y = vp->height - (_cursor.pos.y - vp->top); y = vp.height - (_cursor.pos.y - vp.top);
} }
/* Get the tile below the cursor and center on the zoomed-out center */ /* Get the tile below the cursor and center on the zoomed-out center */
return GetTileFromScreenXY(_cursor.pos.x, _cursor.pos.y, x + vp->left, y + vp->top); return GetTileFromScreenXY(_cursor.pos.x, _cursor.pos.y, x + vp.left, y + vp.top);
} }
/** /**
@ -493,12 +488,12 @@ Point GetTileZoomCenterWindow(bool in, Window * w)
* @param widget_zoom_in widget index for window with zoom-in button * @param widget_zoom_in widget index for window with zoom-in button
* @param widget_zoom_out widget index for window with zoom-out button * @param widget_zoom_out widget index for window with zoom-out button
*/ */
void HandleZoomMessage(Window *w, const Viewport *vp, WidgetID widget_zoom_in, WidgetID widget_zoom_out) void HandleZoomMessage(Window *w, const Viewport &vp, WidgetID widget_zoom_in, WidgetID widget_zoom_out)
{ {
w->SetWidgetDisabledState(widget_zoom_in, vp->zoom <= _settings_client.gui.zoom_min); w->SetWidgetDisabledState(widget_zoom_in, vp.zoom <= _settings_client.gui.zoom_min);
w->SetWidgetDirty(widget_zoom_in); w->SetWidgetDirty(widget_zoom_in);
w->SetWidgetDisabledState(widget_zoom_out, vp->zoom >= _settings_client.gui.zoom_max); w->SetWidgetDisabledState(widget_zoom_out, vp.zoom >= _settings_client.gui.zoom_max);
w->SetWidgetDirty(widget_zoom_out); w->SetWidgetDirty(widget_zoom_out);
} }
@ -1549,10 +1544,12 @@ void ViewportSign::MarkDirty(ZoomLevel maxzoom) const
} }
for (const Window *w : Window::Iterate()) { for (const Window *w : Window::Iterate()) {
Viewport *vp = w->viewport; if (w->viewport == nullptr) continue;
if (vp != nullptr && vp->zoom <= maxzoom) {
assert(vp->width != 0); Viewport &vp = *w->viewport;
Rect &zl = zoomlevels[vp->zoom]; if (vp.zoom <= maxzoom) {
assert(vp.width != 0);
Rect &zl = zoomlevels[vp.zoom];
MarkViewportDirty(vp, zl.left, zl.top, zl.right, zl.bottom); MarkViewportDirty(vp, zl.left, zl.top, zl.right, zl.bottom);
} }
} }
@ -1787,10 +1784,10 @@ static void ViewportDrawStrings(ZoomLevel zoom, const StringSpriteToDrawVector *
} }
} }
void ViewportDoDraw(const Viewport *vp, int left, int top, int right, int bottom) void ViewportDoDraw(const Viewport &vp, int left, int top, int right, int bottom)
{ {
_vd.dpi.zoom = vp->zoom; _vd.dpi.zoom = vp.zoom;
int mask = ScaleByZoom(-1, vp->zoom); int mask = ScaleByZoom(-1, vp.zoom);
_vd.combine_sprites = SPRITE_COMBINE_NONE; _vd.combine_sprites = SPRITE_COMBINE_NONE;
@ -1801,8 +1798,8 @@ void ViewportDoDraw(const Viewport *vp, int left, int top, int right, int bottom
_vd.dpi.pitch = _cur_dpi->pitch; _vd.dpi.pitch = _cur_dpi->pitch;
_vd.last_child = LAST_CHILD_NONE; _vd.last_child = LAST_CHILD_NONE;
int x = UnScaleByZoom(_vd.dpi.left - (vp->virtual_left & mask), vp->zoom) + vp->left; int x = UnScaleByZoom(_vd.dpi.left - (vp.virtual_left & mask), vp.zoom) + vp.left;
int y = UnScaleByZoom(_vd.dpi.top - (vp->virtual_top & mask), vp->zoom) + vp->top; int y = UnScaleByZoom(_vd.dpi.top - (vp.virtual_top & mask), vp.zoom) + vp.top;
_vd.dpi.dst_ptr = BlitterFactory::GetCurrentBlitter()->MoveTo(_cur_dpi->dst_ptr, x - _cur_dpi->left, y - _cur_dpi->top); _vd.dpi.dst_ptr = BlitterFactory::GetCurrentBlitter()->MoveTo(_cur_dpi->dst_ptr, x - _cur_dpi->left, y - _cur_dpi->top);
AutoRestoreBackup dpi_backup(_cur_dpi, &_vd.dpi); AutoRestoreBackup dpi_backup(_cur_dpi, &_vd.dpi);
@ -1833,11 +1830,11 @@ void ViewportDoDraw(const Viewport *vp, int left, int top, int right, int bottom
dp.height = UnScaleByZoom(dp.height, zoom); dp.height = UnScaleByZoom(dp.height, zoom);
AutoRestoreBackup cur_dpi(_cur_dpi, &dp); AutoRestoreBackup cur_dpi(_cur_dpi, &dp);
if (vp->overlay != nullptr && vp->overlay->GetCargoMask() != 0 && vp->overlay->GetCompanyMask().Any()) { if (vp.overlay != nullptr && vp.overlay->GetCargoMask() != 0 && vp.overlay->GetCompanyMask().Any()) {
/* translate to window coordinates */ /* translate to window coordinates */
dp.left = x; dp.left = x;
dp.top = y; dp.top = y;
vp->overlay->Draw(&dp); vp.overlay->Draw(&dp);
} }
if (!_vd.string_sprites_to_draw.empty()) { if (!_vd.string_sprites_to_draw.empty()) {
@ -1854,25 +1851,25 @@ void ViewportDoDraw(const Viewport *vp, int left, int top, int right, int bottom
_vd.child_screen_sprites_to_draw.clear(); _vd.child_screen_sprites_to_draw.clear();
} }
static inline void ViewportDraw(const Viewport *vp, int left, int top, int right, int bottom) static inline void ViewportDraw(const Viewport &vp, int left, int top, int right, int bottom)
{ {
if (right <= vp->left || bottom <= vp->top) return; if (right <= vp.left || bottom <= vp.top) return;
if (left >= vp->left + vp->width) return; if (left >= vp.left + vp.width) return;
if (left < vp->left) left = vp->left; if (left < vp.left) left = vp.left;
if (right > vp->left + vp->width) right = vp->left + vp->width; if (right > vp.left + vp.width) right = vp.left + vp.width;
if (top >= vp->top + vp->height) return; if (top >= vp.top + vp.height) return;
if (top < vp->top) top = vp->top; if (top < vp.top) top = vp.top;
if (bottom > vp->top + vp->height) bottom = vp->top + vp->height; if (bottom > vp.top + vp.height) bottom = vp.top + vp.height;
ViewportDoDraw(vp, ViewportDoDraw(vp,
ScaleByZoom(left - vp->left, vp->zoom) + vp->virtual_left, ScaleByZoom(left - vp.left, vp.zoom) + vp.virtual_left,
ScaleByZoom(top - vp->top, vp->zoom) + vp->virtual_top, ScaleByZoom(top - vp.top, vp.zoom) + vp.virtual_top,
ScaleByZoom(right - vp->left, vp->zoom) + vp->virtual_left, ScaleByZoom(right - vp.left, vp.zoom) + vp.virtual_left,
ScaleByZoom(bottom - vp->top, vp->zoom) + vp->virtual_top ScaleByZoom(bottom - vp.top, vp.zoom) + vp.virtual_top
); );
} }
@ -1888,7 +1885,7 @@ void Window::DrawViewport() const
dpi->left += this->left; dpi->left += this->left;
dpi->top += this->top; dpi->top += this->top;
ViewportDraw(this->viewport, dpi->left, dpi->top, dpi->left + dpi->width, dpi->top + dpi->height); ViewportDraw(*this->viewport, dpi->left, dpi->top, dpi->left + dpi->width, dpi->top + dpi->height);
dpi->left -= this->left; dpi->left -= this->left;
dpi->top -= this->top; dpi->top -= this->top;
@ -1904,12 +1901,12 @@ void Window::DrawViewport() const
* @param[in,out] scroll_x Viewport X scroll. * @param[in,out] scroll_x Viewport X scroll.
* @param[in,out] scroll_y Viewport Y scroll. * @param[in,out] scroll_y Viewport Y scroll.
*/ */
static inline void ClampViewportToMap(const Viewport *vp, int *scroll_x, int *scroll_y) static inline void ClampViewportToMap(const Viewport &vp, int *scroll_x, int *scroll_y)
{ {
/* Centre of the viewport is hot spot. */ /* Centre of the viewport is hot spot. */
Point pt = { Point pt = {
*scroll_x + vp->virtual_width / 2, *scroll_x + vp.virtual_width / 2,
*scroll_y + vp->virtual_height / 2 *scroll_y + vp.virtual_height / 2
}; };
/* Find nearest tile that is within borders of the map. */ /* Find nearest tile that is within borders of the map. */
@ -1919,8 +1916,8 @@ static inline void ClampViewportToMap(const Viewport *vp, int *scroll_x, int *sc
if (clamped) { if (clamped) {
/* Convert back to viewport coordinates and remove centering. */ /* Convert back to viewport coordinates and remove centering. */
pt = RemapCoords2(pt.x, pt.y); pt = RemapCoords2(pt.x, pt.y);
*scroll_x = pt.x - vp->virtual_width / 2; *scroll_x = pt.x - vp.virtual_width / 2;
*scroll_y = pt.y - vp->virtual_height / 2; *scroll_y = pt.y - vp.virtual_height / 2;
} }
} }
@ -1966,24 +1963,24 @@ static void ClampSmoothScroll(uint32_t delta_ms, int64_t delta_hi, int64_t delta
*/ */
void UpdateViewportPosition(Window *w, uint32_t delta_ms) void UpdateViewportPosition(Window *w, uint32_t delta_ms)
{ {
const Viewport *vp = w->viewport; ViewportData &vp = *w->viewport;
if (w->viewport->follow_vehicle != VehicleID::Invalid()) { if (vp.follow_vehicle != VehicleID::Invalid()) {
const Vehicle *veh = Vehicle::Get(w->viewport->follow_vehicle); const Vehicle *veh = Vehicle::Get(vp.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; vp.scrollpos_x = pt.x;
w->viewport->scrollpos_y = pt.y; vp.scrollpos_y = pt.y;
SetViewportPosition(w, pt.x, pt.y); SetViewportPosition(w, pt.x, pt.y);
} 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, &vp.dest_scrollpos_x, &vp.dest_scrollpos_y);
int delta_x = w->viewport->dest_scrollpos_x - w->viewport->scrollpos_x; int delta_x = vp.dest_scrollpos_x - vp.scrollpos_x;
int delta_y = w->viewport->dest_scrollpos_y - w->viewport->scrollpos_y; int delta_y = vp.dest_scrollpos_y - vp.scrollpos_y;
int current_x = w->viewport->scrollpos_x; int current_x = vp.scrollpos_x;
int current_y = w->viewport->scrollpos_y; int current_y = vp.scrollpos_y;
bool update_overlay = false; bool update_overlay = false;
if (delta_x != 0 || delta_y != 0) { if (delta_x != 0 || delta_y != 0) {
@ -1997,26 +1994,26 @@ void UpdateViewportPosition(Window *w, uint32_t delta_ms)
ClampSmoothScroll(delta_ms, delta_y, delta_x, delta_y_clamped, delta_x_clamped); ClampSmoothScroll(delta_ms, delta_y, delta_x, delta_y_clamped, delta_x_clamped);
} }
w->viewport->scrollpos_x += delta_x_clamped; vp.scrollpos_x += delta_x_clamped;
w->viewport->scrollpos_y += delta_y_clamped; vp.scrollpos_y += delta_y_clamped;
} else { } else {
w->viewport->scrollpos_x = w->viewport->dest_scrollpos_x; vp.scrollpos_x = vp.dest_scrollpos_x;
w->viewport->scrollpos_y = w->viewport->dest_scrollpos_y; vp.scrollpos_y = vp.dest_scrollpos_y;
} }
update_overlay = (w->viewport->scrollpos_x == w->viewport->dest_scrollpos_x && update_overlay = (vp.scrollpos_x == vp.dest_scrollpos_x &&
w->viewport->scrollpos_y == w->viewport->dest_scrollpos_y); vp.scrollpos_y == vp.dest_scrollpos_y);
} }
ClampViewportToMap(vp, &w->viewport->scrollpos_x, &w->viewport->scrollpos_y); ClampViewportToMap(vp, &vp.scrollpos_x, &vp.scrollpos_y);
/* When moving small amounts around the border we can get stuck, and /* When moving small amounts around the border we can get stuck, and
* not actually move. In those cases, teleport to the destination. */ * not actually move. In those cases, teleport to the destination. */
if ((delta_x != 0 || delta_y != 0) && current_x == w->viewport->scrollpos_x && current_y == w->viewport->scrollpos_y) { if ((delta_x != 0 || delta_y != 0) && current_x == vp.scrollpos_x && current_y == vp.scrollpos_y) {
w->viewport->scrollpos_x = w->viewport->dest_scrollpos_x; vp.scrollpos_x = vp.dest_scrollpos_x;
w->viewport->scrollpos_y = w->viewport->dest_scrollpos_y; vp.scrollpos_y = vp.dest_scrollpos_y;
} }
SetViewportPosition(w, w->viewport->scrollpos_x, w->viewport->scrollpos_y); SetViewportPosition(w, vp.scrollpos_x, vp.scrollpos_y);
if (update_overlay) RebuildViewportOverlay(w); if (update_overlay) RebuildViewportOverlay(w);
} }
} }
@ -2031,31 +2028,31 @@ void UpdateViewportPosition(Window *w, uint32_t delta_ms)
* @return true if the viewport contains a dirty block * @return true if the viewport contains a dirty block
* @ingroup dirty * @ingroup dirty
*/ */
static bool MarkViewportDirty(const Viewport *vp, int left, int top, int right, int bottom) static bool MarkViewportDirty(const Viewport &vp, int left, int top, int right, int bottom)
{ {
/* Rounding wrt. zoom-out level */ /* Rounding wrt. zoom-out level */
right += (1 << vp->zoom) - 1; right += (1 << vp.zoom) - 1;
bottom += (1 << vp->zoom) - 1; bottom += (1 << vp.zoom) - 1;
right -= vp->virtual_left; right -= vp.virtual_left;
if (right <= 0) return false; if (right <= 0) return false;
bottom -= vp->virtual_top; bottom -= vp.virtual_top;
if (bottom <= 0) return false; if (bottom <= 0) return false;
left = std::max(0, left - vp->virtual_left); left = std::max(0, left - vp.virtual_left);
if (left >= vp->virtual_width) return false; if (left >= vp.virtual_width) return false;
top = std::max(0, top - vp->virtual_top); top = std::max(0, top - vp.virtual_top);
if (top >= vp->virtual_height) return false; if (top >= vp.virtual_height) return false;
AddDirtyBlock( AddDirtyBlock(
UnScaleByZoomLower(left, vp->zoom) + vp->left, UnScaleByZoomLower(left, vp.zoom) + vp.left,
UnScaleByZoomLower(top, vp->zoom) + vp->top, UnScaleByZoomLower(top, vp.zoom) + vp.top,
UnScaleByZoom(right, vp->zoom) + vp->left + 1, UnScaleByZoom(right, vp.zoom) + vp.left + 1,
UnScaleByZoom(bottom, vp->zoom) + vp->top + 1 UnScaleByZoom(bottom, vp.zoom) + vp.top + 1
); );
return true; return true;
@ -2075,10 +2072,9 @@ bool MarkAllViewportsDirty(int left, int top, int right, int bottom)
bool dirty = false; bool dirty = false;
for (const Window *w : Window::Iterate()) { for (const Window *w : Window::Iterate()) {
Viewport *vp = w->viewport; if (w->viewport != nullptr) {
if (vp != nullptr) { assert(w->viewport->width != 0);
assert(vp->width != 0); if (MarkViewportDirty(*w->viewport, left, top, right, bottom)) dirty = true;
if (MarkViewportDirty(vp, left, top, right, bottom)) dirty = true;
} }
} }
@ -2247,11 +2243,11 @@ void SetSelectionRed(bool b)
* @param sign the sign to check * @param sign the sign to check
* @return true if the sign was hit * @return true if the sign was hit
*/ */
static bool CheckClickOnViewportSign(const Viewport *vp, int x, int y, const ViewportSign *sign) static bool CheckClickOnViewportSign(const Viewport &vp, int x, int y, const ViewportSign *sign)
{ {
bool small = (vp->zoom >= ZOOM_LVL_OUT_4X); bool small = (vp.zoom >= ZOOM_LVL_OUT_4X);
int sign_half_width = ScaleByZoom((small ? sign->width_small : sign->width_normal) / 2, vp->zoom); int sign_half_width = ScaleByZoom((small ? sign->width_small : sign->width_normal) / 2, vp.zoom);
int sign_height = ScaleByZoom(WidgetDimensions::scaled.fullbevel.top + GetCharacterHeight(small ? FS_SMALL : FS_NORMAL) + WidgetDimensions::scaled.fullbevel.bottom, vp->zoom); int sign_height = ScaleByZoom(WidgetDimensions::scaled.fullbevel.top + GetCharacterHeight(small ? FS_SMALL : FS_NORMAL) + WidgetDimensions::scaled.fullbevel.bottom, vp.zoom);
return y >= sign->top && y < sign->top + sign_height && return y >= sign->top && y < sign->top + sign_height &&
x >= sign->center - sign_half_width && x < sign->center + sign_half_width; x >= sign->center - sign_half_width && x < sign->center + sign_half_width;
@ -2265,15 +2261,15 @@ static bool CheckClickOnViewportSign(const Viewport *vp, int x, int y, const Vie
* @param y Y position of click * @param y Y position of click
* @return true if the sign was hit * @return true if the sign was hit
*/ */
static bool CheckClickOnViewportSign(const Viewport *vp, int x, int y) static bool CheckClickOnViewportSign(const Viewport &vp, int x, int y)
{ {
if (_game_mode == GM_MENU) return false; if (_game_mode == GM_MENU) return false;
x = ScaleByZoom(x - vp->left, vp->zoom) + vp->virtual_left; x = ScaleByZoom(x - vp.left, vp.zoom) + vp.virtual_left;
y = ScaleByZoom(y - vp->top, vp->zoom) + vp->virtual_top; y = ScaleByZoom(y - vp.top, vp.zoom) + vp.virtual_top;
Rect search_rect{ x - 1, y - 1, x + 1, y + 1 }; Rect search_rect{ x - 1, y - 1, x + 1, y + 1 };
search_rect = ExpandRectWithViewportSignMargins(search_rect, vp->zoom); search_rect = ExpandRectWithViewportSignMargins(search_rect, vp.zoom);
bool show_stations = HasBit(_display_opt, DO_SHOW_STATION_NAMES) && !IsInvisibilitySet(TO_SIGNS); bool show_stations = HasBit(_display_opt, DO_SHOW_STATION_NAMES) && !IsInvisibilitySet(TO_SIGNS);
bool show_waypoints = HasBit(_display_opt, DO_SHOW_WAYPOINT_NAMES) && !IsInvisibilitySet(TO_SIGNS); bool show_waypoints = HasBit(_display_opt, DO_SHOW_WAYPOINT_NAMES) && !IsInvisibilitySet(TO_SIGNS);
@ -2437,7 +2433,7 @@ void RebuildViewportKdtree()
} }
static bool CheckClickOnLandscape(const Viewport *vp, int x, int y) static bool CheckClickOnLandscape(const Viewport &vp, int x, int y)
{ {
Point pt = TranslateXYToTileCoord(vp, x, y); Point pt = TranslateXYToTileCoord(vp, x, y);
@ -2466,7 +2462,7 @@ static void PlaceObject()
} }
bool HandleViewportClicked(const Viewport *vp, int x, int y) bool HandleViewportClicked(const Viewport &vp, int x, int y)
{ {
const Vehicle *v = CheckClickOnVehicle(vp, x, y); const Vehicle *v = CheckClickOnVehicle(vp, x, y);
@ -2529,7 +2525,7 @@ bool ScrollWindowTo(int x, int y, int z, Window *w, bool instant)
} }
} }
Point pt = MapXYZToViewport(w->viewport, x, y, z); Point pt = MapXYZToViewport(*w->viewport, x, y, z);
w->viewport->CancelFollow(*w); w->viewport->CancelFollow(*w);
if (w->viewport->dest_scrollpos_x == pt.x && w->viewport->dest_scrollpos_y == pt.y) return false; if (w->viewport->dest_scrollpos_x == pt.x && w->viewport->dest_scrollpos_y == pt.y) return false;
@ -3549,15 +3545,15 @@ void ResetObjectToPlace()
SetObjectToPlace(SPR_CURSOR_MOUSE, PAL_NONE, HT_NONE, WC_MAIN_WINDOW, 0); SetObjectToPlace(SPR_CURSOR_MOUSE, PAL_NONE, HT_NONE, WC_MAIN_WINDOW, 0);
} }
Point GetViewportStationMiddle(const Viewport *vp, const Station *st) Point GetViewportStationMiddle(const Viewport &vp, const Station *st)
{ {
int x = TileX(st->xy) * TILE_SIZE; int x = TileX(st->xy) * TILE_SIZE;
int y = TileY(st->xy) * TILE_SIZE; int y = TileY(st->xy) * TILE_SIZE;
int z = GetSlopePixelZ(Clamp(x, 0, Map::SizeX() * TILE_SIZE - 1), Clamp(y, 0, Map::SizeY() * TILE_SIZE - 1)); int z = GetSlopePixelZ(Clamp(x, 0, Map::SizeX() * TILE_SIZE - 1), Clamp(y, 0, Map::SizeY() * TILE_SIZE - 1));
Point p = RemapCoords(x, y, z); Point p = RemapCoords(x, y, z);
p.x = UnScaleByZoom(p.x - vp->virtual_left, vp->zoom) + vp->left; p.x = UnScaleByZoom(p.x - vp.virtual_left, vp.zoom) + vp.left;
p.y = UnScaleByZoom(p.y - vp->virtual_top, vp->zoom) + vp->top; p.y = UnScaleByZoom(p.y - vp.virtual_top, vp.zoom) + vp.top;
return p; return p;
} }

View File

@ -24,7 +24,7 @@ void SetSelectionRed(bool);
void DeleteWindowViewport(Window *w); void DeleteWindowViewport(Window *w);
void InitializeWindowViewport(Window *w, int x, int y, int width, int height, std::variant<TileIndex, VehicleID> focus, ZoomLevel zoom); void InitializeWindowViewport(Window *w, int x, int y, int width, int height, std::variant<TileIndex, VehicleID> focus, ZoomLevel zoom);
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, uint32_t delta_ms); void UpdateViewportPosition(Window *w, uint32_t delta_ms);
@ -35,7 +35,7 @@ void ZoomInOrOutToCursorWindow(bool in, Window * w);
void ConstrainAllViewportsZoom(); void ConstrainAllViewportsZoom();
Point GetTileZoomCenterWindow(bool in, Window * w); Point GetTileZoomCenterWindow(bool in, Window * w);
void FixTitleGameZoom(int zoom_adjust = 0); void FixTitleGameZoom(int zoom_adjust = 0);
void HandleZoomMessage(Window *w, const Viewport *vp, WidgetID widget_zoom_in, WidgetID widget_zoom_out); void HandleZoomMessage(Window *w, const Viewport &vp, WidgetID widget_zoom_in, WidgetID widget_zoom_out);
/** /**
* Zoom a viewport as far as possible in the given direction. * Zoom a viewport as far as possible in the given direction.
@ -60,12 +60,12 @@ std::string *ViewportAddString(const DrawPixelInfo *dpi, const ViewportSign *sig
void StartSpriteCombine(); void StartSpriteCombine();
void EndSpriteCombine(); void EndSpriteCombine();
bool HandleViewportClicked(const Viewport *vp, int x, int y); bool HandleViewportClicked(const Viewport &vp, int x, int y);
void SetRedErrorSquare(TileIndex tile); void SetRedErrorSquare(TileIndex tile);
void SetTileSelectSize(int w, int h); void SetTileSelectSize(int w, int h);
void SetTileSelectBigSize(int ox, int oy, int sx, int sy); void SetTileSelectBigSize(int ox, int oy, int sx, int sy);
void ViewportDoDraw(const Viewport *vp, int left, int top, int right, int bottom); void ViewportDoDraw(const Viewport &vp, int left, int top, int right, int bottom);
bool ScrollWindowToTile(TileIndex tile, Window *w, bool instant = false); bool ScrollWindowToTile(TileIndex tile, Window *w, bool instant = false);
bool ScrollWindowTo(int x, int y, int z, Window *w, bool instant = false); bool ScrollWindowTo(int x, int y, int z, Window *w, bool instant = false);
@ -93,7 +93,7 @@ inline void MarkTileDirtyByTile(TileIndex tile, int bridge_level_offset = 0)
MarkTileDirtyByTile(tile, bridge_level_offset, TileHeight(tile)); MarkTileDirtyByTile(tile, bridge_level_offset, TileHeight(tile));
} }
Point GetViewportStationMiddle(const Viewport *vp, const Station *st); Point GetViewportStationMiddle(const Viewport &vp, const Station *st);
struct Station; struct Station;
struct Waypoint; struct Waypoint;

View File

@ -140,7 +140,7 @@ public:
{ {
if (!gui_scope) return; if (!gui_scope) return;
/* Only handle zoom message if intended for us (msg ZOOM_IN/ZOOM_OUT) */ /* Only handle zoom message if intended for us (msg ZOOM_IN/ZOOM_OUT) */
HandleZoomMessage(this, this->viewport, WID_EV_ZOOM_IN, WID_EV_ZOOM_OUT); HandleZoomMessage(this, *this->viewport, WID_EV_ZOOM_IN, WID_EV_ZOOM_OUT);
} }
}; };

View File

@ -2425,16 +2425,16 @@ void NWidgetViewport::InitializeViewport(Window *w, std::variant<TileIndex, Vehi
*/ */
void NWidgetViewport::UpdateViewportCoordinates(Window *w) void NWidgetViewport::UpdateViewportCoordinates(Window *w)
{ {
Viewport *vp = w->viewport; if (w->viewport == nullptr) return;
if (vp != nullptr) {
vp->left = w->left + this->pos_x;
vp->top = w->top + this->pos_y;
vp->width = this->current_x;
vp->height = this->current_y;
vp->virtual_width = ScaleByZoom(vp->width, vp->zoom); Viewport &vp = *w->viewport;
vp->virtual_height = ScaleByZoom(vp->height, vp->zoom); vp.left = w->left + this->pos_x;
} vp.top = w->top + this->pos_y;
vp.width = this->current_x;
vp.height = this->current_y;
vp.virtual_width = ScaleByZoom(vp.width, vp.zoom);
vp.virtual_height = ScaleByZoom(vp.height, vp.zoom);
} }
/** /**

View File

@ -2834,7 +2834,7 @@ static void MouseLoop(MouseClick click, int mousewheel)
switch (click) { switch (click) {
case MC_DOUBLE_LEFT: case MC_DOUBLE_LEFT:
case MC_LEFT: case MC_LEFT:
if (HandleViewportClicked(vp, x, y)) return; if (HandleViewportClicked(*vp, x, y)) return;
if (!w->flags.Test(WindowFlag::DisableVpScroll) && if (!w->flags.Test(WindowFlag::DisableVpScroll) &&
_settings_client.gui.scroll_mode == VSM_MAP_LMB) { _settings_client.gui.scroll_mode == VSM_MAP_LMB) {
_scrolling_viewport = true; _scrolling_viewport = true;