175 void InitializeWindowViewport(Window *w, int x, int y, |
175 void InitializeWindowViewport(Window *w, int x, int y, |
176 int width, int height, uint32 follow_flags, ZoomLevel zoom) |
176 int width, int height, uint32 follow_flags, ZoomLevel zoom) |
177 { |
177 { |
178 assert(w->viewport == NULL); |
178 assert(w->viewport == NULL); |
179 |
179 |
180 ViewPort *vp = &(WP(w, vp_d).vp_data); |
180 ViewportData *vp = CallocT<ViewportData>(1); |
181 |
181 |
182 vp->left = x + w->left; |
182 vp->left = x + w->left; |
183 vp->top = y + w->top; |
183 vp->top = y + w->top; |
184 vp->width = width; |
184 vp->width = width; |
185 vp->height = height; |
185 vp->height = height; |
192 Point pt; |
192 Point pt; |
193 |
193 |
194 if (follow_flags & 0x80000000) { |
194 if (follow_flags & 0x80000000) { |
195 const Vehicle *veh; |
195 const Vehicle *veh; |
196 |
196 |
197 WP(w, vp_d).follow_vehicle = (VehicleID)(follow_flags & 0xFFFF); |
197 vp->follow_vehicle = (VehicleID)(follow_flags & 0xFFFF); |
198 veh = GetVehicle(WP(w, vp_d).follow_vehicle); |
198 veh = GetVehicle(vp->follow_vehicle); |
199 pt = MapXYZToViewport(vp, veh->x_pos, veh->y_pos, veh->z_pos); |
199 pt = MapXYZToViewport(vp, veh->x_pos, veh->y_pos, veh->z_pos); |
200 } else { |
200 } else { |
201 uint x = TileX(follow_flags) * TILE_SIZE; |
201 uint x = TileX(follow_flags) * TILE_SIZE; |
202 uint y = TileY(follow_flags) * TILE_SIZE; |
202 uint y = TileY(follow_flags) * TILE_SIZE; |
203 |
203 |
204 WP(w, vp_d).follow_vehicle = INVALID_VEHICLE; |
204 vp->follow_vehicle = INVALID_VEHICLE; |
205 pt = MapXYZToViewport(vp, x, y, GetSlopeZ(x, y)); |
205 pt = MapXYZToViewport(vp, x, y, GetSlopeZ(x, y)); |
206 } |
206 } |
207 |
207 |
208 WP(w, vp_d).scrollpos_x = pt.x; |
208 vp->scrollpos_x = pt.x; |
209 WP(w, vp_d).scrollpos_y = pt.y; |
209 vp->scrollpos_y = pt.y; |
210 WP(w, vp_d).dest_scrollpos_x = pt.x; |
210 vp->dest_scrollpos_x = pt.x; |
211 WP(w, vp_d).dest_scrollpos_y = pt.y; |
211 vp->dest_scrollpos_y = pt.y; |
212 |
212 |
213 w->viewport = vp; |
213 w->viewport = vp; |
214 vp->virtual_left = 0;//pt.x; |
214 vp->virtual_left = 0;//pt.x; |
215 vp->virtual_top = 0;//pt.y; |
215 vp->virtual_top = 0;//pt.y; |
216 } |
216 } |
1579 |
1577 |
1580 void UpdateViewportPosition(Window *w) |
1578 void UpdateViewportPosition(Window *w) |
1581 { |
1579 { |
1582 const ViewPort *vp = w->viewport; |
1580 const ViewPort *vp = w->viewport; |
1583 |
1581 |
1584 if (WP(w, vp_d).follow_vehicle != INVALID_VEHICLE) { |
1582 if (w->viewport->follow_vehicle != INVALID_VEHICLE) { |
1585 const Vehicle* veh = GetVehicle(WP(w, vp_d).follow_vehicle); |
1583 const Vehicle* veh = GetVehicle(w->viewport->follow_vehicle); |
1586 Point pt = MapXYZToViewport(vp, veh->x_pos, veh->y_pos, veh->z_pos); |
1584 Point pt = MapXYZToViewport(vp, veh->x_pos, veh->y_pos, veh->z_pos); |
1587 |
1585 |
1588 SetViewportPosition(w, pt.x, pt.y); |
1586 SetViewportPosition(w, pt.x, pt.y); |
1589 } else { |
1587 } else { |
1590 /* Ensure the destination location is within the map */ |
1588 /* Ensure the destination location is within the map */ |
1591 ClampViewportToMap(vp, WP(w, vp_d).dest_scrollpos_x, WP(w, vp_d).dest_scrollpos_y); |
1589 ClampViewportToMap(vp, w->viewport->dest_scrollpos_x, w->viewport->dest_scrollpos_y); |
1592 |
1590 |
1593 int delta_x = WP(w, vp_d).dest_scrollpos_x - WP(w, vp_d).scrollpos_x; |
1591 int delta_x = w->viewport->dest_scrollpos_x - w->viewport->scrollpos_x; |
1594 int delta_y = WP(w, vp_d).dest_scrollpos_y - WP(w, vp_d).scrollpos_y; |
1592 int delta_y = w->viewport->dest_scrollpos_y - w->viewport->scrollpos_y; |
1595 |
1593 |
1596 if (delta_x != 0 || delta_y != 0) { |
1594 if (delta_x != 0 || delta_y != 0) { |
1597 if (_patches.smooth_scroll) { |
1595 if (_patches.smooth_scroll) { |
1598 int max_scroll = ScaleByMapSize1D(512); |
1596 int max_scroll = ScaleByMapSize1D(512); |
1599 /* Not at our desired positon yet... */ |
1597 /* Not at our desired positon yet... */ |
1600 WP(w, vp_d).scrollpos_x += Clamp(delta_x / 4, -max_scroll, max_scroll); |
1598 w->viewport->scrollpos_x += Clamp(delta_x / 4, -max_scroll, max_scroll); |
1601 WP(w, vp_d).scrollpos_y += Clamp(delta_y / 4, -max_scroll, max_scroll); |
1599 w->viewport->scrollpos_y += Clamp(delta_y / 4, -max_scroll, max_scroll); |
1602 } else { |
1600 } else { |
1603 WP(w, vp_d).scrollpos_x = WP(w, vp_d).dest_scrollpos_x; |
1601 w->viewport->scrollpos_x = w->viewport->dest_scrollpos_x; |
1604 WP(w, vp_d).scrollpos_y = WP(w, vp_d).dest_scrollpos_y; |
1602 w->viewport->scrollpos_y = w->viewport->dest_scrollpos_y; |
1605 } |
1603 } |
1606 } |
1604 } |
1607 |
1605 |
1608 ClampViewportToMap(vp, WP(w, vp_d).scrollpos_x, WP(w, vp_d).scrollpos_y); |
1606 ClampViewportToMap(vp, w->viewport->scrollpos_x, w->viewport->scrollpos_y); |
1609 |
1607 |
1610 SetViewportPosition(w, WP(w, vp_d).scrollpos_x, WP(w, vp_d).scrollpos_y); |
1608 SetViewportPosition(w, w->viewport->scrollpos_x, w->viewport->scrollpos_y); |
1611 } |
1609 } |
1612 } |
1610 } |
1613 |
1611 |
1614 /** |
1612 /** |
1615 * Marks a viewport as dirty for repaint if it displays (a part of) the area the needs to be repainted. |
1613 * Marks a viewport as dirty for repaint if it displays (a part of) the area the needs to be repainted. |
2064 /* scrolls the viewport in a window to a given location */ |
2062 /* scrolls the viewport in a window to a given location */ |
2065 bool ScrollWindowTo(int x , int y, Window *w, bool instant) |
2063 bool ScrollWindowTo(int x , int y, Window *w, bool instant) |
2066 { |
2064 { |
2067 /* The slope cannot be acquired outside of the map, so make sure we are always within the map. */ |
2065 /* The slope cannot be acquired outside of the map, so make sure we are always within the map. */ |
2068 Point pt = MapXYZToViewport(w->viewport, x, y, GetSlopeZ(Clamp(x, 0, MapSizeX()), Clamp(y, 0, MapSizeY()))); |
2066 Point pt = MapXYZToViewport(w->viewport, x, y, GetSlopeZ(Clamp(x, 0, MapSizeX()), Clamp(y, 0, MapSizeY()))); |
2069 WP(w, vp_d).follow_vehicle = INVALID_VEHICLE; |
2067 w->viewport->follow_vehicle = INVALID_VEHICLE; |
2070 |
2068 |
2071 if (WP(w, vp_d).dest_scrollpos_x == pt.x && WP(w, vp_d).dest_scrollpos_y == pt.y) |
2069 if (w->viewport->dest_scrollpos_x == pt.x && w->viewport->dest_scrollpos_y == pt.y) |
2072 return false; |
2070 return false; |
2073 |
2071 |
2074 if (instant) { |
2072 if (instant) { |
2075 WP(w, vp_d).scrollpos_x = pt.x; |
2073 w->viewport->scrollpos_x = pt.x; |
2076 WP(w, vp_d).scrollpos_y = pt.y; |
2074 w->viewport->scrollpos_y = pt.y; |
2077 } |
2075 } |
2078 |
2076 |
2079 WP(w, vp_d).dest_scrollpos_x = pt.x; |
2077 w->viewport->dest_scrollpos_x = pt.x; |
2080 WP(w, vp_d).dest_scrollpos_y = pt.y; |
2078 w->viewport->dest_scrollpos_y = pt.y; |
2081 return true; |
2079 return true; |
2082 } |
2080 } |
2083 |
2081 |
2084 |
2082 |
2085 bool ScrollMainWindowTo(int x, int y, bool instant) |
2083 bool ScrollMainWindowTo(int x, int y, bool instant) |