|
|
|
@ -631,32 +631,12 @@ static const byte _vehicle_type_colours[6] = {
|
|
|
|
|
InvalidateWindowClassesData(WC_INDUSTRY_CARGOES, NUM_INDUSTRYTYPES);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
inline Point SmallMapWindow::SmallmapRemapCoords(int x, int y) const
|
|
|
|
|
inline Point SmallMapWindow::TileToPixel(int tx, int ty) const
|
|
|
|
|
{
|
|
|
|
|
Point pt;
|
|
|
|
|
pt.x = (y - x) * 2;
|
|
|
|
|
pt.y = y + x;
|
|
|
|
|
return pt;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Remap tile to location on this smallmap.
|
|
|
|
|
* @param tile_x X coordinate of the tile.
|
|
|
|
|
* @param tile_y Y coordinate of the tile.
|
|
|
|
|
* @return Position to draw on.
|
|
|
|
|
*/
|
|
|
|
|
inline Point SmallMapWindow::RemapTile(int tile_x, int tile_y) const
|
|
|
|
|
{
|
|
|
|
|
int x_offset = tile_x - this->scroll_x / (int)TILE_SIZE;
|
|
|
|
|
int y_offset = tile_y - this->scroll_y / (int)TILE_SIZE;
|
|
|
|
|
|
|
|
|
|
if (this->zoom == 1) return SmallmapRemapCoords(x_offset, y_offset);
|
|
|
|
|
|
|
|
|
|
/* For negative offsets, round towards -inf. */
|
|
|
|
|
if (x_offset < 0) x_offset -= this->zoom - 1;
|
|
|
|
|
if (y_offset < 0) y_offset -= this->zoom - 1;
|
|
|
|
|
|
|
|
|
|
return SmallmapRemapCoords(x_offset / this->zoom, y_offset / this->zoom);
|
|
|
|
|
return {
|
|
|
|
|
(ty - tx) * 2 / this->zoom + this->scroll_x,
|
|
|
|
|
(ty + tx) / this->zoom + this->scroll_y,
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
@ -664,63 +644,16 @@ inline Point SmallMapWindow::RemapTile(int tile_x, int tile_y) const
|
|
|
|
|
* that tile for a point in the smallmap.
|
|
|
|
|
* @param px Horizontal coordinate of the pixel.
|
|
|
|
|
* @param py Vertical coordinate of the pixel.
|
|
|
|
|
* @param[out] sub Pixel position at the tile (0..3).
|
|
|
|
|
* @param add_sub Add current #subscroll to the position.
|
|
|
|
|
* @return Tile being displayed at the given position relative to #scroll_x and #scroll_y.
|
|
|
|
|
* @note The #subscroll offset is already accounted for.
|
|
|
|
|
*/
|
|
|
|
|
inline Point SmallMapWindow::PixelToTile(int px, int py, int *sub, bool add_sub) const
|
|
|
|
|
inline Point SmallMapWindow::PixelToTile(int px, int py) const
|
|
|
|
|
{
|
|
|
|
|
if (add_sub) px += this->subscroll; // Total horizontal offset.
|
|
|
|
|
|
|
|
|
|
/* For each two rows down, add a x and a y tile, and
|
|
|
|
|
* For each four pixels to the right, move a tile to the right. */
|
|
|
|
|
Point pt = {((py >> 1) - (px >> 2)) * this->zoom, ((py >> 1) + (px >> 2)) * this->zoom};
|
|
|
|
|
px &= 3;
|
|
|
|
|
px -= this->scroll_x;
|
|
|
|
|
py -= this->scroll_y;
|
|
|
|
|
|
|
|
|
|
if (py & 1) { // Odd number of rows, handle the 2 pixel shift.
|
|
|
|
|
if (px < 2) {
|
|
|
|
|
pt.x += this->zoom;
|
|
|
|
|
px += 2;
|
|
|
|
|
} else {
|
|
|
|
|
pt.y += this->zoom;
|
|
|
|
|
px -= 2;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
*sub = px;
|
|
|
|
|
return pt;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Compute base parameters of the smallmap such that tile (\a tx, \a ty) starts at pixel (\a x, \a y).
|
|
|
|
|
* @param tx Tile x coordinate.
|
|
|
|
|
* @param ty Tile y coordinate.
|
|
|
|
|
* @param x Non-negative horizontal position in the display where the tile starts.
|
|
|
|
|
* @param y Non-negative vertical position in the display where the tile starts.
|
|
|
|
|
* @param[out] sub Value of #subscroll needed.
|
|
|
|
|
* @return #scroll_x, #scroll_y values.
|
|
|
|
|
*/
|
|
|
|
|
Point SmallMapWindow::ComputeScroll(int tx, int ty, int x, int y, int *sub)
|
|
|
|
|
{
|
|
|
|
|
assert(x >= 0 && y >= 0);
|
|
|
|
|
|
|
|
|
|
int new_sub;
|
|
|
|
|
Point tile_xy = PixelToTile(x, y, &new_sub, false);
|
|
|
|
|
tx -= tile_xy.x;
|
|
|
|
|
ty -= tile_xy.y;
|
|
|
|
|
|
|
|
|
|
Point scroll;
|
|
|
|
|
if (new_sub == 0) {
|
|
|
|
|
*sub = 0;
|
|
|
|
|
scroll.x = (tx + this->zoom) * TILE_SIZE;
|
|
|
|
|
scroll.y = (ty - this->zoom) * TILE_SIZE;
|
|
|
|
|
} else {
|
|
|
|
|
*sub = 4 - new_sub;
|
|
|
|
|
scroll.x = (tx + 2 * this->zoom) * TILE_SIZE;
|
|
|
|
|
scroll.y = (ty - 2 * this->zoom) * TILE_SIZE;
|
|
|
|
|
}
|
|
|
|
|
return scroll;
|
|
|
|
|
return {
|
|
|
|
|
(py * 2 - px) * this->zoom / 4,
|
|
|
|
|
(py * 2 + px) * this->zoom / 4,
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
@ -731,27 +664,28 @@ Point SmallMapWindow::ComputeScroll(int tx, int ty, int x, int y, int *sub)
|
|
|
|
|
*/
|
|
|
|
|
void SmallMapWindow::SetZoomLevel(ZoomLevelChange change, const Point *zoom_pt)
|
|
|
|
|
{
|
|
|
|
|
static const int zoomlevels[] = {1, 2, 4, 6, 8}; // Available zoom levels. Bigger number means more zoom-out (further away).
|
|
|
|
|
static const int tile_zoomlevels[] = {1, 1, 1, 2, 4, 6, 8}; // Available zoom levels. Bigger number means more zoom-out (further away).
|
|
|
|
|
static const int ui_zoomlevels[] = {4, 2, 1, 1, 1, 1, 1};
|
|
|
|
|
static const int MIN_ZOOM_INDEX = 0;
|
|
|
|
|
static const int MAX_ZOOM_INDEX = lengthof(zoomlevels) - 1;
|
|
|
|
|
static const int MAX_ZOOM_INDEX = lengthof(tile_zoomlevels) - 1;
|
|
|
|
|
|
|
|
|
|
int new_index, cur_index, sub;
|
|
|
|
|
int new_index, cur_index;
|
|
|
|
|
Point tile;
|
|
|
|
|
switch (change) {
|
|
|
|
|
case ZLC_INITIALIZE:
|
|
|
|
|
cur_index = - 1; // Definitely different from new_index.
|
|
|
|
|
new_index = MIN_ZOOM_INDEX;
|
|
|
|
|
new_index = Clamp((int)ZOOM_LVL_GUI, MIN_ZOOM_INDEX, MAX_ZOOM_INDEX);
|
|
|
|
|
tile.x = tile.y = 0;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case ZLC_ZOOM_IN:
|
|
|
|
|
case ZLC_ZOOM_OUT:
|
|
|
|
|
for (cur_index = MIN_ZOOM_INDEX; cur_index <= MAX_ZOOM_INDEX; cur_index++) {
|
|
|
|
|
if (this->zoom == zoomlevels[cur_index]) break;
|
|
|
|
|
if (this->tile_zoom == tile_zoomlevels[cur_index] && this->ui_zoom == ui_zoomlevels[cur_index]) break;
|
|
|
|
|
}
|
|
|
|
|
assert(cur_index <= MAX_ZOOM_INDEX);
|
|
|
|
|
|
|
|
|
|
tile = this->PixelToTile(zoom_pt->x, zoom_pt->y, &sub);
|
|
|
|
|
tile = this->PixelToTile(zoom_pt->x, zoom_pt->y);
|
|
|
|
|
new_index = Clamp(cur_index + ((change == ZLC_ZOOM_IN) ? -1 : 1), MIN_ZOOM_INDEX, MAX_ZOOM_INDEX);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
@ -759,14 +693,16 @@ void SmallMapWindow::SetZoomLevel(ZoomLevelChange change, const Point *zoom_pt)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (new_index != cur_index) {
|
|
|
|
|
this->zoom = zoomlevels[new_index];
|
|
|
|
|
this->tile_zoom = tile_zoomlevels[new_index];
|
|
|
|
|
this->ui_zoom = ui_zoomlevels[new_index];
|
|
|
|
|
this->zoom = this->tile_zoom * TILE_SIZE / this->ui_zoom;
|
|
|
|
|
if (cur_index >= 0) {
|
|
|
|
|
Point new_tile = this->PixelToTile(zoom_pt->x, zoom_pt->y, &sub);
|
|
|
|
|
this->SetNewScroll(this->scroll_x + (tile.x - new_tile.x) * TILE_SIZE,
|
|
|
|
|
this->scroll_y + (tile.y - new_tile.y) * TILE_SIZE, sub);
|
|
|
|
|
Point new_tile = this->TileToPixel(tile.x, tile.y);
|
|
|
|
|
this->scroll_x += zoom_pt->x - new_tile.x;
|
|
|
|
|
this->scroll_y += zoom_pt->y - new_tile.y;
|
|
|
|
|
}
|
|
|
|
|
this->SetWidgetDisabledState(WID_SM_ZOOM_IN, this->zoom == zoomlevels[MIN_ZOOM_INDEX]);
|
|
|
|
|
this->SetWidgetDisabledState(WID_SM_ZOOM_OUT, this->zoom == zoomlevels[MAX_ZOOM_INDEX]);
|
|
|
|
|
this->SetWidgetDisabledState(WID_SM_ZOOM_IN, this->ui_zoom == ui_zoomlevels[MIN_ZOOM_INDEX]);
|
|
|
|
|
this->SetWidgetDisabledState(WID_SM_ZOOM_OUT, this->tile_zoom == tile_zoomlevels[MAX_ZOOM_INDEX]);
|
|
|
|
|
this->SetDirty();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -865,11 +801,15 @@ inline uint32 SmallMapWindow::GetTileColours(const TileArea &ta) const
|
|
|
|
|
* @param blitter current blitter
|
|
|
|
|
* @note If pixel position is below \c 0, skip drawing.
|
|
|
|
|
*/
|
|
|
|
|
void SmallMapWindow::DrawSmallMapColumn(void *dst, uint xc, uint yc, int pitch, int reps, int start_pos, int end_pos, Blitter *blitter) const
|
|
|
|
|
void SmallMapWindow::DrawSmallMapColumn(void *dst, uint xc, uint yc, int pitch, int reps, int start_pos, int end_pos, int y, int end_y, Blitter *blitter) const
|
|
|
|
|
{
|
|
|
|
|
void *dst_ptr_abs_end = blitter->MoveTo(_screen.dst_ptr, 0, _screen.height);
|
|
|
|
|
uint min_xy = _settings_game.construction.freeform_edges ? 1 : 0;
|
|
|
|
|
|
|
|
|
|
int hidden_x = std::max(0, -start_pos);
|
|
|
|
|
int hidden_idx = hidden_x / this->ui_zoom;
|
|
|
|
|
int hidden_mod = hidden_x % this->ui_zoom;
|
|
|
|
|
|
|
|
|
|
do {
|
|
|
|
|
/* Check if the tile (xc,yc) is within the map range */
|
|
|
|
|
if (xc >= MapMaxX() || yc >= MapMaxY()) continue;
|
|
|
|
@ -881,23 +821,47 @@ void SmallMapWindow::DrawSmallMapColumn(void *dst, uint xc, uint yc, int pitch,
|
|
|
|
|
/* Construct tilearea covered by (xc, yc, xc + this->zoom, yc + this->zoom) such that it is within min_xy limits. */
|
|
|
|
|
TileArea ta;
|
|
|
|
|
if (min_xy == 1 && (xc == 0 || yc == 0)) {
|
|
|
|
|
if (this->zoom == 1) continue; // The tile area is empty, don't draw anything.
|
|
|
|
|
|
|
|
|
|
ta = TileArea(TileXY(std::max(min_xy, xc), std::max(min_xy, yc)), this->zoom - (xc == 0), this->zoom - (yc == 0));
|
|
|
|
|
if (this->tile_zoom == 1) continue; // The tile area is empty, don't draw anything.
|
|
|
|
|
ta = TileArea(TileXY(std::max(min_xy, xc), std::max(min_xy, yc)), this->tile_zoom - (xc == 0), this->tile_zoom - (yc == 0));
|
|
|
|
|
} else {
|
|
|
|
|
ta = TileArea(TileXY(xc, yc), this->zoom, this->zoom);
|
|
|
|
|
ta = TileArea(TileXY(xc, yc), this->tile_zoom, this->tile_zoom);
|
|
|
|
|
}
|
|
|
|
|
ta.ClampToMap(); // Clamp to map boundaries (may contain MP_VOID tiles!).
|
|
|
|
|
|
|
|
|
|
uint32 val = this->GetTileColours(ta);
|
|
|
|
|
uint8 *val8 = (uint8 *)&val;
|
|
|
|
|
int idx = std::max(0, -start_pos);
|
|
|
|
|
for (int pos = std::max(0, start_pos); pos < end_pos; pos++) {
|
|
|
|
|
blitter->SetPixel(dst, idx, 0, val8[idx]);
|
|
|
|
|
idx++;
|
|
|
|
|
if (this->ui_zoom == 1) {
|
|
|
|
|
int idx = std::max(0, -start_pos);
|
|
|
|
|
if (y >= 0 && y < end_y) {
|
|
|
|
|
for (int pos = std::max(0, start_pos); pos < end_pos; pos++) {
|
|
|
|
|
blitter->SetPixel(dst, idx, 0, val8[idx]);
|
|
|
|
|
idx++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
auto ndst = dst;
|
|
|
|
|
auto ny = y;
|
|
|
|
|
for (auto i = 0; i < this->ui_zoom; i++) {
|
|
|
|
|
if (ny >= 0 && ny < end_y) {
|
|
|
|
|
int idx = hidden_idx;
|
|
|
|
|
int j = hidden_mod;
|
|
|
|
|
int x = hidden_x;
|
|
|
|
|
for (int pos = std::max(0, start_pos); pos < end_pos; pos++) {
|
|
|
|
|
blitter->SetPixel(ndst, x, 0, val8[idx]);
|
|
|
|
|
j++;
|
|
|
|
|
x++;
|
|
|
|
|
if (j == this->ui_zoom) {
|
|
|
|
|
idx++;
|
|
|
|
|
j = 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
ndst = blitter->MoveTo(ndst, pitch, 0);
|
|
|
|
|
ny++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
/* Switch to next tile in the column */
|
|
|
|
|
} while (xc += this->zoom, yc += this->zoom, dst = blitter->MoveTo(dst, pitch, 0), --reps != 0);
|
|
|
|
|
} while (xc += this->tile_zoom, yc += this->tile_zoom, dst = blitter->MoveTo(dst, pitch * this->ui_zoom * 2, 0), y += 2 * this->ui_zoom, --reps != 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
@ -912,30 +876,23 @@ void SmallMapWindow::DrawVehicles(const DrawPixelInfo *dpi, Blitter *blitter) co
|
|
|
|
|
if (v->vehstatus & (VS_HIDDEN | VS_UNCLICKABLE)) continue;
|
|
|
|
|
|
|
|
|
|
/* Remap into flat coordinates. */
|
|
|
|
|
Point pt = this->RemapTile(v->x_pos / (int)TILE_SIZE, v->y_pos / (int)TILE_SIZE);
|
|
|
|
|
Point pt = this->TileToPixel(v->x_pos & ~TILE_UNIT_MASK, v->y_pos & ~TILE_UNIT_MASK);
|
|
|
|
|
|
|
|
|
|
int y = pt.y - dpi->top;
|
|
|
|
|
if (!IsInsideMM(y, 0, dpi->height)) continue; // y is out of bounds.
|
|
|
|
|
|
|
|
|
|
bool skip = false; // Default is to draw both pixels.
|
|
|
|
|
int x = pt.x - this->subscroll - 3 - dpi->left; // Offset X coordinate.
|
|
|
|
|
if (x < 0) {
|
|
|
|
|
/* if x+1 is 0, that means we're on the very left edge,
|
|
|
|
|
* and should thus only draw a single pixel */
|
|
|
|
|
if (++x != 0) continue;
|
|
|
|
|
skip = true;
|
|
|
|
|
} else if (x >= dpi->width - 1) {
|
|
|
|
|
/* Check if we're at the very right edge, and if so draw only a single pixel */
|
|
|
|
|
if (x != dpi->width - 1) continue;
|
|
|
|
|
skip = true;
|
|
|
|
|
}
|
|
|
|
|
int x = pt.x - 1 * this->ui_zoom - dpi->left; // Offset X coordinate.
|
|
|
|
|
if (!IsInsideMM(y, -this->ui_zoom + 1, dpi->height)) continue; // y is out of bounds.
|
|
|
|
|
|
|
|
|
|
/* Calculate pointer to pixel and the colour */
|
|
|
|
|
byte colour = (this->map_type == SMT_VEHICLES) ? _vehicle_type_colours[v->type] : PC_WHITE;
|
|
|
|
|
|
|
|
|
|
/* And draw either one or two pixels depending on clipping */
|
|
|
|
|
blitter->SetPixel(dpi->dst_ptr, x, y, colour);
|
|
|
|
|
if (!skip) blitter->SetPixel(dpi->dst_ptr, x + 1, y, colour);
|
|
|
|
|
auto min_i = std::max(0, -y);
|
|
|
|
|
auto max_i = std::min(this->ui_zoom, dpi->height - y);
|
|
|
|
|
auto min_j = std::max(0, -x);
|
|
|
|
|
auto max_j = std::min(2 * this->ui_zoom, dpi->width - x);
|
|
|
|
|
if (min_i < max_i && min_j < max_j) {
|
|
|
|
|
blitter->DrawRectAt(dpi->dst_ptr, x + min_j, y + min_i, max_j - min_j, max_i - min_i, colour);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -947,8 +904,8 @@ void SmallMapWindow::DrawTowns(const DrawPixelInfo *dpi) const
|
|
|
|
|
{
|
|
|
|
|
for (const Town *t : Town::Iterate()) {
|
|
|
|
|
/* Remap the town coordinate */
|
|
|
|
|
Point pt = this->RemapTile(TileX(t->xy), TileY(t->xy));
|
|
|
|
|
int x = pt.x - this->subscroll - (t->cache.sign.width_small >> 1);
|
|
|
|
|
Point pt = this->TileToPixel(TileX(t->xy) * TILE_SIZE, TileY(t->xy) * TILE_SIZE);
|
|
|
|
|
int x = pt.x - (t->cache.sign.width_small >> 1);
|
|
|
|
|
int y = pt.y;
|
|
|
|
|
|
|
|
|
|
/* Check if the town sign is within bounds */
|
|
|
|
@ -974,11 +931,8 @@ void SmallMapWindow::DrawMapIndicators() const
|
|
|
|
|
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 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;
|
|
|
|
|
|
|
|
|
|
Point lower_right = this->RemapTile(lower_right_smallmap_coord.x / (int)TILE_SIZE, lower_right_smallmap_coord.y / (int)TILE_SIZE);
|
|
|
|
|
lower_right.x -= this->subscroll;
|
|
|
|
|
Point upper_left = this->TileToPixel(upper_left_smallmap_coord.x, upper_left_smallmap_coord.y);
|
|
|
|
|
Point lower_right = this->TileToPixel(lower_right_smallmap_coord.x, lower_right_smallmap_coord.y);
|
|
|
|
|
|
|
|
|
|
SmallMapWindow::DrawVertMapIndicator(upper_left.x, upper_left.y, lower_right.y);
|
|
|
|
|
SmallMapWindow::DrawVertMapIndicator(lower_right.x, upper_left.y, lower_right.y);
|
|
|
|
@ -1010,38 +964,43 @@ void SmallMapWindow::DrawSmallMap(DrawPixelInfo *dpi, bool draw_indicators) cons
|
|
|
|
|
GfxFillRect(dpi->left, dpi->top, dpi->left + dpi->width - 1, dpi->top + dpi->height - 1, PC_BLACK);
|
|
|
|
|
|
|
|
|
|
/* Which tile is displayed at (dpi->left, dpi->top)? */
|
|
|
|
|
int dx;
|
|
|
|
|
Point tile = this->PixelToTile(dpi->left, dpi->top, &dx);
|
|
|
|
|
int tile_x = this->scroll_x / (int)TILE_SIZE + tile.x;
|
|
|
|
|
int tile_y = this->scroll_y / (int)TILE_SIZE + tile.y;
|
|
|
|
|
|
|
|
|
|
void *ptr = blitter->MoveTo(dpi->dst_ptr, -dx - 4, 0);
|
|
|
|
|
int x = - dx - 4;
|
|
|
|
|
int y = 0;
|
|
|
|
|
Point tile = this->PixelToTile(dpi->left, dpi->top);
|
|
|
|
|
int tile_x = tile.x / (int)TILE_SIZE + this->tile_zoom;
|
|
|
|
|
int tile_y = tile.y / (int)TILE_SIZE - 2 * this->tile_zoom;
|
|
|
|
|
tile_x -= tile_x % this->tile_zoom;
|
|
|
|
|
tile_y -= tile_y % this->tile_zoom;
|
|
|
|
|
Point tile_pos = this->TileToPixel(tile_x * TILE_SIZE, tile_y * TILE_SIZE);
|
|
|
|
|
int dx = tile_pos.x - dpi->left;
|
|
|
|
|
int dy = tile_pos.y - dpi->top;
|
|
|
|
|
|
|
|
|
|
int x = dx - 2 * this->ui_zoom;
|
|
|
|
|
int y = dy;
|
|
|
|
|
void *ptr = blitter->MoveTo(dpi->dst_ptr, x, y);
|
|
|
|
|
bool even = true;
|
|
|
|
|
|
|
|
|
|
for (;;) {
|
|
|
|
|
/* Distance from left edge */
|
|
|
|
|
if (x >= -3) {
|
|
|
|
|
if (x > -4 * this->ui_zoom) {
|
|
|
|
|
if (x >= dpi->width) break; // Exit the loop.
|
|
|
|
|
|
|
|
|
|
int end_pos = std::min(dpi->width, x + 4);
|
|
|
|
|
int reps = (dpi->height - y + 1) / 2; // Number of lines.
|
|
|
|
|
int end_pos = std::min(dpi->width, x + 4 * this->ui_zoom);
|
|
|
|
|
int reps = (dpi->height - y + 3 * this->ui_zoom - 1) / 2 / this->ui_zoom; // Number of lines.
|
|
|
|
|
if (reps > 0) {
|
|
|
|
|
this->DrawSmallMapColumn(ptr, tile_x, tile_y, dpi->pitch * 2, reps, x, end_pos, blitter);
|
|
|
|
|
this->DrawSmallMapColumn(ptr, tile_x, tile_y, dpi->pitch, reps, x, end_pos, y, dpi->height, blitter);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (y == 0) {
|
|
|
|
|
tile_y += this->zoom;
|
|
|
|
|
y++;
|
|
|
|
|
ptr = blitter->MoveTo(ptr, 0, 1);
|
|
|
|
|
if (even) {
|
|
|
|
|
tile_y += this->tile_zoom;
|
|
|
|
|
y += this->ui_zoom;
|
|
|
|
|
ptr = blitter->MoveTo(ptr, 0, this->ui_zoom);
|
|
|
|
|
} else {
|
|
|
|
|
tile_x -= this->zoom;
|
|
|
|
|
y--;
|
|
|
|
|
ptr = blitter->MoveTo(ptr, 0, -1);
|
|
|
|
|
tile_x -= this->tile_zoom;
|
|
|
|
|
y -= this->ui_zoom;
|
|
|
|
|
ptr = blitter->MoveTo(ptr, 0, -this->ui_zoom);
|
|
|
|
|
}
|
|
|
|
|
ptr = blitter->MoveTo(ptr, 2, 0);
|
|
|
|
|
x += 2;
|
|
|
|
|
even = !even;
|
|
|
|
|
ptr = blitter->MoveTo(ptr, 2 * this->ui_zoom, 0);
|
|
|
|
|
x += 2 * this->ui_zoom;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Draw vehicles */
|
|
|
|
@ -1462,10 +1421,8 @@ int SmallMapWindow::GetPositionOnLegend(Point pt)
|
|
|
|
|
|
|
|
|
|
const NWidgetBase *wid = this->GetWidget<NWidgetBase>(WID_SM_MAP);
|
|
|
|
|
Window *w = GetMainWindow();
|
|
|
|
|
int sub;
|
|
|
|
|
pt = this->PixelToTile(pt.x - wid->pos_x, pt.y - wid->pos_y, &sub);
|
|
|
|
|
ScrollWindowTo(this->scroll_x + pt.x * TILE_SIZE, this->scroll_y + pt.y * TILE_SIZE, -1, w);
|
|
|
|
|
|
|
|
|
|
pt = this->PixelToTile(pt.x - wid->pos_x, pt.y - wid->pos_y);
|
|
|
|
|
ScrollWindowTo(pt.x, pt.y, -1, w);
|
|
|
|
|
this->SetDirty();
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
@ -1652,13 +1609,13 @@ uint SmallMapWindow::GetRefreshPeriod() const
|
|
|
|
|
switch (map_type) {
|
|
|
|
|
case SMT_CONTOUR:
|
|
|
|
|
case SMT_VEHICLES:
|
|
|
|
|
return FORCE_REFRESH_PERIOD_VEH * (1 + (this->zoom / 2));
|
|
|
|
|
return FORCE_REFRESH_PERIOD_VEH * (1 + (this->tile_zoom / 2));
|
|
|
|
|
|
|
|
|
|
case SMT_LINKSTATS:
|
|
|
|
|
return FORCE_REFRESH_PERIOD_LINK_GRAPH * (1 + (this->zoom / 6));
|
|
|
|
|
return FORCE_REFRESH_PERIOD_LINK_GRAPH * (1 + (this->tile_zoom / 6));
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
return FORCE_REFRESH_PERIOD * (1 + (this->zoom / 6));
|
|
|
|
|
return FORCE_REFRESH_PERIOD * (1 + (this->tile_zoom / 6));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -1679,51 +1636,12 @@ uint SmallMapWindow::PausedAdjustRefreshTimeDelta(uint delta_ms) const
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Set new #scroll_x, #scroll_y, and #subscroll values after limiting them such that the center
|
|
|
|
|
* of the smallmap always contains a part of the map.
|
|
|
|
|
* @param sx Proposed new #scroll_x
|
|
|
|
|
* @param sy Proposed new #scroll_y
|
|
|
|
|
* @param sub Proposed new #subscroll
|
|
|
|
|
*/
|
|
|
|
|
void SmallMapWindow::SetNewScroll(int sx, int sy, int sub)
|
|
|
|
|
{
|
|
|
|
|
const NWidgetBase *wi = this->GetWidget<NWidgetBase>(WID_SM_MAP);
|
|
|
|
|
Point hv = InverseRemapCoords(wi->current_x * ZOOM_LVL_BASE * TILE_SIZE / 2, wi->current_y * ZOOM_LVL_BASE * TILE_SIZE / 2);
|
|
|
|
|
hv.x *= this->zoom;
|
|
|
|
|
hv.y *= this->zoom;
|
|
|
|
|
|
|
|
|
|
if (sx < -hv.x) {
|
|
|
|
|
sx = -hv.x;
|
|
|
|
|
sub = 0;
|
|
|
|
|
}
|
|
|
|
|
if (sx > (int)(MapMaxX() * TILE_SIZE) - hv.x) {
|
|
|
|
|
sx = MapMaxX() * TILE_SIZE - hv.x;
|
|
|
|
|
sub = 0;
|
|
|
|
|
}
|
|
|
|
|
if (sy < -hv.y) {
|
|
|
|
|
sy = -hv.y;
|
|
|
|
|
sub = 0;
|
|
|
|
|
}
|
|
|
|
|
if (sy > (int)(MapMaxY() * TILE_SIZE) - hv.y) {
|
|
|
|
|
sy = MapMaxY() * TILE_SIZE - hv.y;
|
|
|
|
|
sub = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
this->scroll_x = sx;
|
|
|
|
|
this->scroll_y = sy;
|
|
|
|
|
this->subscroll = sub;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* virtual */ void SmallMapWindow::OnScroll(Point delta)
|
|
|
|
|
{
|
|
|
|
|
if (_settings_client.gui.scroll_mode == VSM_VIEWPORT_RMB_FIXED || _settings_client.gui.scroll_mode == VSM_MAP_RMB_FIXED) _cursor.fix_at = true;
|
|
|
|
|
|
|
|
|
|
/* While tile is at (delta.x, delta.y)? */
|
|
|
|
|
int sub;
|
|
|
|
|
Point pt = this->PixelToTile(delta.x, delta.y, &sub);
|
|
|
|
|
this->SetNewScroll(this->scroll_x + pt.x * TILE_SIZE, this->scroll_y + pt.y * TILE_SIZE, sub);
|
|
|
|
|
|
|
|
|
|
this->scroll_x -= delta.x;
|
|
|
|
|
this->scroll_y -= delta.y;
|
|
|
|
|
this->SetDirty();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -1735,11 +1653,10 @@ void SmallMapWindow::SmallMapCenterOnCurrentPos()
|
|
|
|
|
const Viewport *vp = GetMainWindow()->viewport;
|
|
|
|
|
Point viewport_center = InverseRemapCoords2(vp->virtual_left + vp->virtual_width / 2, vp->virtual_top + vp->virtual_height / 2);
|
|
|
|
|
|
|
|
|
|
int sub;
|
|
|
|
|
const NWidgetBase *wid = this->GetWidget<NWidgetBase>(WID_SM_MAP);
|
|
|
|
|
Point sxy = this->ComputeScroll(viewport_center.x / (int)TILE_SIZE, viewport_center.y / (int)TILE_SIZE,
|
|
|
|
|
std::max(0, (int)wid->current_x / 2 - 2), wid->current_y / 2, &sub);
|
|
|
|
|
this->SetNewScroll(sxy.x, sxy.y, sub);
|
|
|
|
|
auto pt = this->TileToPixel(viewport_center.x, viewport_center.y);
|
|
|
|
|
this->scroll_x += std::max(0, (int)wid->current_x / 2 - 2) - pt.x;
|
|
|
|
|
this->scroll_y += wid->current_y / 2 - pt.y;
|
|
|
|
|
this->SetDirty();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -1750,14 +1667,14 @@ void SmallMapWindow::SmallMapCenterOnCurrentPos()
|
|
|
|
|
*/
|
|
|
|
|
Point SmallMapWindow::GetStationMiddle(const Station *st) const
|
|
|
|
|
{
|
|
|
|
|
int x = CenterBounds(st->rect.left, st->rect.right, 0);
|
|
|
|
|
int y = CenterBounds(st->rect.top, st->rect.bottom, 0);
|
|
|
|
|
Point ret = this->RemapTile(x, y);
|
|
|
|
|
int x = (st->rect.right + st->rect.left + 1) * TILE_SIZE / 2;
|
|
|
|
|
int y = (st->rect.bottom + st->rect.top + 1) * TILE_SIZE / 2;
|
|
|
|
|
Point ret = this->TileToPixel(x, y);
|
|
|
|
|
|
|
|
|
|
/* Same magic 3 as in DrawVehicles; that's where I got it from.
|
|
|
|
|
* No idea what it is, but without it the result looks bad.
|
|
|
|
|
*/
|
|
|
|
|
ret.x -= 3 + this->subscroll;
|
|
|
|
|
ret.x -= 3;
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -1767,17 +1684,14 @@ Point SmallMapWindow::GetStationMiddle(const Station *st) const
|
|
|
|
|
*/
|
|
|
|
|
void SmallMapWindow::TakeScreenshot()
|
|
|
|
|
{
|
|
|
|
|
int32 width = ((MapMaxX() + MapMaxY()) * 2) / this->zoom;
|
|
|
|
|
int32 height = (MapMaxX() + MapMaxY() + 1) / this->zoom;
|
|
|
|
|
int32 width = (((MapMaxX() + MapMaxY()) * 2) * this->ui_zoom) / this->tile_zoom;
|
|
|
|
|
int32 height = ((MapMaxX() + MapMaxY() + 1) * this->ui_zoom) / this->tile_zoom;
|
|
|
|
|
|
|
|
|
|
int32 saved_scroll_x = this->scroll_x;
|
|
|
|
|
int32 saved_scroll_y = this->scroll_y;
|
|
|
|
|
int32 saved_subscroll = this->subscroll;
|
|
|
|
|
this->subscroll = 0;
|
|
|
|
|
MakeSmallMapScreenshot(width, height, this);
|
|
|
|
|
this->scroll_x = saved_scroll_x;
|
|
|
|
|
this->scroll_y = saved_scroll_y;
|
|
|
|
|
this->subscroll = saved_subscroll;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
@ -1806,7 +1720,7 @@ void SmallMapWindow::ScreenshotCallbackHandler(void *buf, uint y, uint pitch, ui
|
|
|
|
|
|
|
|
|
|
dpi.dst_ptr = buf;
|
|
|
|
|
dpi.height = n;
|
|
|
|
|
dpi.width = ((MapMaxX() + MapMaxY()) * 2) / this->zoom;
|
|
|
|
|
dpi.width = (((MapMaxX() + MapMaxY()) * 2) * this->ui_zoom) / this->tile_zoom;
|
|
|
|
|
dpi.pitch = pitch;
|
|
|
|
|
dpi.zoom = ZOOM_LVL_NORMAL;
|
|
|
|
|
dpi.left = 0;
|
|
|
|
|