Merge remote-tracking branch 'upstream/master'
This commit is contained in:
+121
-106
@@ -112,14 +112,14 @@
|
||||
Point _tile_fract_coords;
|
||||
|
||||
|
||||
ViewportSignKdtree _viewport_sign_kdtree(&Kdtree_ViewportSignXYFunc);
|
||||
ViewportSignKdtree _viewport_sign_kdtree{};
|
||||
static int _viewport_sign_maxwidth = 0;
|
||||
|
||||
|
||||
static const int MAX_TILE_EXTENT_LEFT = ZOOM_LVL_BASE * TILE_PIXELS; ///< Maximum left extent of tile relative to north corner.
|
||||
static const int MAX_TILE_EXTENT_RIGHT = ZOOM_LVL_BASE * TILE_PIXELS; ///< Maximum right extent of tile relative to north corner.
|
||||
static const int MAX_TILE_EXTENT_TOP = ZOOM_LVL_BASE * MAX_BUILDING_PIXELS; ///< Maximum top extent of tile relative to north corner (not considering bridges).
|
||||
static const int MAX_TILE_EXTENT_BOTTOM = ZOOM_LVL_BASE * (TILE_PIXELS + 2 * TILE_HEIGHT); ///< Maximum bottom extent of tile relative to north corner (worst case: #SLOPE_STEEP_N).
|
||||
static const int MAX_TILE_EXTENT_LEFT = ZOOM_BASE * TILE_PIXELS; ///< Maximum left extent of tile relative to north corner.
|
||||
static const int MAX_TILE_EXTENT_RIGHT = ZOOM_BASE * TILE_PIXELS; ///< Maximum right extent of tile relative to north corner.
|
||||
static const int MAX_TILE_EXTENT_TOP = ZOOM_BASE * MAX_BUILDING_PIXELS; ///< Maximum top extent of tile relative to north corner (not considering bridges).
|
||||
static const int MAX_TILE_EXTENT_BOTTOM = ZOOM_BASE * (TILE_PIXELS + 2 * TILE_HEIGHT); ///< Maximum bottom extent of tile relative to north corner (worst case: #SLOPE_STEEP_N).
|
||||
|
||||
struct StringSpriteToDraw {
|
||||
std::string string;
|
||||
@@ -171,6 +171,9 @@ typedef std::vector<StringSpriteToDraw> StringSpriteToDrawVector;
|
||||
typedef std::vector<ParentSpriteToDraw> ParentSpriteToDrawVector;
|
||||
typedef std::vector<ChildScreenSpriteToDraw> ChildScreenSpriteToDrawVector;
|
||||
|
||||
constexpr int LAST_CHILD_NONE = -1; ///< There is no last_child to fill.
|
||||
constexpr int LAST_CHILD_PARENT = -2; ///< Fill last_child of the most recent parent sprite.
|
||||
|
||||
/**
|
||||
* Snapping point for a track.
|
||||
*
|
||||
@@ -203,13 +206,13 @@ struct ViewportDrawer {
|
||||
ParentSpriteToSortVector parent_sprites_to_sort; ///< Parent sprite pointer array used for sorting
|
||||
ChildScreenSpriteToDrawVector child_screen_sprites_to_draw;
|
||||
|
||||
int *last_child;
|
||||
int last_child;
|
||||
|
||||
SpriteCombineMode combine_sprites; ///< Current mode of "sprite combining". @see StartSpriteCombine
|
||||
|
||||
int foundation[FOUNDATION_PART_END]; ///< Foundation sprites (index into parent_sprites_to_draw).
|
||||
FoundationPart foundation_part; ///< Currently active foundation for ground sprite drawing.
|
||||
int *last_foundation_child[FOUNDATION_PART_END]; ///< Tail of ChildSprite list of the foundations. (index into child_screen_sprites_to_draw)
|
||||
int last_foundation_child[FOUNDATION_PART_END]; ///< Tail of ChildSprite list of the foundations. (index into child_screen_sprites_to_draw)
|
||||
Point foundation_offset[FOUNDATION_PART_END]; ///< Pixel offset for ground sprites on the foundations.
|
||||
|
||||
citymania::TileHighlight cm_highlight;
|
||||
@@ -596,13 +599,8 @@ void AddChildSpriteToFoundation(SpriteID image, PaletteID pal, const SubSprite *
|
||||
Point offs = _vd.foundation_offset[foundation_part];
|
||||
|
||||
/* Change the active ChildSprite list to the one of the foundation */
|
||||
int *old_child = _vd.last_child;
|
||||
_vd.last_child = _vd.last_foundation_child[foundation_part];
|
||||
|
||||
AutoRestoreBackup backup(_vd.last_child, _vd.last_foundation_child[foundation_part]);
|
||||
AddChildSpriteScreen(image, pal, offs.x + extra_offs_x, offs.y + extra_offs_y, false, sub, false, false);
|
||||
|
||||
/* Switch back to last ChildSprite list */
|
||||
_vd.last_child = old_child;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -625,9 +623,9 @@ void DrawGroundSpriteAt(SpriteID image, PaletteID pal, int32_t x, int32_t y, int
|
||||
if (_vd.cm_highlight.ground_pal) pal = _vd.cm_highlight.ground_pal;
|
||||
if (_vd.foundation[_vd.foundation_part] != -1) {
|
||||
Point pt = RemapCoords(x, y, z);
|
||||
AddChildSpriteToFoundation(image, pal, sub, _vd.foundation_part, pt.x + extra_offs_x * ZOOM_LVL_BASE, pt.y + extra_offs_y * ZOOM_LVL_BASE);
|
||||
AddChildSpriteToFoundation(image, pal, sub, _vd.foundation_part, pt.x + extra_offs_x * ZOOM_BASE, pt.y + extra_offs_y * ZOOM_BASE);
|
||||
} else {
|
||||
AddTileSpriteToDraw(image, pal, _cur_ti.x + x, _cur_ti.y + y, _cur_ti.z + z, sub, extra_offs_x * ZOOM_LVL_BASE, extra_offs_y * ZOOM_LVL_BASE);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -666,11 +664,11 @@ void OffsetGroundSprite(int x, int y)
|
||||
default: NOT_REACHED();
|
||||
}
|
||||
|
||||
/* _vd.last_child == nullptr if foundation sprite was clipped by the viewport bounds */
|
||||
if (_vd.last_child != nullptr) _vd.foundation[_vd.foundation_part] = (uint)_vd.parent_sprites_to_draw.size() - 1;
|
||||
/* _vd.last_child is LAST_CHILD_NONE if foundation sprite was clipped by the viewport bounds */
|
||||
if (_vd.last_child != LAST_CHILD_NONE) _vd.foundation[_vd.foundation_part] = static_cast<uint>(_vd.parent_sprites_to_draw.size()) - 1;
|
||||
|
||||
_vd.foundation_offset[_vd.foundation_part].x = x * ZOOM_LVL_BASE;
|
||||
_vd.foundation_offset[_vd.foundation_part].y = y * ZOOM_LVL_BASE;
|
||||
_vd.foundation_offset[_vd.foundation_part].x = x * ZOOM_BASE;
|
||||
_vd.foundation_offset[_vd.foundation_part].y = y * ZOOM_BASE;
|
||||
_vd.last_foundation_child[_vd.foundation_part] = _vd.last_child;
|
||||
}
|
||||
|
||||
@@ -746,7 +744,7 @@ void AddSortableSpriteToDraw(SpriteID image, PaletteID pal, int x, int y, int w,
|
||||
return;
|
||||
}
|
||||
|
||||
_vd.last_child = nullptr;
|
||||
_vd.last_child = LAST_CHILD_NONE;
|
||||
if (!ignore_highlight_pal && pal == CM_PALETTE_HIDE_SPRITE) return;
|
||||
|
||||
Point pt = RemapCoords(x, y, z);
|
||||
@@ -801,9 +799,9 @@ void AddSortableSpriteToDraw(SpriteID image, PaletteID pal, int x, int y, int w,
|
||||
ps.zmin = z + bb_offset_z;
|
||||
ps.zmax = z + std::max(bb_offset_z, dz) - 1;
|
||||
|
||||
ps.first_child = -1;
|
||||
ps.first_child = LAST_CHILD_NONE;
|
||||
|
||||
_vd.last_child = &ps.first_child;
|
||||
_vd.last_child = LAST_CHILD_PARENT;
|
||||
|
||||
if (_vd.combine_sprites == SPRITE_COMBINE_PENDING) _vd.combine_sprites = SPRITE_COMBINE_ACTIVE;
|
||||
}
|
||||
@@ -895,7 +893,7 @@ void AddChildSpriteScreen(SpriteID image, PaletteID pal, int x, int y, bool tran
|
||||
assert((image & SPRITE_MASK) < MAX_SPRITES);
|
||||
|
||||
/* If the ParentSprite was clipped by the viewport bounds, do not draw the ChildSprites either */
|
||||
if (_vd.last_child == nullptr) return;
|
||||
if (_vd.last_child == LAST_CHILD_NONE) return;
|
||||
|
||||
/* make the sprites transparent with the right palette */
|
||||
if (transparent) {
|
||||
@@ -903,23 +901,28 @@ void AddChildSpriteScreen(SpriteID image, PaletteID pal, int x, int y, bool tran
|
||||
pal = PALETTE_TO_TRANSPARENT;
|
||||
}
|
||||
|
||||
*_vd.last_child = (uint)_vd.child_screen_sprites_to_draw.size();
|
||||
int32_t child_id = static_cast<int32_t>(_vd.child_screen_sprites_to_draw.size());
|
||||
if (_vd.last_child != LAST_CHILD_PARENT) {
|
||||
_vd.child_screen_sprites_to_draw[_vd.last_child].next = child_id;
|
||||
} else {
|
||||
_vd.parent_sprites_to_draw.back().first_child = child_id;
|
||||
}
|
||||
|
||||
ChildScreenSpriteToDraw &cs = _vd.child_screen_sprites_to_draw.emplace_back();
|
||||
cs.image = image;
|
||||
cs.pal = pal;
|
||||
cs.sub = sub;
|
||||
cs.x = scale ? x * ZOOM_LVL_BASE : x;
|
||||
cs.y = scale ? y * ZOOM_LVL_BASE : y;
|
||||
cs.x = scale ? x * ZOOM_BASE : x;
|
||||
cs.y = scale ? y * ZOOM_BASE : y;
|
||||
cs.relative = relative;
|
||||
cs.next = -1;
|
||||
cs.next = LAST_CHILD_NONE;
|
||||
|
||||
/* Append the sprite to the active ChildSprite list.
|
||||
* If the active ParentSprite is a foundation, update last_foundation_child as well.
|
||||
* Note: ChildSprites of foundations are NOT sequential in the vector, as selection sprites are added at last. */
|
||||
if (_vd.last_foundation_child[0] == _vd.last_child) _vd.last_foundation_child[0] = &cs.next;
|
||||
if (_vd.last_foundation_child[1] == _vd.last_child) _vd.last_foundation_child[1] = &cs.next;
|
||||
_vd.last_child = &cs.next;
|
||||
if (_vd.last_foundation_child[0] == _vd.last_child) _vd.last_foundation_child[0] = child_id;
|
||||
if (_vd.last_foundation_child[1] == _vd.last_child) _vd.last_foundation_child[1] = child_id;
|
||||
_vd.last_child = child_id;
|
||||
}
|
||||
|
||||
static void AddStringToDraw(int x, int y, StringID string, Colours colour, uint16_t width)
|
||||
@@ -956,7 +959,7 @@ void DrawSelectionSprite(SpriteID image, PaletteID pal, const TileInfo *ti, int
|
||||
AddTileSpriteToDraw(image, pal, ti->x, ti->y, ti->z + z_offset, nullptr, extra_offs_x, extra_offs_y);
|
||||
} else {
|
||||
/* draw on top of foundation */
|
||||
AddChildSpriteToFoundation(image, pal, nullptr, foundation_part, extra_offs_x, extra_offs_y - z_offset * ZOOM_LVL_BASE);
|
||||
AddChildSpriteToFoundation(image, pal, nullptr, foundation_part, extra_offs_x, extra_offs_y - z_offset * ZOOM_BASE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1235,7 +1238,7 @@ static void DrawTileSelection(const TileInfo *ti)
|
||||
static int GetViewportY(Point tile)
|
||||
{
|
||||
/* Each increment in X or Y direction moves down by half a tile, i.e. TILE_PIXELS / 2. */
|
||||
return (tile.y * (int)(TILE_PIXELS / 2) + tile.x * (int)(TILE_PIXELS / 2) - TilePixelHeightOutsideMap(tile.x, tile.y)) << ZOOM_LVL_SHIFT;
|
||||
return (tile.y * (int)(TILE_PIXELS / 2) + tile.x * (int)(TILE_PIXELS / 2) - TilePixelHeightOutsideMap(tile.x, tile.y)) << ZOOM_BASE_SHIFT;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1265,7 +1268,7 @@ static void ViewportAddLandscape()
|
||||
int left_column = DivTowardsNegativeInf(upper_left.y - upper_left.x, (int)TILE_SIZE) - 1;
|
||||
int right_column = DivTowardsPositiveInf(upper_right.y - upper_right.x, (int)TILE_SIZE) + 1;
|
||||
|
||||
int potential_bridge_height = ZOOM_LVL_BASE * TILE_HEIGHT * _settings_game.construction.max_bridge_height;
|
||||
int potential_bridge_height = ZOOM_BASE * TILE_HEIGHT * _settings_game.construction.max_bridge_height;
|
||||
|
||||
/* Rows overlap with neighbouring rows by a half tile.
|
||||
* The first row that could possibly be visible is the row above upper_left (if it is at height 0).
|
||||
@@ -1300,10 +1303,10 @@ static void ViewportAddLandscape()
|
||||
|
||||
if (tile_type != MP_VOID) {
|
||||
/* We are inside the map => paint landscape. */
|
||||
_cur_ti.tileh = GetTilePixelSlope(_cur_ti.tile, &_cur_ti.z);
|
||||
std::tie(_cur_ti.tileh, _cur_ti.z) = GetTilePixelSlope(_cur_ti.tile);
|
||||
} else {
|
||||
/* We are outside the map => paint black. */
|
||||
_cur_ti.tileh = GetTilePixelSlopeOutsideMap(tilecoord.x, tilecoord.y, &_cur_ti.z);
|
||||
std::tie(_cur_ti.tileh, _cur_ti.z) = GetTilePixelSlopeOutsideMap(tilecoord.x, tilecoord.y);
|
||||
}
|
||||
|
||||
int viewport_y = GetViewportY(tilecoord);
|
||||
@@ -1325,7 +1328,7 @@ static void ViewportAddLandscape()
|
||||
if (IsBridgeAbove(_cur_ti.tile)) {
|
||||
/* Is the bridge visible? */
|
||||
TileIndex bridge_tile = GetNorthernBridgeEnd(_cur_ti.tile);
|
||||
int bridge_height = ZOOM_LVL_BASE * (GetBridgePixelHeight(bridge_tile) - TilePixelHeight(_cur_ti.tile));
|
||||
int bridge_height = ZOOM_BASE * (GetBridgePixelHeight(bridge_tile) - TilePixelHeight(_cur_ti.tile));
|
||||
if (min_visible_height < bridge_height + MAX_TILE_EXTENT_TOP) tile_visible = true;
|
||||
}
|
||||
|
||||
@@ -1343,8 +1346,8 @@ static void ViewportAddLandscape()
|
||||
_vd.foundation_part = FOUNDATION_PART_NONE;
|
||||
_vd.foundation[0] = -1;
|
||||
_vd.foundation[1] = -1;
|
||||
_vd.last_foundation_child[0] = nullptr;
|
||||
_vd.last_foundation_child[1] = nullptr;
|
||||
_vd.last_foundation_child[0] = LAST_CHILD_NONE;
|
||||
_vd.last_foundation_child[1] = LAST_CHILD_NONE;
|
||||
_vd.cm_highlight = citymania::GetTileHighlight(&_cur_ti, tile_type);
|
||||
|
||||
_tile_type_procs[tile_type]->draw_tile_proc(&_cur_ti);
|
||||
@@ -1381,7 +1384,7 @@ void ViewportAddString(const DrawPixelInfo *dpi, ZoomLevel small_from, const Vie
|
||||
int right = left + dpi->width;
|
||||
int bottom = top + dpi->height;
|
||||
|
||||
int sign_height = ScaleByZoom(WidgetDimensions::scaled.fullbevel.top + GetCharacterHeight(FS_NORMAL) + WidgetDimensions::scaled.fullbevel.bottom, dpi->zoom);
|
||||
int sign_height = ScaleByZoom(WidgetDimensions::scaled.fullbevel.top + GetCharacterHeight(small ? FS_SMALL : FS_NORMAL) + WidgetDimensions::scaled.fullbevel.bottom, dpi->zoom);
|
||||
int sign_half_width = ScaleByZoom((small ? sign->width_small : sign->width_normal) / 2, dpi->zoom);
|
||||
|
||||
if (bottom < sign->top ||
|
||||
@@ -1405,8 +1408,7 @@ void ViewportAddString(const DrawPixelInfo *dpi, ZoomLevel small_from, const Vie
|
||||
|
||||
Rect ExpandRectWithViewportSignMargins(Rect r, ZoomLevel zoom)
|
||||
{
|
||||
/* Pessimistically always use normal font, but also assume small font is never larger in either dimension */
|
||||
const int fh = GetCharacterHeight(FS_NORMAL);
|
||||
const int fh = std::max(GetCharacterHeight(FS_NORMAL), GetCharacterHeight(FS_SMALL));
|
||||
const int max_tw = _viewport_sign_maxwidth / 2 + 1;
|
||||
const int expand_y = ScaleByZoom(WidgetDimensions::scaled.fullbevel.top + fh + WidgetDimensions::scaled.fullbevel.bottom, zoom);
|
||||
const int expand_x = ScaleByZoom(WidgetDimensions::scaled.fullbevel.left + max_tw + WidgetDimensions::scaled.fullbevel.right, zoom);
|
||||
@@ -1487,7 +1489,7 @@ static void ViewportAddKdtreeSigns(DrawPixelInfo *dpi)
|
||||
for (const auto *t : towns) {
|
||||
SetDParam(0, t->index);
|
||||
SetDParam(1, t->cache.population);
|
||||
ViewportAddString(dpi, ZOOM_LVL_OUT_16X, &t->cache.sign,
|
||||
ViewportAddString(dpi, ZOOM_LVL_OUT_4X, &t->cache.sign,
|
||||
_settings_client.gui.population_in_label ? STR_VIEWPORT_TOWN_POP : STR_VIEWPORT_TOWN,
|
||||
STR_VIEWPORT_TOWN_TINY_WHITE, STR_VIEWPORT_TOWN_TINY_BLACK);
|
||||
}
|
||||
@@ -1497,7 +1499,7 @@ static void ViewportAddKdtreeSigns(DrawPixelInfo *dpi)
|
||||
|
||||
for (const auto *si : signs) {
|
||||
SetDParam(0, si->index);
|
||||
ViewportAddString(dpi, ZOOM_LVL_OUT_16X, &si->sign,
|
||||
ViewportAddString(dpi, ZOOM_LVL_OUT_4X, &si->sign,
|
||||
STR_WHITE_SIGN,
|
||||
(IsTransparencySet(TO_SIGNS) || si->owner == OWNER_DEITY) ? STR_VIEWPORT_SIGN_SMALL_WHITE : STR_VIEWPORT_SIGN_SMALL_BLACK, STR_NULL,
|
||||
(si->owner == OWNER_NONE) ? COLOUR_GREY : (si->owner == OWNER_DEITY ? INVALID_COLOUR : _company_colours[si->owner]));
|
||||
@@ -1508,12 +1510,12 @@ static void ViewportAddKdtreeSigns(DrawPixelInfo *dpi)
|
||||
SetDParam(1, st->facilities);
|
||||
if (Station::IsExpected(st)) {
|
||||
/* Station */
|
||||
ViewportAddString(dpi, ZOOM_LVL_OUT_16X, &st->sign,
|
||||
ViewportAddString(dpi, ZOOM_LVL_OUT_4X, &st->sign,
|
||||
STR_VIEWPORT_STATION, STR_VIEWPORT_STATION_TINY, STR_NULL,
|
||||
(st->owner == OWNER_NONE || !st->IsInUse()) ? COLOUR_GREY : _company_colours[st->owner]);
|
||||
} else {
|
||||
/* Waypoint */
|
||||
ViewportAddString(dpi, ZOOM_LVL_OUT_16X, &st->sign,
|
||||
ViewportAddString(dpi, ZOOM_LVL_OUT_4X, &st->sign,
|
||||
STR_VIEWPORT_WAYPOINT, STR_VIEWPORT_WAYPOINT_TINY, STR_NULL,
|
||||
(st->owner == OWNER_NONE || !st->IsInUse()) ? COLOUR_GREY : _company_colours[st->owner]);
|
||||
}
|
||||
@@ -1557,12 +1559,16 @@ void ViewportSign::MarkDirty(ZoomLevel maxzoom) const
|
||||
{
|
||||
Rect zoomlevels[ZOOM_LVL_END];
|
||||
|
||||
/* We don't know which size will be drawn, so mark the largest area dirty. */
|
||||
const uint half_width = std::max(this->width_normal, this->width_small) / 2 + 1;
|
||||
const uint height = WidgetDimensions::scaled.fullbevel.top + std::max(GetCharacterHeight(FS_NORMAL), GetCharacterHeight(FS_SMALL)) + WidgetDimensions::scaled.fullbevel.bottom + 1;
|
||||
|
||||
for (ZoomLevel zoom = ZOOM_LVL_BEGIN; zoom != ZOOM_LVL_END; zoom++) {
|
||||
/* FIXME: This doesn't switch to width_small when appropriate. */
|
||||
zoomlevels[zoom].left = this->center - ScaleByZoom(this->width_normal / 2 + 1, zoom);
|
||||
zoomlevels[zoom].left = this->center - ScaleByZoom(half_width, zoom);
|
||||
zoomlevels[zoom].top = this->top - ScaleByZoom(1, zoom);
|
||||
zoomlevels[zoom].right = this->center + ScaleByZoom(this->width_normal / 2 + 1, zoom);
|
||||
zoomlevels[zoom].bottom = this->top + ScaleByZoom(WidgetDimensions::scaled.fullbevel.top + GetCharacterHeight(FS_NORMAL) + WidgetDimensions::scaled.fullbevel.bottom + 1, zoom);
|
||||
zoomlevels[zoom].right = this->center + ScaleByZoom(half_width, zoom);
|
||||
zoomlevels[zoom].bottom = this->top + ScaleByZoom(height, zoom);
|
||||
}
|
||||
|
||||
for (const Window *w : Window::Iterate()) {
|
||||
@@ -1608,7 +1614,7 @@ static void ViewportSortParentSprites(ParentSpriteToSortVector *psdv)
|
||||
|
||||
/* Initialize sprite list and order. */
|
||||
for (auto p = psdv->rbegin(); p != psdv->rend(); p++) {
|
||||
sprite_list.push_front(std::make_pair((*p)->xmin + (*p)->ymin, *p));
|
||||
sprite_list.emplace_front((*p)->xmin + (*p)->ymin, *p);
|
||||
sprite_order.push(*p);
|
||||
(*p)->order = next_order++;
|
||||
}
|
||||
@@ -1760,7 +1766,7 @@ void ViewportDrawDirtyBlocks()
|
||||
|
||||
dst = dpi->dst_ptr;
|
||||
|
||||
byte bo = UnScaleByZoom(dpi->left + dpi->top, dpi->zoom) & 1;
|
||||
uint8_t bo = UnScaleByZoom(dpi->left + dpi->top, dpi->zoom) & 1;
|
||||
do {
|
||||
for (int i = (bo ^= 1); i < right; i += 2) blitter->SetPixel(dst, i, 0, (uint8_t)colour);
|
||||
dst = blitter->MoveTo(dst, 0, 1);
|
||||
@@ -1775,14 +1781,14 @@ static void ViewportDrawStrings(ZoomLevel zoom, const StringSpriteToDrawVector *
|
||||
int w = GB(ss.width, 0, 15);
|
||||
int x = UnScaleByZoom(ss.x, zoom);
|
||||
int y = UnScaleByZoom(ss.y, zoom);
|
||||
int h = WidgetDimensions::scaled.fullbevel.top + (small ? GetCharacterHeight(FS_SMALL) : GetCharacterHeight(FS_NORMAL)) + WidgetDimensions::scaled.fullbevel.bottom;
|
||||
int h = WidgetDimensions::scaled.fullbevel.top + GetCharacterHeight(small ? FS_SMALL : FS_NORMAL) + WidgetDimensions::scaled.fullbevel.bottom;
|
||||
|
||||
if (ss.colour != INVALID_COLOUR) {
|
||||
if (IsTransparencySet(TO_SIGNS) && ss.string_id != STR_WHITE_SIGN) {
|
||||
/* Don't draw the rectangle.
|
||||
* Real colours need the TC_IS_PALETTE_COLOUR flag.
|
||||
* Otherwise colours from _string_colourmap are assumed. */
|
||||
colour = (TextColour)_colour_gradient[ss.colour][6] | TC_IS_PALETTE_COLOUR;
|
||||
colour = (TextColour)GetColourGradient(ss.colour, SHADE_LIGHTER) | TC_IS_PALETTE_COLOUR;
|
||||
} else {
|
||||
/* Draw the rectangle if 'transparent station signs' is off,
|
||||
* or if we are drawing a general text sign (STR_WHITE_SIGN). */
|
||||
@@ -1809,7 +1815,7 @@ void ViewportDoDraw(const Viewport *vp, int left, int top, int right, int bottom
|
||||
_vd.dpi.left = left & mask;
|
||||
_vd.dpi.top = top & mask;
|
||||
_vd.dpi.pitch = _cur_dpi->pitch;
|
||||
_vd.last_child = nullptr;
|
||||
_vd.last_child = LAST_CHILD_NONE;
|
||||
|
||||
int x = UnScaleByZoomLower(_vd.dpi.left - (vp->virtual_left & mask), vp->zoom) + vp->left;
|
||||
int y = UnScaleByZoomLower(_vd.dpi.top - (vp->virtual_top & mask), vp->zoom) + vp->top;
|
||||
@@ -1840,7 +1846,7 @@ void ViewportDoDraw(const Viewport *vp, int left, int top, int right, int bottom
|
||||
|
||||
DrawPixelInfo dp = _vd.dpi;
|
||||
ZoomLevel zoom = _vd.dpi.zoom;
|
||||
dp.zoom = ZOOM_LVL_NORMAL;
|
||||
dp.zoom = ZOOM_LVL_MIN;
|
||||
dp.width = UnScaleByZoom(dp.width, zoom);
|
||||
dp.height = UnScaleByZoom(dp.height, zoom);
|
||||
_cur_dpi = &dp;
|
||||
@@ -1962,7 +1968,7 @@ static inline void ClampViewportToMap(const Viewport *vp, int *scroll_x, int *sc
|
||||
static void ClampSmoothScroll(uint32_t delta_ms, int64_t delta_hi, int64_t delta_lo, int &delta_hi_clamped, int &delta_lo_clamped)
|
||||
{
|
||||
/** A tile is 64 pixels in width at 1x zoom; viewport coordinates are in 4x zoom. */
|
||||
constexpr int PIXELS_PER_TILE = TILE_PIXELS * 2 * ZOOM_LVL_BASE;
|
||||
constexpr int PIXELS_PER_TILE = TILE_PIXELS * 2 * ZOOM_BASE;
|
||||
|
||||
assert(delta_hi != 0);
|
||||
|
||||
@@ -2141,10 +2147,10 @@ static bool MarkViewportDirty(Viewport *vp, int left, int top, int right, int bo
|
||||
|
||||
/**
|
||||
* Mark all viewports that display an area as dirty (in need of repaint).
|
||||
* @param left Left edge of area to repaint. (viewport coordinates, that is wrt. #ZOOM_LVL_NORMAL)
|
||||
* @param top Top edge of area to repaint. (viewport coordinates, that is wrt. #ZOOM_LVL_NORMAL)
|
||||
* @param right Right edge of area to repaint. (viewport coordinates, that is wrt. #ZOOM_LVL_NORMAL)
|
||||
* @param bottom Bottom edge of area to repaint. (viewport coordinates, that is wrt. #ZOOM_LVL_NORMAL)
|
||||
* @param left Left edge of area to repaint. (viewport coordinates, that is wrt. #ZOOM_LVL_MIN)
|
||||
* @param top Top edge of area to repaint. (viewport coordinates, that is wrt. #ZOOM_LVL_MIN)
|
||||
* @param right Right edge of area to repaint. (viewport coordinates, that is wrt. #ZOOM_LVL_MIN)
|
||||
* @param bottom Bottom edge of area to repaint. (viewport coordinates, that is wrt. #ZOOM_LVL_MIN)
|
||||
* @return true if at least one viewport has a dirty block
|
||||
* @ingroup dirty
|
||||
*/
|
||||
@@ -2188,7 +2194,7 @@ void MarkTileDirtyByTile(TileIndex tile, int bridge_level_offset, int tile_heigh
|
||||
Point pt = RemapCoords(TileX(tile) * TILE_SIZE, TileY(tile) * TILE_SIZE, tile_height_override * TILE_HEIGHT);
|
||||
MarkAllViewportsDirty(
|
||||
pt.x - MAX_TILE_EXTENT_LEFT,
|
||||
pt.y - MAX_TILE_EXTENT_TOP - ZOOM_LVL_BASE * TILE_HEIGHT * bridge_level_offset,
|
||||
pt.y - MAX_TILE_EXTENT_TOP - ZOOM_BASE * TILE_HEIGHT * bridge_level_offset,
|
||||
pt.x + MAX_TILE_EXTENT_RIGHT,
|
||||
pt.y + MAX_TILE_EXTENT_BOTTOM);
|
||||
}
|
||||
@@ -2266,15 +2272,15 @@ void MarkTileDirtyByTile(TileIndex tile, int bridge_level_offset, int tile_heigh
|
||||
/* the 'x' coordinate of 'top' and 'bot' is the same (and always in the same distance from tile middle),
|
||||
* tile height/slope affects only the 'y' on-screen coordinate! */
|
||||
|
||||
int l = top.x - TILE_PIXELS * ZOOM_LVL_BASE; // 'x' coordinate of left side of the dirty rectangle
|
||||
int l = top.x - TILE_PIXELS * ZOOM_BASE; // 'x' coordinate of left side of the dirty rectangle
|
||||
int t = top.y; // 'y' coordinate of top side of the dirty rectangle
|
||||
int r = top.x + TILE_PIXELS * ZOOM_LVL_BASE; // 'x' coordinate of right side of the dirty rectangle
|
||||
int r = top.x + TILE_PIXELS * ZOOM_BASE; // 'x' coordinate of right side of the dirty rectangle
|
||||
int b = bot.y; // 'y' coordinate of bottom side of the dirty rectangle
|
||||
|
||||
static const int OVERLAY_WIDTH = 4 * ZOOM_LVL_BASE; // part of selection sprites is drawn outside the selected area (in particular: terraforming)
|
||||
static const int OVERLAY_WIDTH = 4 * ZOOM_BASE; // part of selection sprites is drawn outside the selected area (in particular: terraforming)
|
||||
|
||||
/* For halftile foundations on SLOPE_STEEP_S the sprite extents some more towards the top */
|
||||
MarkAllViewportsDirty(l - OVERLAY_WIDTH, t - OVERLAY_WIDTH - TILE_HEIGHT * ZOOM_LVL_BASE, r + OVERLAY_WIDTH, b + OVERLAY_WIDTH);
|
||||
MarkAllViewportsDirty(l - OVERLAY_WIDTH, t - OVERLAY_WIDTH - TILE_HEIGHT * ZOOM_BASE, r + OVERLAY_WIDTH, b + OVERLAY_WIDTH);
|
||||
|
||||
/* haven't we reached the topmost tile yet? */
|
||||
if (top_x != x_start) {
|
||||
@@ -2327,9 +2333,9 @@ void SetSelectionRed(bool b)
|
||||
*/
|
||||
bool CheckClickOnViewportSign(const Viewport *vp, int x, int y, const ViewportSign *sign)
|
||||
{
|
||||
bool small = (vp->zoom >= ZOOM_LVL_OUT_16X);
|
||||
bool small = (vp->zoom >= ZOOM_LVL_OUT_4X);
|
||||
int sign_half_width = ScaleByZoom((small ? sign->width_small : sign->width_normal) / 2, vp->zoom);
|
||||
int sign_height = ScaleByZoom(WidgetDimensions::scaled.fullbevel.top + (small ? GetCharacterHeight(FS_SMALL) : GetCharacterHeight(FS_NORMAL)) + WidgetDimensions::scaled.fullbevel.bottom, vp->zoom);
|
||||
int sign_height = ScaleByZoom(WidgetDimensions::scaled.fullbevel.top + GetCharacterHeight(small ? FS_SMALL : FS_NORMAL) + WidgetDimensions::scaled.fullbevel.bottom, vp->zoom);
|
||||
|
||||
return y >= sign->top && y < sign->top + sign_height &&
|
||||
x >= sign->center - sign_half_width && x < sign->center + sign_half_width;
|
||||
@@ -2432,7 +2438,7 @@ ViewportSignKdtreeItem ViewportSignKdtreeItem::MakeStation(StationID id)
|
||||
item.top = st->sign.top;
|
||||
|
||||
/* Assume the sign can be a candidate for drawing, so measure its width */
|
||||
_viewport_sign_maxwidth = std::max<int>(_viewport_sign_maxwidth, st->sign.width_normal);
|
||||
_viewport_sign_maxwidth = std::max<int>({_viewport_sign_maxwidth, st->sign.width_normal, st->sign.width_small});
|
||||
|
||||
return item;
|
||||
}
|
||||
@@ -2449,7 +2455,7 @@ ViewportSignKdtreeItem ViewportSignKdtreeItem::MakeWaypoint(StationID id)
|
||||
item.top = st->sign.top;
|
||||
|
||||
/* Assume the sign can be a candidate for drawing, so measure its width */
|
||||
_viewport_sign_maxwidth = std::max<int>(_viewport_sign_maxwidth, st->sign.width_normal);
|
||||
_viewport_sign_maxwidth = std::max<int>({_viewport_sign_maxwidth, st->sign.width_normal, st->sign.width_small});
|
||||
|
||||
return item;
|
||||
}
|
||||
@@ -2466,7 +2472,7 @@ ViewportSignKdtreeItem ViewportSignKdtreeItem::MakeTown(TownID id)
|
||||
item.top = town->cache.sign.top;
|
||||
|
||||
/* Assume the sign can be a candidate for drawing, so measure its width */
|
||||
_viewport_sign_maxwidth = std::max<int>(_viewport_sign_maxwidth, town->cache.sign.width_normal);
|
||||
_viewport_sign_maxwidth = std::max<int>({_viewport_sign_maxwidth, town->cache.sign.width_normal, town->cache.sign.width_small});
|
||||
|
||||
return item;
|
||||
}
|
||||
@@ -2483,7 +2489,7 @@ ViewportSignKdtreeItem ViewportSignKdtreeItem::MakeSign(SignID id)
|
||||
item.top = sign->sign.top;
|
||||
|
||||
/* Assume the sign can be a candidate for drawing, so measure its width */
|
||||
_viewport_sign_maxwidth = std::max<int>(_viewport_sign_maxwidth, sign->sign.width_normal);
|
||||
_viewport_sign_maxwidth = std::max<int>({_viewport_sign_maxwidth, sign->sign.width_normal, sign->sign.width_small});
|
||||
|
||||
return item;
|
||||
}
|
||||
@@ -3112,19 +3118,18 @@ static int CalcHeightdiff(HighLightStyle style, uint distance, TileIndex start_t
|
||||
if (swap) Swap(start_tile, end_tile);
|
||||
|
||||
switch (style & HT_DRAG_MASK) {
|
||||
case HT_RECT: {
|
||||
static const TileIndexDiffC heightdiff_area_by_dir[] = {
|
||||
/* Start */ {1, 0}, /* Dragging east */ {0, 0}, // Dragging south
|
||||
/* End */ {0, 1}, /* Dragging east */ {1, 1} // Dragging south
|
||||
};
|
||||
|
||||
case HT_RECT:
|
||||
/* In the case of an area we can determine whether we were dragging south or
|
||||
* east by checking the X-coordinates of the tiles */
|
||||
byte style_t = (byte)(TileX(end_tile) > TileX(start_tile));
|
||||
start_tile = TILE_ADD(start_tile, ToTileIndexDiff(heightdiff_area_by_dir[style_t]));
|
||||
end_tile = TILE_ADD(end_tile, ToTileIndexDiff(heightdiff_area_by_dir[2 + style_t]));
|
||||
if (TileX(end_tile) > TileX(start_tile)) {
|
||||
/* Dragging south does not need to change the start tile. */
|
||||
end_tile = TileAddByDir(end_tile, DIR_S);
|
||||
} else {
|
||||
/* Dragging east. */
|
||||
start_tile = TileAddByDir(start_tile, DIR_SW);
|
||||
end_tile = TileAddByDir(end_tile, DIR_SE);
|
||||
}
|
||||
[[fallthrough]];
|
||||
}
|
||||
|
||||
case HT_POINT:
|
||||
h0 = TileHeight(start_tile);
|
||||
@@ -3134,18 +3139,28 @@ static int CalcHeightdiff(HighLightStyle style, uint distance, TileIndex start_t
|
||||
static const HighLightStyle flip_style_direction[] = {
|
||||
HT_DIR_X, HT_DIR_Y, HT_DIR_HL, HT_DIR_HU, HT_DIR_VR, HT_DIR_VL
|
||||
};
|
||||
static const TileIndexDiffC heightdiff_line_by_dir[] = {
|
||||
/* Start */ {1, 0}, {1, 1}, /* HT_DIR_X */ {0, 1}, {1, 1}, // HT_DIR_Y
|
||||
/* Start */ {1, 0}, {0, 0}, /* HT_DIR_HU */ {1, 0}, {1, 1}, // HT_DIR_HL
|
||||
/* Start */ {1, 0}, {1, 1}, /* HT_DIR_VL */ {0, 1}, {1, 1}, // HT_DIR_VR
|
||||
|
||||
/* Start */ {0, 1}, {0, 0}, /* HT_DIR_X */ {1, 0}, {0, 0}, // HT_DIR_Y
|
||||
/* End */ {0, 1}, {0, 0}, /* HT_DIR_HU */ {1, 1}, {0, 1}, // HT_DIR_HL
|
||||
/* End */ {1, 0}, {0, 0}, /* HT_DIR_VL */ {0, 0}, {0, 1}, // HT_DIR_VR
|
||||
static const std::pair<TileIndexDiffC, TileIndexDiffC> start_heightdiff_line_by_dir[] = {
|
||||
{ {1, 0}, {1, 1} }, // HT_DIR_X
|
||||
{ {0, 1}, {1, 1} }, // HT_DIR_Y
|
||||
{ {1, 0}, {0, 0} }, // HT_DIR_HU
|
||||
{ {1, 0}, {1, 1} }, // HT_DIR_HL
|
||||
{ {1, 0}, {1, 1} }, // HT_DIR_VL
|
||||
{ {0, 1}, {1, 1} }, // HT_DIR_VR
|
||||
};
|
||||
static const std::pair<TileIndexDiffC, TileIndexDiffC> end_heightdiff_line_by_dir[] = {
|
||||
{ {0, 1}, {0, 0} }, // HT_DIR_X
|
||||
{ {1, 0}, {0, 0} }, // HT_DIR_Y
|
||||
{ {0, 1}, {0, 0} }, // HT_DIR_HU
|
||||
{ {1, 1}, {0, 1} }, // HT_DIR_HL
|
||||
{ {1, 0}, {0, 0} }, // HT_DIR_VL
|
||||
{ {0, 0}, {0, 1} }, // HT_DIR_VR
|
||||
};
|
||||
static_assert(std::size(start_heightdiff_line_by_dir) == HT_DIR_END);
|
||||
static_assert(std::size(end_heightdiff_line_by_dir) == HT_DIR_END);
|
||||
|
||||
distance %= 2; // we're only interested if the distance is even or uneven
|
||||
style &= HT_DIR_MASK;
|
||||
assert(style < HT_DIR_END);
|
||||
|
||||
/* To handle autorail, we do some magic to be able to use a lookup table.
|
||||
* Firstly if we drag the other way around, we switch start&end, and if needed
|
||||
@@ -3153,20 +3168,20 @@ static int CalcHeightdiff(HighLightStyle style, uint distance, TileIndex start_t
|
||||
* that means the end, which is now the start is on the right */
|
||||
if (swap && distance == 0) style = flip_style_direction[style];
|
||||
|
||||
/* Lambda to help calculating the height at one side of the line. */
|
||||
auto get_height = [](auto &tile, auto &heightdiffs) {
|
||||
return std::max(
|
||||
TileHeight(TileAdd(tile, ToTileIndexDiff(heightdiffs.first))),
|
||||
TileHeight(TileAdd(tile, ToTileIndexDiff(heightdiffs.second))));
|
||||
};
|
||||
|
||||
/* Use lookup table for start-tile based on HighLightStyle direction */
|
||||
byte style_t = style * 2;
|
||||
assert(style_t < lengthof(heightdiff_line_by_dir) - 13);
|
||||
h0 = TileHeight(TILE_ADD(start_tile, ToTileIndexDiff(heightdiff_line_by_dir[style_t])));
|
||||
uint ht = TileHeight(TILE_ADD(start_tile, ToTileIndexDiff(heightdiff_line_by_dir[style_t + 1])));
|
||||
h0 = std::max(h0, ht);
|
||||
h0 = get_height(start_tile, start_heightdiff_line_by_dir[style]);
|
||||
|
||||
/* Use lookup table for end-tile based on HighLightStyle direction
|
||||
* flip around side (lower/upper, left/right) based on distance */
|
||||
if (distance == 0) style_t = flip_style_direction[style] * 2;
|
||||
assert(style_t < lengthof(heightdiff_line_by_dir) - 13);
|
||||
h1 = TileHeight(TILE_ADD(end_tile, ToTileIndexDiff(heightdiff_line_by_dir[12 + style_t])));
|
||||
ht = TileHeight(TILE_ADD(end_tile, ToTileIndexDiff(heightdiff_line_by_dir[12 + style_t + 1])));
|
||||
h1 = std::max(h1, ht);
|
||||
if (distance == 0) style = flip_style_direction[style];
|
||||
h1 = get_height(end_tile, end_heightdiff_line_by_dir[style]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -3189,7 +3204,7 @@ static void ShowLengthMeasurement(HighLightStyle style, TileIndex start_tile, Ti
|
||||
|
||||
if (_settings_client.gui.measure_tooltip) {
|
||||
uint distance = DistanceManhattan(start_tile, end_tile) + 1;
|
||||
byte index = 0;
|
||||
uint8_t index = 0;
|
||||
|
||||
if (show_single_tile_length || distance != 1) {
|
||||
int heightdiff = CalcHeightdiff(style, distance, start_tile, end_tile);
|
||||
@@ -3620,7 +3635,7 @@ static void CalcRaildirsDrawstyle(int x, int y, int method)
|
||||
TileIndex t0 = TileVirtXY(_thd.selstart.x, _thd.selstart.y);
|
||||
TileIndex t1 = TileVirtXY(x, y);
|
||||
uint distance = DistanceManhattan(t0, t1) + 1;
|
||||
byte index = 0;
|
||||
uint8_t index = 0;
|
||||
|
||||
if (distance != 1) {
|
||||
int heightdiff = CalcHeightdiff(b, distance, t0, t1);
|
||||
@@ -3810,7 +3825,7 @@ calc_heightdiff_single_direction:;
|
||||
TileIndex t0 = TileVirtXY(sx, sy);
|
||||
TileIndex t1 = TileVirtXY(x, y);
|
||||
uint distance = DistanceManhattan(t0, t1) + 1;
|
||||
byte index = 0;
|
||||
uint8_t index = 0;
|
||||
|
||||
if (distance != 1) {
|
||||
/* With current code passing a HT_LINE style to calculate the height
|
||||
@@ -3853,7 +3868,7 @@ calc_heightdiff_single_direction:;
|
||||
TileIndex t1 = TileVirtXY(x, y);
|
||||
uint dx = Delta(TileX(t0), TileX(t1)) + 1;
|
||||
uint dy = Delta(TileY(t0), TileY(t1)) + 1;
|
||||
byte index = 0;
|
||||
uint8_t index = 0;
|
||||
|
||||
/* If dragging an area (eg dynamite tool) and it is actually a single
|
||||
* row/column, change the type to 'line' to get proper calculation for height */
|
||||
@@ -4078,9 +4093,9 @@ static ViewportSSCSS _vp_sprite_sorters[] = {
|
||||
/** Choose the "best" sprite sorter and set _vp_sprite_sorter. */
|
||||
void InitializeSpriteSorter()
|
||||
{
|
||||
for (uint i = 0; i < lengthof(_vp_sprite_sorters); i++) {
|
||||
if (_vp_sprite_sorters[i].fct_checker()) {
|
||||
_vp_sprite_sorter = _vp_sprite_sorters[i].fct_sorter;
|
||||
for (const auto &sprite_sorter : _vp_sprite_sorters) {
|
||||
if (sprite_sorter.fct_checker()) {
|
||||
_vp_sprite_sorter = sprite_sorter.fct_sorter;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -4448,7 +4463,7 @@ namespace citymania {
|
||||
_vd.dpi.left = left & mask;
|
||||
_vd.dpi.top = top & mask;
|
||||
_vd.dpi.pitch = old_dpi->pitch;
|
||||
_vd.last_child = nullptr;
|
||||
_vd.last_child = LAST_CHILD_NONE;
|
||||
|
||||
ViewportAddLandscape();
|
||||
ViewportAddVehicles(&_vd.dpi);
|
||||
|
||||
Reference in New Issue
Block a user