84#include "viewport_kdtree.h"
94#include <forward_list>
97#include "table/strings.h"
102Point _tile_fract_coords;
106static int _viewport_sign_maxwidth = 0;
159typedef std::vector<TileSpriteToDraw> TileSpriteToDrawVector;
160typedef std::vector<StringSpriteToDraw> StringSpriteToDrawVector;
161typedef std::vector<ParentSpriteToDraw> ParentSpriteToDrawVector;
162typedef std::vector<ChildScreenSpriteToDraw> ChildScreenSpriteToDrawVector;
171 StringSpriteToDrawVector string_sprites_to_draw;
172 TileSpriteToDrawVector tile_sprites_to_draw;
173 ParentSpriteToDrawVector parent_sprites_to_draw;
175 ChildScreenSpriteToDrawVector child_screen_sprites_to_draw;
193bool _draw_bounding_boxes =
false;
194bool _draw_dirty_blocks =
false;
195uint _dirty_block_colour = 0;
198static Point MapXYZToViewport(
const Viewport *vp,
int x,
int y,
int z)
206void DeleteWindowViewport(
Window *w)
223 int width,
int height, std::variant<TileIndex, VehicleID> focus,
ZoomLevel zoom)
241 if (std::holds_alternative<VehicleID>(focus)) {
248 TileIndex tile = std::get<TileIndex>(focus);
271 vp->overlay =
nullptr;
278static Point _vp_move_offs;
282 for (; !it.IsEnd(); ++it) {
284 if (left + width > w->
left &&
286 top + height > w->
top &&
289 if (left < w->left) {
290 DoSetViewportPosition(it, left, top, w->
left - left, height);
291 DoSetViewportPosition(it, left + (w->
left - left), top, width - (w->
left - left), height);
296 DoSetViewportPosition(it, left, top, (w->
left + w->
width - left), height);
297 DoSetViewportPosition(it, left + (w->
left + w->
width - left), top, width - (w->
left + w->
width - left), height);
302 DoSetViewportPosition(it, left, top, width, (w->
top - top));
303 DoSetViewportPosition(it, left, top + (w->
top - top), width, height - (w->
top - top));
308 DoSetViewportPosition(it, left, top, width, (w->
top + w->
height - top));
309 DoSetViewportPosition(it, left, top + (w->
top + w->
height - top), width, height - (w->
top + w->
height - top));
318 int xo = _vp_move_offs.x;
319 int yo = _vp_move_offs.y;
321 if (
abs(xo) >= width ||
abs(yo) >= height) {
327 GfxScroll(left, top, width, height, xo, yo);
346static void SetViewportPosition(
Window *w,
int x,
int y)
352 int left, top, width, height;
368 if (old_top == 0 && old_left == 0)
return;
370 _vp_move_offs.x = old_left;
371 _vp_move_offs.y = old_top;
383 i = left + width - _screen.width;
384 if (i >= 0) width -= i;
392 i = top + height - _screen.height;
393 if (i >= 0) height -= i;
398 DoSetViewportPosition(it, left, top, width, height);
438 Point pt = { -1, -1 };
450static Point GetTileFromScreenXY(
int x,
int y,
int zoom_x,
int zoom_y)
464Point GetTileBelowCursor()
466 return GetTileFromScreenXY(_cursor.
pos.x, _cursor.
pos.y, _cursor.
pos.x, _cursor.
pos.y);
476 x = ((_cursor.
pos.x - vp->
left) >> 1) + (vp->
width >> 2);
477 y = ((_cursor.
pos.y - vp->
top) >> 1) + (vp->
height >> 2);
483 return GetTileFromScreenXY(_cursor.
pos.x, _cursor.
pos.y, x + vp->
left, y + vp->
top);
524 ts.
x = pt.x + extra_offs_x;
525 ts.
y = pt.y + extra_offs_y;
542 assert(
IsInsideMM(foundation_part, 0, FOUNDATION_PART_END));
543 assert(_vd.
foundation[foundation_part] != -1);
548 AddChildSpriteScreen(image, pal, offs.x + extra_offs_x, offs.y + extra_offs_y,
false, sub,
false,
false);
573 AddTileSpriteToDraw(image, pal, _cur_ti.
x + x, _cur_ti.
y + y, _cur_ti.
z + z, sub, extra_offs_x * ZOOM_BASE, extra_offs_y * ZOOM_BASE);
609 default: NOT_REACHED();
636 if (pt.x + spr->
x_offs >= _vd.dpi.left + _vd.dpi.width ||
638 pt.y + spr->
y_offs >= _vd.dpi.top + _vd.dpi.height ||
671void AddSortableSpriteToDraw(
SpriteID image,
PaletteID pal,
int x,
int y,
int w,
int h,
int dz,
int z,
bool transparent,
int bb_offset_x,
int bb_offset_y,
int bb_offset_z,
const SubSprite *sub)
673 int32_t left, right, top, bottom;
691 int tmp_left, tmp_top, tmp_x = pt.x, tmp_y = pt.y;
694 if (image == SPR_EMPTY_BOUNDING_BOX) {
695 left = tmp_left =
RemapCoords(x + w , y + bb_offset_y, z + bb_offset_z).x;
696 right =
RemapCoords(x + bb_offset_x, y + h , z + bb_offset_z).x + 1;
697 top = tmp_top =
RemapCoords(x + bb_offset_x, y + bb_offset_y, z + dz ).y;
698 bottom =
RemapCoords(x + w , y + h , z + bb_offset_z).y + 1;
701 left = tmp_left = (pt.x += spr->
x_offs);
702 right = (pt.x + spr->
width );
703 top = tmp_top = (pt.y += spr->
y_offs);
704 bottom = (pt.y + spr->
height);
707 if (_draw_bounding_boxes && (image != SPR_EMPTY_BOUNDING_BOX)) {
709 left = std::min(left ,
RemapCoords(x + w , y + bb_offset_y, z + bb_offset_z).x);
710 right = std::max(right ,
RemapCoords(x + bb_offset_x, y + h , z + bb_offset_z).x + 1);
711 top = std::min(top ,
RemapCoords(x + bb_offset_x, y + bb_offset_y, z + dz ).y);
712 bottom = std::max(bottom,
RemapCoords(x + w , y + h , z + bb_offset_z).y + 1);
716 if (left >= _vd.dpi.left + _vd.dpi.width ||
717 right <= _vd.dpi.left ||
718 top >= _vd.dpi.top + _vd.dpi.height ||
719 bottom <= _vd.dpi.top) {
733 ps.
xmin = x + bb_offset_x;
734 ps.
xmax = x + std::max(bb_offset_x, w) - 1;
736 ps.
ymin = y + bb_offset_y;
737 ps.
ymax = y + std::max(bb_offset_y, h) - 1;
739 ps.
zmin = z + bb_offset_z;
740 ps.
zmax = z + std::max(bb_offset_z, dz) - 1;
794 if (begin > end)
Swap(begin, end);
795 return begin <= check && check <= end;
806 int dist_a = (_thd.
size.x + _thd.
size.y);
807 int dist_b = (_thd.
size.x - _thd.
size.y);
808 int a = ((x - _thd.
pos.x) + (y - _thd.
pos.y));
809 int b = ((x - _thd.
pos.x) - (y - _thd.
pos.y));
840 int32_t child_id =
static_cast<int32_t
>(_vd.child_screen_sprites_to_draw.size());
842 _vd.child_screen_sprites_to_draw[_vd.last_child].next = child_id;
844 _vd.parent_sprites_to_draw.back().first_child = child_id;
851 cs.x = scale ? x * ZOOM_BASE : x;
852 cs.y = scale ? y * ZOOM_BASE : y;
853 cs.relative = relative;
861 _vd.last_child = child_id;
864static void AddStringToDraw(
int x,
int y,
StringID string, Colours colour, uint16_t width)
869 ss.string_id = string;
915 SpriteID sel2 = SPR_HALFTILE_SELECTION_FLAT + halftile_corner;
920 sel = SPR_HALFTILE_SELECTION_DOWN;
924 sel += opposite_corner;
931static bool IsPartOfAutoLine(
int px,
int py)
941 case HT_DIR_HU:
return px == -py || px == -py - 16;
942 case HT_DIR_HL:
return px == -py || px == -py + 16;
943 case HT_DIR_VL:
return px == py || px == py + 16;
944 case HT_DIR_VR:
return px == py || px == py - 16;
977 static const uint _lower_rail[4] = { 5U, 2U, 4U, 3U };
979 if (autorail_type != _lower_rail[halftile_corner]) {
986 offset = _AutorailTilehSprite[autorail_tileh][autorail_type];
988 image = SPR_AUTORAIL_BASE + offset;
991 image = SPR_AUTORAIL_BASE - offset;
998enum TileHighlightType {
1027 TileHighlightType type = THT_RED;
1030 if (st->TileIsInCatchment(t))
return THT_BLUE;
1054 case THT_NONE:
break;
1069 if (_town_local_authority_kdtree.
Count() == 0)
return;
1135 if ((halftile_corner == CORNER_W) || (halftile_corner == CORNER_E)) z +=
TILE_HEIGHT;
1136 if (halftile_corner != CORNER_S) {
1147 }
else if (IsPartOfAutoLine(ti->
x, ti->
y)) {
1165 if (!is_redsq && (tht == THT_NONE || tht == THT_RED) && _thd.
outersize.x > 0 &&
1191 assert(_vd.dpi.top <= _vd.dpi.top + _vd.dpi.height);
1192 assert(_vd.dpi.left <= _vd.dpi.left + _vd.dpi.width);
1210 int left_column = (upper_left.y - upper_left.x) / (
int)
TILE_SIZE - 2;
1211 int right_column = (upper_right.y - upper_right.x) / (
int)
TILE_SIZE + 2;
1219 int row = (upper_left.x + upper_left.y) / (
int)
TILE_SIZE - 2;
1220 bool last_row =
false;
1221 for (; !last_row; row++) {
1223 for (
int column = left_column; column <= right_column; column++) {
1225 if ((row + column) % 2 != 0)
continue;
1228 tilecoord.x = (row - column) / 2;
1229 tilecoord.y = (row + column) / 2;
1230 assert(column == tilecoord.y - tilecoord.x);
1231 assert(row == tilecoord.y + tilecoord.x);
1239 _cur_ti.
tile =
TileXY(tilecoord.x, tilecoord.y);
1263 int min_visible_height = viewport_y - (_vd.dpi.top + _vd.dpi.height);
1264 bool tile_visible = min_visible_height <= 0;
1283 if ((tilecoord.x <= 0 || tilecoord.y <= 0) && min_visible_height < potential_bridge_height +
MAX_TILE_EXTENT_TOP) last_row =
false;
1313 bool small = dpi->zoom >= small_from;
1315 int left = dpi->left;
1317 int right = left + dpi->width;
1318 int bottom = top + dpi->height;
1323 if (bottom < sign->top ||
1324 top > sign->
top + sign_height ||
1325 right < sign->center - sign_half_width ||
1326 left > sign->
center + sign_half_width) {
1331 AddStringToDraw(sign->
center - sign_half_width, sign->
top, string_normal, colour, sign->
width_normal);
1333 int shadow_offset = 0;
1334 if (string_small_shadow != STR_NULL) {
1336 AddStringToDraw(sign->
center - sign_half_width + shadow_offset, sign->
top, string_small_shadow, INVALID_COLOUR, sign->
width_small | 0x8000);
1338 AddStringToDraw(sign->
center - sign_half_width, sign->
top - shadow_offset, string_small, colour, sign->
width_small | 0x8000);
1345 const int max_tw = _viewport_sign_maxwidth / 2 + 1;
1350 r.right += expand_x;
1352 r.bottom += expand_y;
1359 Rect search_rect{ dpi->left, dpi->top, dpi->left + dpi->width, dpi->top + dpi->height };
1360 search_rect = ExpandRectWithViewportSignMargins(search_rect, dpi->zoom);
1369 std::vector<const BaseStation *> stations;
1370 std::vector<const Town *> towns;
1371 std::vector<const Sign *> signs;
1374 switch (item.type) {
1375 case ViewportSignKdtreeItem::VKI_STATION: {
1376 if (!show_stations) break;
1377 const BaseStation *st = BaseStation::Get(item.id.station);
1380 if (!show_competitors && _local_company != st->owner && st->owner != OWNER_NONE) break;
1382 stations.push_back(st);
1386 case ViewportSignKdtreeItem::VKI_WAYPOINT: {
1387 if (!show_waypoints) break;
1388 const BaseStation *st = BaseStation::Get(item.id.station);
1391 if (!show_competitors && _local_company != st->owner && st->owner != OWNER_NONE) break;
1393 stations.push_back(st);
1397 case ViewportSignKdtreeItem::VKI_TOWN:
1398 if (!show_towns) break;
1399 towns.push_back(Town::Get(item.id.town));
1402 case ViewportSignKdtreeItem::VKI_SIGN: {
1403 if (!show_signs) break;
1404 const Sign *si = Sign::Get(item.id.sign);
1409 if (!show_competitors && _local_company != si->owner && si->owner != OWNER_DEITY) break;
1411 signs.push_back(si);
1422 for (
const auto *t : towns) {
1427 STR_VIEWPORT_TOWN_TINY_WHITE, STR_VIEWPORT_TOWN_TINY_BLACK);
1433 for (
const auto *si : signs) {
1441 for (
const auto *st : stations) {
1447 STR_VIEWPORT_STATION, STR_VIEWPORT_STATION_TINY, STR_NULL,
1452 STR_VIEWPORT_WAYPOINT, STR_VIEWPORT_WAYPOINT_TINY, STR_NULL,
1477 if (str_small != STR_NULL) {
1502 zoomlevels[zoom].top = this->top -
ScaleByZoom(1, zoom);
1504 zoomlevels[zoom].bottom = this->top +
ScaleByZoom(height, zoom);
1509 if (vp !=
nullptr && vp->
zoom <= maxzoom) {
1510 assert(vp->
width != 0);
1517static void ViewportDrawTileSprites(
const TileSpriteToDrawVector *tstdv)
1533 if (psdv->size() < 2)
return;
1542 const uint32_t ORDER_COMPARED = UINT32_MAX;
1543 const uint32_t ORDER_RETURNED = UINT32_MAX - 1;
1544 std::stack<ParentSpriteToDraw *> sprite_order;
1545 uint32_t next_order = 0;
1547 std::forward_list<std::pair<int64_t, ParentSpriteToDraw *>> sprite_list;
1550 for (
auto p = psdv->rbegin(); p != psdv->rend(); p++) {
1551 sprite_list.emplace_front((*p)->xmin + (*p)->ymin, *p);
1552 sprite_order.push(*p);
1553 (*p)->order = next_order++;
1558 std::vector<ParentSpriteToDraw *> preceding;
1559 auto preceding_prev = sprite_list.begin();
1560 auto out = psdv->begin();
1562 while (!sprite_order.empty()) {
1564 auto s = sprite_order.top();
1568 if (s->order == ORDER_RETURNED)
continue;
1571 if (s->order == ORDER_COMPARED) {
1573 s->order = ORDER_RETURNED;
1587 auto ssum = std::max(s->xmax, s->xmin) + std::max(s->ymax, s->ymin);
1588 auto prev = sprite_list.before_begin();
1589 auto x = sprite_list.begin();
1590 while (x != sprite_list.end() && ((*x).first <= ssum)) {
1591 auto p = (*x).second;
1594 x = sprite_list.erase_after(prev);
1601 if (s->xmax < p->xmin || s->ymax < p->ymin || s->zmax < p->zmin)
continue;
1602 if (s->xmin <= p->xmax &&
1603 s->ymin <= p->ymax &&
1604 s->zmin <= p->zmax) {
1605 if (s->xmin + s->xmax + s->ymin + s->ymax + s->zmin + s->zmax <=
1606 p->xmin + p->xmax + p->ymin + p->ymax + p->zmin + p->zmax) {
1610 preceding.push_back(p);
1611 preceding_prev = p_prev;
1614 if (preceding.empty()) {
1617 s->order = ORDER_RETURNED;
1622 if (preceding.size() == 1) {
1623 auto p = preceding[0];
1625 if (p->xmax <= s->xmax && p->ymax <= s->ymax && p->zmax <= s->zmax) {
1626 p->order = ORDER_RETURNED;
1627 s->order = ORDER_RETURNED;
1628 sprite_list.erase_after(preceding_prev);
1637 return a->order > b->order;
1640 s->order = ORDER_COMPARED;
1641 sprite_order.push(s);
1643 for (
auto p: preceding) {
1644 p->order = next_order++;
1645 sprite_order.push(p);
1651static void ViewportDrawParentSprites(
const ParentSpriteToSortVector *psd,
const ChildScreenSpriteToDrawVector *csstdv)
1654 if (ps->image != SPR_EMPTY_BOUNDING_BOX)
DrawSpriteViewport(ps->image, ps->pal, ps->x, ps->y, ps->sub);
1656 int child_idx = ps->first_child;
1657 while (child_idx >= 0) {
1659 child_idx = cs->
next;
1682 pt2.x - pt1.x, pt2.y - pt1.y,
1683 pt3.x - pt1.x, pt3.y - pt1.y,
1684 pt4.x - pt1.x, pt4.y - pt1.y);
1703 uint8_t bo =
UnScaleByZoom(dpi->left + dpi->top, dpi->zoom) & 1;
1705 for (
int i = (bo ^= 1); i < right; i += 2) blitter->
SetPixel(dst, i, 0, (uint8_t)colour);
1706 dst = blitter->
MoveTo(dst, 0, 1);
1707 }
while (--bottom > 0);
1710static void ViewportDrawStrings(
ZoomLevel zoom,
const StringSpriteToDrawVector *sstdv)
1714 bool small =
HasBit(ss.width, 15);
1715 int w =
GB(ss.width, 0, 15);
1720 if (ss.colour != INVALID_COLOUR) {
1730 x, y, x + w - 1, y + h - 1, ss.colour,
1740void ViewportDoDraw(
const Viewport *vp,
int left,
int top,
int right,
int bottom)
1742 _vd.dpi.zoom = vp->
zoom;
1747 _vd.dpi.width = (right - left) & mask;
1748 _vd.dpi.height = (bottom - top) & mask;
1749 _vd.dpi.left = left & mask;
1750 _vd.dpi.top = top & mask;
1751 _vd.dpi.pitch = _cur_dpi->pitch;
1763 ViewportAddKdtreeSigns(&_vd.dpi);
1765 DrawTextEffects(&_vd.dpi);
1767 if (!_vd.tile_sprites_to_draw.empty()) ViewportDrawTileSprites(&_vd.tile_sprites_to_draw);
1769 for (
auto &psd : _vd.parent_sprites_to_draw) {
1786 if (vp->overlay !=
nullptr && vp->overlay->GetCargoMask() != 0 && vp->overlay->GetCompanyMask() != 0) {
1790 vp->overlay->Draw(&dp);
1793 if (!_vd.string_sprites_to_draw.empty()) {
1797 ViewportDrawStrings(zoom, &_vd.string_sprites_to_draw);
1800 _vd.string_sprites_to_draw.clear();
1801 _vd.tile_sprites_to_draw.clear();
1802 _vd.parent_sprites_to_draw.clear();
1804 _vd.child_screen_sprites_to_draw.clear();
1807static inline void ViewportDraw(
const Viewport *vp,
int left,
int top,
int right,
int bottom)
1809 if (right <= vp->left || bottom <= vp->top)
return;
1811 if (left >= vp->
left + vp->
width)
return;
1813 if (left < vp->left) left = vp->
left;
1816 if (top >= vp->
top + vp->
height)
return;
1818 if (top < vp->top) top = vp->
top;
1838 dpi->left += this->
left;
1839 dpi->top += this->
top;
1841 ViewportDraw(this->
viewport, dpi->left, dpi->top, dpi->left + dpi->width, dpi->top + dpi->height);
1843 dpi->left -= this->
left;
1844 dpi->top -= this->
top;
1889static void ClampSmoothScroll(uint32_t delta_ms, int64_t delta_hi, int64_t delta_lo,
int &delta_hi_clamped,
int &delta_lo_clamped)
1892 constexpr int PIXELS_PER_TILE =
TILE_PIXELS * 2 * ZOOM_BASE;
1894 assert(delta_hi != 0);
1897 int64_t delta_left = delta_hi * std::pow(0.75, delta_ms / 30.0);
1902 delta_hi_clamped =
Clamp(delta_hi - delta_left, -max_scroll, max_scroll);
1904 delta_lo_clamped = delta_lo * delta_hi_clamped / delta_hi;
1907 if (delta_hi_clamped == 0) {
1908 delta_hi_clamped = delta_hi > 0 ? 1 : -1;
1926 SetViewportPosition(w, pt.x, pt.y);
1937 bool update_overlay =
false;
1938 if (delta_x != 0 || delta_y != 0) {
1940 int delta_x_clamped;
1941 int delta_y_clamped;
1943 if (
abs(delta_x) >
abs(delta_y)) {
1944 ClampSmoothScroll(delta_ms, delta_x, delta_y, delta_x_clamped, delta_y_clamped);
1946 ClampSmoothScroll(delta_ms, delta_y, delta_x, delta_y_clamped, delta_x_clamped);
1969 if (update_overlay) RebuildViewportOverlay(w);
1986 right += (1 << vp->
zoom) - 1;
1987 bottom += (1 << vp->
zoom) - 1;
1990 if (right <= 0)
return false;
1993 if (bottom <= 0)
return false;
2028 if (vp !=
nullptr) {
2029 assert(vp->
width != 0);
2037void ConstrainAllViewportsZoom()
2040 if (w->viewport ==
nullptr)
continue;
2043 if (zoom != w->viewport->zoom) {
2076 int x_size = _thd.
size.x;
2077 int y_size = _thd.
size.y;
2080 int x_start = _thd.
pos.x;
2081 int y_start = _thd.
pos.y;
2085 x_start += _thd.
offs.x;
2087 y_start += _thd.
offs.y;
2093 assert(x_size >= 0);
2094 assert(y_size >= 0);
2103 assert((x_end | y_end | x_start | y_start) %
TILE_SIZE == 0);
2124 int top_y = y_start;
2145 static const int OVERLAY_WIDTH = 4 * ZOOM_BASE;
2151 if (top_x != x_start) {
2158 if (bot_y != y_end) {
2163 }
while (bot_x >= top_x);
2166 int a_size = x_size + y_size, b_size = x_size - y_size;
2171 for (
int a = -interval_a; a != a_size + interval_a; a += interval_a) {
2172 for (
int b = -interval_b; b != b_size + interval_b; b += interval_b) {
2185void SetSelectionRed(
bool b)
2205 return y >= sign->
top && y < sign->
top + sign_height &&
2206 x >= sign->
center - sign_half_width && x < sign->
center + sign_half_width;
2219 if (_game_mode == GM_MENU)
return false;
2224 Rect search_rect{ x - 1, y - 1, x + 1, y + 1 };
2225 search_rect = ExpandRectWithViewportSignMargins(search_rect, vp->
zoom);
2235 Town *t =
nullptr, *last_t =
nullptr;
2236 Sign *si =
nullptr, *last_si =
nullptr;
2240 switch (item.type) {
2241 case ViewportSignKdtreeItem::VKI_STATION:
2242 if (!show_stations) break;
2243 st = BaseStation::Get(item.id.station);
2244 if (!show_competitors && _local_company != st->owner && st->owner != OWNER_NONE) break;
2245 if (CheckClickOnViewportSign(vp, x, y, &st->sign)) last_st = st;
2248 case ViewportSignKdtreeItem::VKI_WAYPOINT:
2249 if (!show_waypoints) break;
2250 st = BaseStation::Get(item.id.station);
2251 if (!show_competitors && _local_company != st->owner && st->owner != OWNER_NONE) break;
2252 if (CheckClickOnViewportSign(vp, x, y, &st->sign)) last_st = st;
2255 case ViewportSignKdtreeItem::VKI_TOWN:
2256 if (!show_towns) break;
2257 t = Town::Get(item.id.town);
2258 if (CheckClickOnViewportSign(vp, x, y, &t->cache.sign)) last_t = t;
2261 case ViewportSignKdtreeItem::VKI_SIGN:
2262 if (!show_signs) break;
2263 si = Sign::Get(item.id.sign);
2264 if (!show_competitors && _local_company != si->owner && si->owner != OWNER_DEITY) break;
2265 if (CheckClickOnViewportSign(vp, x, y, &si->sign)) last_si = si;
2274 if (last_st !=
nullptr) {
2281 }
else if (last_t !=
nullptr) {
2282 ShowTownViewWindow(last_t->index);
2284 }
else if (last_si !=
nullptr) {
2296 item.type = VKI_STATION;
2297 item.id.station = id;
2313 item.type = VKI_WAYPOINT;
2314 item.id.station = id;
2330 item.type = VKI_TOWN;
2347 item.type = VKI_SIGN;
2352 item.center = sign->sign.
center;
2353 item.top = sign->sign.
top;
2356 _viewport_sign_maxwidth = std::max<int>({_viewport_sign_maxwidth, sign->sign.
width_normal, sign->sign.
width_small});
2361void RebuildViewportKdtree()
2364 _viewport_sign_maxwidth = 0;
2366 std::vector<ViewportSignKdtreeItem> items;
2374 if (wp->sign.kdtree_valid) items.push_back(ViewportSignKdtreeItem::MakeWaypoint(wp->index));
2377 for (
const Town *town :
Town::Iterate()) {
2381 for (
const Sign *sign :
Sign::Iterate()) {
2382 if (sign->sign.
kdtree_valid) items.push_back(ViewportSignKdtreeItem::MakeSign(sign->
index));
2385 _viewport_sign_kdtree.
Build(items.begin(), items.end());
2389static bool CheckClickOnLandscape(
const Viewport *vp,
int x,
int y)
2393 if (pt.x != -1)
return ClickTile(
TileVirtXY(pt.x, pt.y));
2397static void PlaceObject()
2402 pt = GetTileBelowCursor();
2403 if (pt.x == -1)
return;
2418bool HandleViewportClicked(
const Viewport *vp,
int x,
int y)
2433 bool result = CheckClickOnLandscape(vp, x, y);
2450void RebuildViewportOverlay(
Window *w)
2452 if (w->
viewport->overlay !=
nullptr &&
2453 w->
viewport->overlay->GetCompanyMask() != 0 &&
2454 w->
viewport->overlay->GetCargoMask() != 0) {
2489 RebuildViewportOverlay(w);
2550void SetTileSelectBigSize(
int ox,
int oy,
int sx,
int sy)
2610 bool new_diagonal =
false;
2616 int x2 = _thd.
selstart.x & ~TILE_UNIT_MASK;
2617 int y2 = _thd.
selstart.y & ~TILE_UNIT_MASK;
2618 x1 &= ~TILE_UNIT_MASK;
2619 y1 &= ~TILE_UNIT_MASK;
2622 new_diagonal =
true;
2624 if (x1 >= x2)
Swap(x1, x2);
2625 if (y1 >= y2)
Swap(y1, y2);
2631 if (!new_diagonal) {
2638 Point pt = GetTileBelowCursor();
2670 default: NOT_REACHED();
2672 _thd.
selstart.x = x1 & ~TILE_UNIT_MASK;
2673 _thd.
selstart.y = y1 & ~TILE_UNIT_MASK;
2678 _thd.
new_pos.x = x1 & ~TILE_UNIT_MASK;
2679 _thd.
new_pos.y = y1 & ~TILE_UNIT_MASK;
2716static void HideMeasurementTooltips()
2767void VpSetPlaceSizingLimit(
int limit)
2792 HideMeasurementTooltips();
2796static void VpStartPreSizing()
2808 int fxpy = _tile_fract_coords.x + _tile_fract_coords.y;
2810 int fxmy = _tile_fract_coords.x - _tile_fract_coords.y;
2814 default: NOT_REACHED();
2816 if (fxpy >= 20 && sxpy <= 12)
return HT_DIR_HL;
2817 if (fxmy < -3 && sxmy > 3)
return HT_DIR_VR;
2821 if (fxmy > 3 && sxmy < -3)
return HT_DIR_VL;
2822 if (fxpy <= 12 && sxpy >= 20)
return HT_DIR_HU;
2826 if (fxmy > 3 && sxmy < -3)
return HT_DIR_VL;
2827 if (fxpy >= 20 && sxpy <= 12)
return HT_DIR_HL;
2831 if (fxmy < -3 && sxmy > 3)
return HT_DIR_VR;
2832 if (fxpy <= 12 && sxpy >= 20)
return HT_DIR_HU;
2852 uint start_x =
TileX(start_tile);
2853 uint start_y =
TileY(start_tile);
2854 uint end_x =
TileX(end_tile);
2855 uint end_y =
TileY(end_tile);
2859 case HT_LINE:
return (end_x > start_x || (end_x == start_x && end_y > start_y));
2862 case HT_POINT:
return (end_x != start_x && end_y < start_y);
2863 default: NOT_REACHED();
2889 if (start_tile == end_tile)
return 0;
2890 if (swap)
Swap(start_tile, end_tile);
2914 static const std::pair<TileIndexDiffC, TileIndexDiffC> start_heightdiff_line_by_dir[] = {
2922 static const std::pair<TileIndexDiffC, TileIndexDiffC> end_heightdiff_line_by_dir[] = {
2930 static_assert(std::size(start_heightdiff_line_by_dir) ==
HT_DIR_END);
2931 static_assert(std::size(end_heightdiff_line_by_dir) ==
HT_DIR_END);
2941 if (swap && distance == 0) style = flip_style_direction[style];
2944 auto get_height = [](
auto &tile,
auto &heightdiffs) {
2951 h0 = get_height(start_tile, start_heightdiff_line_by_dir[style]);
2955 if (distance == 0) style = flip_style_direction[style];
2956 h1 = get_height(end_tile, end_heightdiff_line_by_dir[style]);
2961 if (swap)
Swap(h0, h1);
2965static const StringID measure_strings_length[] = {STR_NULL, STR_MEASURE_LENGTH, STR_MEASURE_LENGTH_HEIGHTDIFF};
2975 if (test >= 0)
return;
2977 other += mult * test;
2990 if (test <= max)
return;
2992 other += mult * (test - max);
3035 int offset = (raw_dx - raw_dy) / 2;
3036 x = _thd.
selstart.x - (offset & ~TILE_UNIT_MASK);
3037 y = _thd.
selstart.y + (offset & ~TILE_UNIT_MASK);
3070 int offset = (raw_dx + raw_dy + (int)
TILE_SIZE) / 2;
3071 x = _thd.
selstart.x - (offset & ~TILE_UNIT_MASK);
3072 y = _thd.
selstart.y - (offset & ~TILE_UNIT_MASK);
3119 }
else if (w > h * 2) {
3122 }
else if (h > w * 2) {
3136 }
else if (d >= 0) {
3147 }
else if (d >= 0) {
3160 }
else if (d >= 0) {
3171 }
else if (d >= 0) {
3188 if (distance != 1) {
3194 distance =
CeilDiv(distance, 2);
3198 if (heightdiff != 0)
SetDParam(index++, heightdiff);
3247 if (
abs(sy - y) <
abs(sx - x)) {
3254 goto calc_heightdiff_single_direction;
3263 goto calc_heightdiff_single_direction;
3273calc_heightdiff_single_direction:;
3275 x = sx +
Clamp(x - sx, -limit, limit);
3276 y = sy +
Clamp(y - sy, -limit, limit);
3284 if (distance != 1) {
3293 if (heightdiff != 0)
SetDParam(index++, heightdiff);
3302 x = sx +
Clamp(x - sx, -limit, limit);
3303 y = sy +
Clamp(y - sy, -limit, limit);
3308 static const StringID measure_strings_area[] = {
3309 STR_NULL, STR_NULL, STR_MEASURE_AREA, STR_MEASURE_AREA_HEIGHTDIFF
3334 int a_max = dist_x + dist_y;
3335 int b_max = dist_y - dist_x;
3339 a_max =
abs(a_max + (a_max > 0 ? 2 : -2)) / 2;
3340 b_max =
abs(b_max + (b_max > 0 ? 2 : -2)) / 2;
3346 if (a_max != 1 || b_max != 1) {
3353 }
else if (dy == 1) {
3358 if (dx != 1 || dy != 1) {
3363 if (heightdiff != 0)
SetDParam(index++, heightdiff);
3370 default: NOT_REACHED();
3422 HideMeasurementTooltips();
3463 HideMeasurementTooltips();
3524 { &ViewportSortParentSpritesSSE41Checker, &ViewportSortParentSpritesSSE41 },
3533 if (sprite_sorter.fct_checker()) {
3534 _vp_sprite_sorter = sprite_sorter.fct_sorter;
3538 assert(_vp_sprite_sorter !=
nullptr);
3572void MarkCatchmentTilesDirty()
3597static void SetWindowDirtyForViewportCatchment()
3604static void ClearViewportCatchment()
3606 MarkCatchmentTilesDirty();
3620 SetWindowDirtyForViewportCatchment();
3622 ClearViewportCatchment();
3624 MarkCatchmentTilesDirty();
3626 MarkCatchmentTilesDirty();
3640 SetWindowDirtyForViewportCatchment();
3642 ClearViewportCatchment();
3644 MarkCatchmentTilesDirty();
3646 MarkCatchmentTilesDirty();
3660 SetWindowDirtyForViewportCatchment();
3662 ClearViewportCatchment();
This file defines all the the animated cursors.
static const AnimCursor *const _animcursors[]
This is an array of pointers to all the animated cursor definitions we have above.
Highlight/sprite information for autorail.
Class for backupping variables and making sure they are restored later.
debug_inline constexpr bool HasBit(const T x, const uint8_t y)
Checks if a bit in a value is set.
constexpr T SetBit(T &x, const uint8_t y)
Set a bit in a variable.
debug_inline static constexpr uint GB(const T x, const uint8_t s, const uint8_t n)
Fetch n bits from x, started at bit s.
TileIndex GetNorthernBridgeEnd(TileIndex t)
Finds the northern end of a bridge starting at a middle tile.
Map accessor functions for bridges.
int GetBridgePixelHeight(TileIndex tile)
Get the height ('z') of a bridge in pixels.
bool IsBridgeAbove(Tile t)
checks if a bridge is set above the ground of this tile
Iterator to iterate over all tiles belonging to a bitmaptilearea.
static Blitter * GetCurrentBlitter()
Get the current active blitter (always set by calling SelectBlitter).
How all blitters should look like.
virtual void * MoveTo(void *video, int x, int y)=0
Move the destination pointer the requested amount x and y, keeping in mind any pitch and bpp of the r...
virtual void SetPixel(void *video, int x, int y, uint8_t colour)=0
Draw a pixel with a given colour on the video-buffer.
Common return value for all commands.
K-dimensional tree, specialised for 2-dimensional space.
void Build(It begin, It end)
Clear and rebuild the tree from a new sequence of elements,.
size_t Count() const
Get number of elements stored in tree.
void FindContained(CoordT x1, CoordT y1, CoordT x2, CoordT y2, const Outputter &outputter) const
Find all items contained within the given rectangle.
T FindNearest(CoordT x, CoordT y) const
Find the element closest to given coordinate, in Manhattan distance.
Functions related to commands.
static const CommandCost CMD_ERROR
Define a default return value for a failed command.
DoCommandFlag
List of flags for a command.
@ DC_EXEC
execute the given command
Definition of stuff that is very close to a company, like the company struct itself.
Colours _company_colours[MAX_COMPANIES]
NOSAVE: can be determined from company structs.
CompanyID _local_company
Company controlled by the human player at this client. Can also be COMPANY_SPECTATOR.
CompanyID _current_company
Company currently doing an action.
Functions related to companies.
Owner
Enum for all companies/owners.
@ OWNER_DEITY
The object is owned by a superuser / goal script.
@ OWNER_NONE
The tile has no ownership.
#define Debug(category, level, format_string,...)
Ouptut a line of debugging information.
Factory to 'query' all available blitters.
int GetCharacterHeight(FontSize size)
Get height of a character for a given font size.
Types for recording game performance data.
@ PFE_DRAWWORLD
Time spent drawing world viewports in GUI.
void SetMouseCursor(CursorID sprite, PaletteID pal)
Assign a single non-animated sprite to the cursor.
bool _left_button_down
Is left mouse button pressed?
Dimension GetStringBoundingBox(std::string_view str, FontSize start_fontsize)
Return the string dimension in pixels.
int DrawString(int left, int right, int top, std::string_view str, TextColour colour, StringAlignment align, bool underline, FontSize fontsize)
Draw string, possibly truncated to make it fit in its allocated space.
bool _ctrl_pressed
Is Ctrl pressed?
void DrawSpriteViewport(SpriteID img, PaletteID pal, int x, int y, const SubSprite *sub)
Draw a sprite in a viewport.
void SetAnimatedMouseCursor(const AnimCursor *table)
Assign an animation to the cursor.
void DrawBox(int x, int y, int dx1, int dy1, int dx2, int dy2, int dx3, int dy3)
Draws the projection of a parallelepiped.
uint32_t SpriteID
The number of a sprite, without mapping bits and colourtables.
@ Normal
The most basic (normal) sprite.
@ SA_HOR_CENTER
Horizontally center the text.
uint32_t CursorID
The number of the cursor (sprite)
@ FS_SMALL
Index of the small font in the font tables.
@ FS_NORMAL
Index of the normal font in the font tables.
uint32_t PaletteID
The number of the palette.
TextColour
Colour of the strings, see _string_colourmap in table/string_colours.h or docs/ottd-colourtext-palett...
@ TC_IS_PALETTE_COLOUR
Colour value is already a real palette colour index, not an index of a StringColour.
bool MarkAllViewportsDirty(int left, int top, int right, int bottom)
Mark all viewports that display an area as dirty (in need of repaint).
void SetDirty() const
Mark entire window as dirty (in need of re-paint)
void AddDirtyBlock(int left, int top, int right, int bottom)
Extend the internal _invalid_rect rectangle to contain the rectangle defined by the given parameters.
void MarkWholeScreenDirty()
This function mark the whole screen as dirty.
static bool MarkViewportDirty(const Viewport *vp, int left, int top, int right, int bottom)
Marks a viewport as dirty for repaint if it displays (a part of) the area the needs to be repainted.
void RedrawScreenRect(int left, int top, int right, int bottom)
Repaints a specific rectangle of the screen.
void MarkDirty(ZoomLevel maxzoom=ZOOM_LVL_MAX) const
Mark the sign dirty in all viewports.
void MarkTileDirtyByTile(TileIndex tile, int bridge_level_offset, int tile_height_override)
Mark a tile given by its index dirty for repaint.
static void SetSelectionTilesDirty()
Marks the selected tiles as dirty.
const TileTypeProcs *const _tile_type_procs[16]
Tile callback functions for each type of tile.
Point InverseRemapCoords2(int x, int y, bool clamp_to_map, bool *clamped)
Map 2D viewport or smallmap coordinate to 3D world or tile coordinate.
int GetSlopePixelZ(int x, int y, bool ground_vehicle)
Return world Z coordinate of a given point of a tile.
Functions related to OTTD's landscape.
Point RemapCoords(int x, int y, int z)
Map 3D world or tile coordinate to equivalent 2D coordinate as used in the viewports and smallmap.
Point RemapCoords2(int x, int y)
Map 3D world or tile coordinate to equivalent 2D coordinate as used in the viewports and smallmap.
Point InverseRemapCoords(int x, int y)
Map 2D viewport or smallmap coordinate to 3D world or tile coordinate.
Declaration of linkgraph overlay GUI.
bool DoZoomInOutWindow(ZoomStateChange how, Window *w)
Zooms a viewport in a window in or out.
uint DistanceManhattan(TileIndex t0, TileIndex t1)
Gets the Manhattan distance between the two given tiles.
TileIndex TileAddByDir(TileIndex tile, Direction dir)
Adds a Direction to a tile.
static debug_inline TileIndex TileXY(uint x, uint y)
Returns the TileIndex of a coordinate.
TileIndexDiff ToTileIndexDiff(TileIndexDiffC tidc)
Return the offset between two tiles from a TileIndexDiffC struct.
constexpr TileIndex TileAdd(TileIndex tile, TileIndexDiff offset)
Adds a given offset to a tile.
static debug_inline uint TileY(TileIndex tile)
Get the Y component of a tile.
static debug_inline uint TileX(TileIndex tile)
Get the X component of a tile.
static debug_inline TileIndex TileVirtXY(uint x, uint y)
Get a tile from the virtual XY-coordinate.
constexpr bool IsInsideBS(const T x, const size_t base, const size_t size)
Checks if a value is between a window started at some base point.
constexpr T abs(const T a)
Returns the absolute value of (scalar) variable.
constexpr T Align(const T x, uint n)
Return the smallest multiple of n equal or greater than x.
constexpr uint CeilDiv(uint a, uint b)
Computes ceil(a / b) for non-negative a and b.
constexpr T Delta(const T a, const T b)
Returns the (absolute) difference between two (scalar) variables.
constexpr T Clamp(const T a, const T min, const T max)
Clamp a value between an interval.
constexpr bool IsInsideMM(const T x, const size_t min, const size_t max) noexcept
Checks if a value is in an interval.
constexpr void Swap(T &a, T &b)
Type safe swap operation.
void GuiShowTooltips(Window *parent, StringID str, TooltipCloseCondition close_tooltip, uint paramcount)
Shows a tooltip.
ClientID _network_own_client_id
Our client identifier.
Network functions used by other parts of OpenTTD.
ClientID
'Unique' identifier to be given to clients
@ DO_SHOW_TOWN_NAMES
Display town names.
@ DO_SHOW_COMPETITOR_SIGNS
Display signs, station names and waypoint names of opponent companies. Buoys and oilrig-stations are ...
@ DO_SHOW_SIGNS
Display signs.
@ DO_SHOW_WAYPOINT_NAMES
Display waypoint names.
@ DO_SHOW_STATION_NAMES
Display station names.
uint8_t GetColourGradient(Colours colour, ColourShade shade)
Get colour gradient palette index.
A number of safeguards to prevent using unsafe methods.
GameSettings _settings_game
Game settings of a running game or the scenario editor.
ClientSettings _settings_client
The current settings for this game.
Functions related to signs.
void HandleClickOnSign(const Sign *si)
Handle clicking on a sign.
uint16_t SignID
The type of the IDs of signs.
Slope SlopeWithThreeCornersRaised(Corner corner)
Returns the slope with all except one corner raised.
Corner OppositeCorner(Corner corner)
Returns the opposite corner.
static constexpr Corner GetHalftileSlopeCorner(Slope s)
Returns the leveled halftile of a halftile slope.
static constexpr Slope RemoveHalftileSlope(Slope s)
Removes a halftile slope from a slope.
uint SlopeToSpriteOffset(Slope s)
Returns the Sprite offset for a given Slope.
static constexpr bool IsSteepSlope(Slope s)
Checks if a slope is steep.
static constexpr bool IsHalftileSlope(Slope s)
Checks for non-continuous slope on halftile foundations.
Slope SlopeWithOneCornerRaised(Corner corner)
Returns the slope with a specific corner raised.
Slope
Enumeration for the slope-type.
@ SLOPE_N
the north corner of the tile is raised
@ SLOPE_STEEP_N
a steep slope falling to south (from north)
Corner
Enumeration of tile corners.
bool ScrollMainWindowTo(int x, int y, int z, bool instant)
Scrolls the main window to given coordinates.
static constexpr uint32_t MAX_SPRITES
Masks needed for sprite operations.
static const PaletteID PALETTE_TILE_RED_PULSATING
pulsating red tile drawn if you try to build a wrong tunnel or raise/lower land where it is not possi...
static const CursorID ANIMCURSOR_FLAG
Flag for saying a cursor sprite is an animated cursor.
static const PaletteID PALETTE_SEL_TILE_RED
makes a square red. is used when removing rails or other stuff
static constexpr uint32_t SPRITE_MASK
The mask to for the main sprite.
static constexpr uint8_t PALETTE_MODIFIER_TRANSPARENT
when a sprite is to be displayed transparently, this bit needs to be set.
static const PaletteID PALETTE_CRASH
Recolour sprite greying of crashed vehicles.
static const CursorID SPR_CURSOR_MOUSE
Cursor sprite numbers.
static const PaletteID PALETTE_SEL_TILE_BLUE
This draws a blueish square (catchment areas for example)
static const PaletteID PALETTE_TO_TRANSPARENT
This sets the sprite to transparent.
Base classes/functions for stations.
void ShowStationViewWindow(StationID station)
Opens StationViewWindow for given station.
StationID GetStationIndex(Tile t)
Get StationID from a tile.
Definition of base types and functions in a cross-platform compatible way.
The colour translation of GRF's strings.
static const uint8_t _string_colourmap[17]
Colour mapping for TextColour.
void SetDParam(size_t n, uint64_t v)
Set a string parameter v at index n in the global string parameter array.
std::string GetString(StringID string)
Resolve the given StringID into a std::string with all the associated DParam lookups and formatting.
Functions related to OTTD's strings.
uint32_t StringID
Numeric value that represents a string, independent of the selected language.
Class to backup a specific variable and restore it upon destruction of this object to prevent stack v...
Base class for all station-ish types.
TileIndex xy
Base tile of the station.
bool IsInUse() const
Check whether the base station currently is in use; in use means that it is not scheduled for deletio...
TrackedViewportSign sign
NOSAVE: Dimensions of sign.
int next
next child to draw (-1 at the end)
const SubSprite * sub
only draw a rectangular part of the sprite
GUISettings gui
settings related to the GUI
uint8_t max_bridge_height
maximum height of bridges
Point pos
logical mouse position
Data about how and where to blit pixels.
uint8_t dist_local_authority
distance for town local authority, default 20
bool population_in_label
show the population of a town in its label?
bool measure_tooltip
show a permanent tooltip when dragging tools
ZoomLevel zoom_min
minimum zoom out level
bool smooth_scroll
smooth scroll viewports
ZoomLevel zoom_max
maximum zoom out level
EconomySettings economy
settings to change the economy
ConstructionSettings construction
construction of things in-game
static uint SizeY()
Get the size of the map along the Y.
static debug_inline uint SizeX()
Get the size of the map along the X.
static uint ScaleBySize1D(uint n)
Scales the given value by the maps circumference, where the given value is for a 256 by 256 map.
static uint MaxY()
Gets the maximum Y coordinate within the map, including MP_VOID.
static debug_inline uint MaxX()
Gets the maximum X coordinate within the map, including MP_VOID.
TileIndex tile
The base tile of the area.
Parent sprite that should be drawn.
const SubSprite * sub
only draw a rectangular part of the sprite
int32_t zmin
minimal world Z coordinate of bounding box
SpriteID image
sprite to draw
int32_t xmax
maximal world X coordinate of bounding box
int32_t ymax
maximal world Y coordinate of bounding box
int32_t x
screen X coordinate of sprite
int32_t y
screen Y coordinate of sprite
int32_t first_child
the first child to draw.
int32_t zmax
maximal world Z coordinate of bounding box
int32_t xmin
minimal world X coordinate of bounding box
int32_t ymin
minimal world Y coordinate of bounding box
PaletteID pal
palette to use
int32_t left
minimal screen X coordinate of sprite (= x + sprite->x_offs), reference point for child sprites
int32_t top
minimal screen Y coordinate of sprite (= y + sprite->y_offs), reference point for child sprites
Coordinates of a point in 2D.
Tindex index
Index of this pool item.
static size_t GetNumItems()
Returns number of valid items in the pool.
static Titem * Get(size_t index)
Returns Titem with given index.
Specification of a rectangle with absolute coordinates of all edges.
static bool IsExpected(const BaseStation *st)
Helper for checking whether the given station is of this type.
static Station * Get(size_t index)
Gets station with given index.
static Waypoint * From(BaseStation *st)
Converts a BaseStation to SpecializedStation with type checking.
Data structure describing a sprite.
uint16_t width
Width of the sprite.
uint16_t height
Height of the sprite.
int16_t y_offs
Number of pixels to shift the sprite downwards.
int16_t x_offs
Number of pixels to shift the sprite to the right.
BitmapTileArea catchment_tiles
NOSAVE: Set of individual tiles covered by catchment area.
Used to only draw a part of the sprite.
Metadata about the current highlighting.
TileIndex redsq
The tile that has to get a red selection.
Point new_pos
New value for pos; used to determine whether to redraw the selection.
Window * GetCallbackWnd()
Get the window that started the current highlighting.
bool make_square_red
Whether to give a tile a red selection.
bool IsDraggingDiagonal()
Is the user dragging a 'diagonal rectangle'?
ViewportDragDropSelectionProcess select_proc
The procedure that has to be called when the selection is done.
Point selstart
The location where the dragging started.
Point new_outersize
New value for outersize; used to determine whether to redraw the selection.
HighLightStyle drawstyle
Lower bits 0-3 are reserved for detailed highlight information.
HighLightStyle place_mode
Method which is used to place the selection.
WindowClass window_class
The WindowClass of the window that is responsible for the selection mode.
uint8_t dirty
Whether the build station window needs to redraw due to the changed selection.
Point offs
Offset, in tile "units", for the blue coverage area from the selected area's northern tile.
Point size
Size, in tile "units", of the white/red selection area.
uint8_t sizelimit
Whether the selection is limited in length, and what the maximum length is.
Point pos
Location, in tile "units", of the northern tile of the selected area.
Point outersize
Size, in tile "units", of the blue coverage area excluding the side of the selected area.
bool diagonal
Whether the dragged area is a 45 degrees rotated rectangle.
void Reset()
Reset tile highlighting.
Point selend
The location where the drag currently ends.
Point new_size
New value for size; used to determine whether to redraw the selection.
bool freeze
Freeze highlight in place.
HighLightStyle next_drawstyle
Queued, but not yet drawn style.
ViewportPlaceMethod select_method
The method which governs how tiles are selected.
WindowNumber window_number
The WindowNumber of the window that is responsible for the selection mode.
Tile information, used while rendering the tile.
int x
X position of the tile in unit coordinates.
Slope tileh
Slope of the tile.
TileIndex tile
Tile index.
int y
Y position of the tile in unit coordinates.
int32_t y
screen Y coordinate of sprite
int32_t x
screen X coordinate of sprite
const SubSprite * sub
only draw a rectangular part of the sprite
DrawTileProc * draw_tile_proc
Called to render the tile and its contents to the screen.
TrackedViewportSign sign
Location of name sign, UpdateVirtCoord updates this.
TileIndex xy
town center tile
TownCache cache
Container for all cacheable data.
bool show_zone
NOSAVE: mark town to show the local authority zone in the viewports.
StationList stations_near
NOSAVE: List of nearby stations.
bool kdtree_valid
Are the sign data valid for use with the _viewport_sign_kdtree?
int32_t z_pos
z coordinate.
Vehicle * First() const
Get the first vehicle of this vehicle chain.
int32_t y_pos
y coordinate.
int32_t x_pos
x coordinate.
Owner owner
Which company owns the vehicle?
UnitID unitnumber
unit number, for display purposes only
Data structure for a window viewport.
int32_t dest_scrollpos_y
Current destination y coordinate to display (virtual screen coordinate of topleft corner of the viewp...
int32_t scrollpos_y
Currently shown y coordinate (virtual screen coordinate of topleft corner of the viewport).
int32_t dest_scrollpos_x
Current destination x coordinate to display (virtual screen coordinate of topleft corner of the viewp...
VehicleID follow_vehicle
VehicleID to follow if following a vehicle, INVALID_VEHICLE otherwise.
int32_t scrollpos_x
Currently shown x coordinate (virtual screen coordinate of topleft corner of the viewport).
Data structure storing rendering information.
int foundation[FOUNDATION_PART_END]
Foundation sprites (index into parent_sprites_to_draw).
int last_foundation_child[FOUNDATION_PART_END]
Tail of ChildSprite list of the foundations. (index into child_screen_sprites_to_draw)
ParentSpriteToSortVector parent_sprites_to_sort
Parent sprite pointer array used for sorting.
Point foundation_offset[FOUNDATION_PART_END]
Pixel offset for ground sprites on the foundations.
SpriteCombineMode combine_sprites
Current mode of "sprite combining".
FoundationPart foundation_part
Currently active foundation for ground sprite drawing.
Helper class for getting the best sprite sorter.
VpSorterChecker fct_checker
The check function.
VpSpriteSorter fct_sorter
The sorting function.
Location information about a sign as seen on the viewport.
int32_t center
The center position of the sign.
uint16_t width_small
The width when zoomed out (small font)
uint16_t width_normal
The width when not zoomed out (normal font)
void UpdatePosition(int center, int top, StringID str, StringID str_small=STR_NULL)
Update the position of the viewport sign.
int32_t top
The top of the sign.
Data structure for viewport, display of a part of the world.
int top
Screen coordinate top edge of the viewport.
int width
Screen width of the viewport.
ZoomLevel zoom
The zoom level of the viewport.
int virtual_top
Virtual top coordinate.
int virtual_left
Virtual left coordinate.
int virtual_width
width << zoom
int left
Screen coordinate left edge of the viewport.
int height
Screen height of the viewport.
int virtual_height
height << zoom
Representation of a waypoint.
Iterator to iterate all valid Windows.
Data structure for an opened window.
void SetWidgetDirty(WidgetID widget_index) const
Invalidate a widget, i.e.
virtual void OnPlaceObjectAbort()
The user cancelled a tile highlight mode that has been set.
WindowClass window_class
Window class.
ViewportData * viewport
Pointer to viewport data, if present.
void DrawViewport() const
Draw the viewport of this window.
virtual void OnPlaceObject(Point pt, TileIndex tile)
The user clicked some place on the map when a tile highlight mode has been set.
int left
x position of left edge of the window
int top
y position of top edge of the window
virtual void OnPlaceMouseUp(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt, TileIndex start_tile, TileIndex end_tile)
The user has dragged over the map when the tile highlight mode has been set.
const NWID * GetWidget(WidgetID widnum) const
Get the nested widget with number widnum from the nested widget tree.
virtual void OnPlaceDrag(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt)
The user is dragging over the map when the tile highlight mode has been set.
void SetWidgetDisabledState(WidgetID widget_index, bool disab_stat)
Sets the enabled/disabled status of a widget.
AllWindows< false > Iterate
Iterate all windows in whatever order is easiest.
int height
Height of the window (number of pixels down in y direction)
int width
width of the window (number of pixels to the right in x direction)
WindowNumber window_number
Window number within the window class.
std::tuple< Slope, int > GetTilePixelSlopeOutsideMap(int x, int y)
Return the slope of a given tile, also for tiles outside the map (virtual "black" tiles).
int GetTilePixelZ(TileIndex tile)
Get bottom height of the tile.
int GetTileMaxPixelZ(TileIndex tile)
Get top height of the tile.
static debug_inline TileType GetTileType(Tile tile)
Get the tiletype of a given tile.
std::tuple< Slope, int > GetTilePixelSlope(TileIndex tile)
Return the slope of a given tile.
bool IsValidTile(Tile tile)
Checks if a tile is valid.
uint TilePixelHeight(Tile tile)
Returns the height of a tile in pixels.
uint TilePixelHeightOutsideMap(int x, int y)
Returns the height of a tile in pixels, also for tiles outside the map (virtual "black" tiles).
static debug_inline bool IsTileType(Tile tile, TileType type)
Checks if a tile is a given tiletype.
static debug_inline uint TileHeight(Tile tile)
Returns the height of a tile.
uint TileHeightOutsideMap(int x, int y)
Returns the height of a tile, also for tiles outside the map (virtual "black" tiles).
static const uint TILE_PIXELS
Pixel distance between tile columns/rows in ZOOM_BASE.
static const uint MAX_BUILDING_PIXELS
Maximum height of a building in pixels in ZOOM_BASE. (Also applies to "bridge buildings" on the bridg...
static const uint TILE_HEIGHT
Height of a height level in world coordinate AND in pixels in ZOOM_BASE.
static const uint TILE_SIZE
Tile size in world coordinates.
static const uint TILE_UNIT_MASK
For masking in/out the inner-tile world coordinate units.
constexpr TileIndex INVALID_TILE
The very nice invalid tile marker.
TileType
The different types of tiles.
@ MP_STATION
A tile of a station.
@ MP_HOUSE
A house by a town.
@ MP_VOID
Invisible tiles at the SW and SE border.
Functions related to tile highlights.
HighLightStyle
Highlighting draw styles.
@ HT_LINE
used for autorail highlighting (longer stretches), lower bits: direction
@ HT_DIR_HL
horizontal lower
@ HT_DIR_HU
horizontal upper
@ HT_DRAG
dragging items in the depot windows
@ HT_DIAGONAL
Also allow 'diagonal rectangles'. Only usable in combination with HT_RECT or HT_POINT.
@ HT_POINT
point (lower land, raise land, level land, ...)
@ HT_RECT
rectangle (stations, depots, ...)
@ HT_DIR_MASK
masks the drag-direction
@ HT_RAIL
autorail (one piece), lower bits: direction
@ HT_DRAG_MASK
Mask for the tile drag-type modes.
@ HT_VEHICLE
vehicle is accepted as target as well (bitmask)
@ HT_DIR_VR
vertical right
@ HT_SPECIAL
special mode used for highlighting while dragging (and for tunnels/docks)
Town * ClosestTownFromTile(TileIndex tile, uint threshold)
Return the town closest (in distance or ownership) to a given tile, within a given threshold.
Declarations for accessing the k-d tree of towns.
TownID GetTownIndex(Tile t)
Get the index of which town this house/street is attached to.
bool IsTransparencySet(TransparencyOption to)
Check if the transparency option bit is set and if we aren't in the game menu (there's never transpar...
uint8_t _display_opt
What do we want to draw/do?
bool IsInvisibilitySet(TransparencyOption to)
Check if the invisibility option bit is set and if we aren't in the game menu (there's never transpar...
void ViewportAddVehicles(DrawPixelInfo *dpi)
Add the vehicle sprites that should be drawn at a part of the screen.
Vehicle * CheckClickOnVehicle(const Viewport *vp, int x, int y)
Find the vehicle close to the clicked coordinates.
Base class for all vehicles.
Functions related to vehicles.
bool IsCompanyBuildableVehicleType(VehicleType type)
Is the given vehicle type buildable by a company?
void ShowVehicleViewWindow(const Vehicle *v)
Shows the vehicle view window of the given vehicle.
bool VehicleClicked(const Vehicle *v)
Dispatch a "vehicle selected" event if any window waits for it.
void StartStopVehicle(const Vehicle *v, bool texteffect)
Executes CMD_START_STOP_VEHICLE for given vehicle.
Functions related to the vehicle's GUIs.
static const VehicleID INVALID_VEHICLE
Constant representing a non-existing vehicle.
static void HighlightTownLocalAuthorityTiles(const TileInfo *ti)
Highlights tiles insede local authority of selected towns.
static void CheckOverflow(int &test, int &other, int max, int mult)
Check for overflowing the map.
bool ScrollWindowToTile(TileIndex tile, Window *w, bool instant)
Scrolls the viewport in a window to a given location.
CommandCost CmdScrollViewport(DoCommandFlag flags, TileIndex tile, ViewportScrollTarget target, uint32_t ref)
Scroll players main viewport.
void SetTileSelectSize(int w, int h)
Highlight w by h tiles at the cursor.
void OffsetGroundSprite(int x, int y)
Called when a foundation has been drawn for the current tile.
void HandleZoomMessage(Window *w, const Viewport *vp, WidgetID widget_zoom_in, WidgetID widget_zoom_out)
Update the status of the zoom-buttons according to the zoom-level of the viewport.
constexpr int LAST_CHILD_NONE
There is no last_child to fill.
void ResetObjectToPlace()
Reset the cursor and mouse mode handling back to default (normal cursor, only clicking in windows).
bool ScrollMainWindowToTile(TileIndex tile, bool instant)
Scrolls the viewport of the main window to a given location.
SpriteCombineMode
Mode of "sprite combining".
@ SPRITE_COMBINE_PENDING
Sprite combining will start with the next unclipped sprite.
@ SPRITE_COMBINE_ACTIVE
Sprite combining is active. AddSortableSpriteToDraw outputs child sprites.
@ SPRITE_COMBINE_NONE
Every AddSortableSpriteToDraw start its own bounding box.
void SetObjectToPlaceWnd(CursorID icon, PaletteID pal, HighLightStyle mode, Window *w)
Change the cursor and mouse click/drag handling to a mode for performing special operations like tile...
constexpr int LAST_CHILD_PARENT
Fill last_child of the most recent parent sprite.
static const int MAX_TILE_EXTENT_TOP
Maximum top extent of tile relative to north corner (not considering bridges).
static const int MAX_TILE_EXTENT_LEFT
Maximum left extent of tile relative to north corner.
bool IsInsideRotatedRectangle(int x, int y)
Checks whether a point is inside the selected a diagonal rectangle given by _thd.size and _thd....
static int CalcHeightdiff(HighLightStyle style, uint distance, TileIndex start_tile, TileIndex end_tile)
Calculates height difference between one tile and another.
static void DrawTileSelectionRect(const TileInfo *ti, PaletteID pal)
Draws a selection rectangle on a tile.
void StartSpriteCombine()
Starts a block of sprites, which are "combined" into a single bounding box.
void InitializeSpriteSorter()
Choose the "best" sprite sorter and set _vp_sprite_sorter.
FoundationPart
Enumeration of multi-part foundations.
@ FOUNDATION_PART_NONE
Neither foundation nor groundsprite drawn yet.
@ FOUNDATION_PART_HALFTILE
Second part (halftile foundation)
@ FOUNDATION_PART_NORMAL
First part (normal foundation or no foundation)
static void AddCombinedSprite(SpriteID image, PaletteID pal, int x, int y, int z, const SubSprite *sub)
Adds a child sprite to a parent sprite.
static void ShowMeasurementTooltips(StringID str, uint paramcount)
Displays the measurement tooltips when selecting multiple tiles.
static int GetViewportY(Point tile)
Returns the y coordinate in the viewport coordinate system where the given tile is painted.
static void ClampViewportToMap(const Viewport *vp, int *scroll_x, int *scroll_y)
Ensure that a given viewport has a valid scroll position.
static void AddChildSpriteToFoundation(SpriteID image, PaletteID pal, const SubSprite *sub, FoundationPart foundation_part, int extra_offs_x, int extra_offs_y)
Adds a child sprite to the active foundation.
static HighLightStyle GetAutorailHT(int x, int y)
returns the best autorail highlight type from map coordinates
static void ClampSmoothScroll(uint32_t delta_ms, int64_t delta_hi, int64_t delta_lo, int &delta_hi_clamped, int &delta_lo_clamped)
Clamp the smooth scroll to a maxmimum speed and distance based on time elapsed.
static void DrawTileSelection(const TileInfo *ti)
Checks if the specified tile is selected and if so draws selection using correct selectionstyle.
Point TranslateXYToTileCoord(const Viewport *vp, int x, int y, bool clamp_to_map)
Translate screen coordinate in a viewport to underlying tile coordinate.
static TileHighlightType GetTileHighlightType(TileIndex t)
Get tile highlight type of coverage area for a given tile.
static bool IsInRangeInclusive(int begin, int end, int check)
Check if the parameter "check" is inside the interval between begin and end, including both begin and...
static void DrawAutorailSelection(const TileInfo *ti, uint autorail_type)
Draws autorail highlights.
static void DrawTileHighlightType(const TileInfo *ti, TileHighlightType tht)
Draw tile highlight for coverage area highlight.
static void ViewportDrawBoundingBoxes(const ParentSpriteToSortVector *psd)
Draws the bounding boxes of all ParentSprites.
void AddSortableSpriteToDraw(SpriteID image, PaletteID pal, int x, int y, int w, int h, int dz, int z, bool transparent, int bb_offset_x, int bb_offset_y, int bb_offset_z, const SubSprite *sub)
Draw a (transparent) sprite at given coordinates with a given bounding box.
void SetViewportCatchmentWaypoint(const Waypoint *wp, bool sel)
Select or deselect waypoint for coverage area highlight.
void SetRedErrorSquare(TileIndex tile)
Set a tile to display a red error square.
static void ViewportSortParentSprites(ParentSpriteToSortVector *psdv)
Sort parent sprites pointer array replicating the way original sorter did it.
void VpSetPresizeRange(TileIndex from, TileIndex to)
Highlights all tiles between a set of two tiles.
void VpSelectTilesWithMethod(int x, int y, ViewportPlaceMethod method)
Selects tiles while dragging.
EventState VpHandlePlaceSizingDrag()
Handle the mouse while dragging for placement/resizing.
void ViewportAddString(const DrawPixelInfo *dpi, ZoomLevel small_from, const ViewportSign *sign, StringID string_normal, StringID string_small, StringID string_small_shadow, Colours colour)
Add a string to draw in the viewport.
Viewport * IsPtInWindowViewport(const Window *w, int x, int y)
Is a xy position inside the viewport of the window?
void SetObjectToPlace(CursorID icon, PaletteID pal, HighLightStyle mode, WindowClass window_class, WindowNumber window_num)
Change the cursor and mouse click/drag handling to a mode for performing special operations like tile...
void EndSpriteCombine()
Terminates a block of sprites started by StartSpriteCombine.
static const int MAX_TILE_EXTENT_RIGHT
Maximum right extent of tile relative to north corner.
void AddChildSpriteScreen(SpriteID image, PaletteID pal, int x, int y, bool transparent, const SubSprite *sub, bool scale, bool relative)
Add a child sprite to a parent sprite.
static void CheckUnderflow(int &test, int &other, int mult)
Check for underflowing the map.
static bool ViewportSortParentSpritesChecker()
This fallback sprite checker always exists.
void DrawGroundSpriteAt(SpriteID image, PaletteID pal, int32_t x, int32_t y, int z, const SubSprite *sub, int extra_offs_x, int extra_offs_y)
Draws a ground sprite at a specific world-coordinate relative to the current tile.
void VpStartDragging(ViewportDragDropSelectionProcess process)
Drag over the map while holding the left mouse down.
static ViewportSSCSS _vp_sprite_sorters[]
List of sorters ordered from best to worst.
void UpdateTileSelection()
Updates tile highlighting for all cases.
static void DrawSelectionSprite(SpriteID image, PaletteID pal, const TileInfo *ti, int z_offset, FoundationPart foundation_part, int extra_offs_x=0, int extra_offs_y=0)
Draws sprites between ground sprite and everything above.
static const int MAX_TILE_EXTENT_BOTTOM
Maximum bottom extent of tile relative to north corner (worst case: SLOPE_STEEP_N).
void SetViewportCatchmentStation(const Station *st, bool sel)
Select or deselect station for coverage area highlight.
void SetViewportCatchmentTown(const Town *t, bool sel)
Select or deselect town for coverage area highlight.
static bool SwapDirection(HighLightStyle style, TileIndex start_tile, TileIndex end_tile)
Check if the direction of start and end tile should be swapped based on the dragging-style.
void InitializeWindowViewport(Window *w, int x, int y, int width, int height, std::variant< TileIndex, VehicleID > focus, ZoomLevel zoom)
Initialize viewport of the window for use.
void DrawGroundSprite(SpriteID image, PaletteID pal, const SubSprite *sub, int extra_offs_x, int extra_offs_y)
Draws a ground sprite for the current tile.
static void CalcRaildirsDrawstyle(int x, int y, int method)
while dragging
static HighLightStyle Check2x1AutoRail(int mode)
returns information about the 2x1 piece to be build.
static bool CheckClickOnViewportSign(const Viewport *vp, int x, int y, const ViewportSign *sign)
Test whether a sign is below the mouse.
static void ViewportDrawDirtyBlocks()
Draw/colour the blocks that have been redrawn.
void VpStartPlaceSizing(TileIndex tile, ViewportPlaceMethod method, ViewportDragDropSelectionProcess process)
highlighting tiles while only going over them with the mouse
static void AddTileSpriteToDraw(SpriteID image, PaletteID pal, int32_t x, int32_t y, int z, const SubSprite *sub=nullptr, int extra_offs_x=0, int extra_offs_y=0)
Schedules a tile sprite for drawing.
static void ViewportAddLandscape()
Add the landscape to the viewport, i.e.
const Station * _viewport_highlight_station
Currently selected station for coverage area highlight.
const Town * _viewport_highlight_town
Currently selected town for coverage area highlight.
void UpdateViewportPosition(Window *w, uint32_t delta_ms)
Update the viewport position being displayed.
const Waypoint * _viewport_highlight_waypoint
Currently selected waypoint for coverage area highlight.
bool ScrollWindowTo(int x, int y, int z, Window *w, bool instant)
Scrolls the viewport in a window to a given location.
Command definitions related to viewports.
Functions related to (drawing on) viewports.
static const int TILE_HEIGHT_STEP
One Z unit tile height difference is displayed as 50m.
Types related to sprite sorting.
bool(* VpSorterChecker)()
Type for method for checking whether a viewport sprite sorter exists.
void(* VpSpriteSorter)(ParentSpriteToSortVector *psd)
Type for the actual viewport sprite sorter.
ViewportScrollTarget
Target of the viewport scrolling GS method.
@ VST_EVERYONE
All players.
@ VST_COMPANY
All players in specific company.
@ VST_CLIENT
Single player.
ViewportDragDropSelectionProcess
Drag and drop selection process, or, what to do with an area of land when you've selected it.
@ ZOOM_IN
Zoom in (get more detailed view).
@ ZOOM_OUT
Zoom out (get helicopter view).
ViewportPlaceMethod
Viewport place method (type of highlighted area and placed objects)
@ VPM_FIX_Y
drag only in Y axis
@ VPM_Y_LIMITED
Drag only in Y axis with limited size.
@ VPM_X_AND_Y_LIMITED
area of land of limited size
@ VPM_FIX_VERTICAL
drag only in vertical direction
@ VPM_X_LIMITED
Drag only in X axis with limited size.
@ VPM_X_AND_Y
area of land in X and Y directions
@ VPM_FIX_HORIZONTAL
drag only in horizontal direction
@ VPM_FIX_X
drag only in X axis
@ VPM_SIGNALDIRS
similar to VMP_RAILDIRS, but with different cursor
@ VPM_X_OR_Y
drag in X or Y direction
@ VPM_RAILDIRS
all rail directions
Functions related to waypoints.
void ShowWaypointWindow(const Waypoint *wp)
Show the window for the given waypoint.
void CloseWindowById(WindowClass cls, WindowNumber number, bool force, int data)
Close a window by its class and window number (if it is open).
Window * GetMainWindow()
Get the main window, i.e.
Window * FindWindowFromPt(int x, int y)
Do a search for a window at specific coordinates.
SpecialMouseMode _special_mouse_mode
Mode of the mouse.
Window * FindWindowById(WindowClass cls, WindowNumber number)
Find a window by its class and window number.
void SetWindowDirty(WindowClass cls, WindowNumber number)
Mark window as dirty (in need of repainting)
Window functions not directly related to making/drawing windows.
Functions, definitions and such used only by the GUI.
@ WSM_DRAGDROP
Drag&drop an object.
@ WSM_DRAGGING
Dragging mode (trees).
@ WSM_PRESIZE
Presizing mode (docks, tunnels).
@ WSM_NONE
No special mouse mode.
@ FR_TRANSPARENT
Makes the background transparent if set.
int32_t WindowNumber
Number to differentiate different windows of the same class.
EventState
State of handling an event.
@ ES_HANDLED
The passed event is handled.
@ ES_NOT_HANDLED
The passed event is not handled.
WindowClass
Window classes.
@ WC_INVALID
Invalid window.
@ WC_WAYPOINT_VIEW
Waypoint view; Window numbers:
@ WC_STATION_VIEW
Station view; Window numbers:
@ WC_MAIN_WINDOW
Main window; Window numbers:
@ WC_TOWN_VIEW
Town view; Window numbers:
@ WC_TOOLTIPS
Tooltip window; Window numbers:
Functions related to zooming.
int ScaleByZoom(int value, ZoomLevel zoom)
Scale by zoom level, usually shift left (when zoom > ZOOM_LVL_MIN) When shifting right,...
int UnScaleByZoomLower(int value, ZoomLevel zoom)
Scale by zoom level, usually shift right (when zoom > ZOOM_LVL_MIN)
int UnScaleByZoom(int value, ZoomLevel zoom)
Scale by zoom level, usually shift right (when zoom > ZOOM_LVL_MIN) When shifting right,...
ZoomLevel
All zoom levels we know.
@ ZOOM_LVL_BEGIN
Begin for iteration.
@ ZOOM_LVL_OUT_4X
Zoomed 4 times out.
@ ZOOM_LVL_END
End for iteration.
@ ZOOM_LVL_MIN
Minimum zoom level.