* Add the landscape to the viewport, i.e. all ground tiles and buildings. */
| 1208 | * Add the landscape to the viewport, i.e. all ground tiles and buildings. |
| 1209 | */ |
| 1210 | static void ViewportAddLandscape() |
| 1211 | { |
| 1212 | assert(_vd.dpi.top <= _vd.dpi.top + _vd.dpi.height); |
| 1213 | assert(_vd.dpi.left <= _vd.dpi.left + _vd.dpi.width); |
| 1214 | |
| 1215 | Point upper_left = InverseRemapCoords(_vd.dpi.left, _vd.dpi.top); |
| 1216 | Point upper_right = InverseRemapCoords(_vd.dpi.left + _vd.dpi.width, _vd.dpi.top); |
| 1217 | |
| 1218 | /* Transformations between tile coordinates and viewport rows/columns: See vp_column_row |
| 1219 | * column = y - x |
| 1220 | * row = x + y |
| 1221 | * x = (row - column) / 2 |
| 1222 | * y = (row + column) / 2 |
| 1223 | * Note: (row, columns) pairs are only valid, if they are both even or both odd. |
| 1224 | */ |
| 1225 | |
| 1226 | /* Columns overlap with neighbouring columns by a half tile. |
| 1227 | * - Left column is column of upper_left (rounded down) and one column to the left. |
| 1228 | * - Right column is column of upper_right (rounded up) and one column to the right. |
| 1229 | * Note: Integer-division does not round down for negative numbers, so ensure rounding with another increment/decrement. |
| 1230 | */ |
| 1231 | int left_column = (upper_left.y - upper_left.x) / (int)TILE_SIZE - 2; |
| 1232 | int right_column = (upper_right.y - upper_right.x) / (int)TILE_SIZE + 2; |
| 1233 | |
| 1234 | int potential_bridge_height = ZOOM_BASE * TILE_HEIGHT * _settings_game.construction.max_bridge_height; |
| 1235 | |
| 1236 | /* Rows overlap with neighbouring rows by a half tile. |
| 1237 | * The first row that could possibly be visible is the row above upper_left (if it is at height 0). |
| 1238 | * Due to integer-division not rounding down for negative numbers, we need another decrement. |
| 1239 | */ |
| 1240 | int row = (upper_left.x + upper_left.y) / (int)TILE_SIZE - 2; |
| 1241 | bool last_row = false; |
| 1242 | for (; !last_row; row++) { |
| 1243 | last_row = true; |
| 1244 | for (int column = left_column; column <= right_column; column++) { |
| 1245 | /* Valid row/column? */ |
| 1246 | if ((row + column) % 2 != 0) continue; |
| 1247 | |
| 1248 | Point tilecoord; |
| 1249 | tilecoord.x = (row - column) / 2; |
| 1250 | tilecoord.y = (row + column) / 2; |
| 1251 | assert(column == tilecoord.y - tilecoord.x); |
| 1252 | assert(row == tilecoord.y + tilecoord.x); |
| 1253 | |
| 1254 | TileType tile_type; |
| 1255 | _cur_ti.x = tilecoord.x * TILE_SIZE; |
| 1256 | _cur_ti.y = tilecoord.y * TILE_SIZE; |
| 1257 | |
| 1258 | if (IsInsideBS(tilecoord.x, 0, Map::SizeX()) && IsInsideBS(tilecoord.y, 0, Map::SizeY())) { |
| 1259 | /* This includes the south border at Map::MaxX / Map::MaxY. When terraforming we still draw tile selections there. */ |
| 1260 | _cur_ti.tile = TileXY(tilecoord.x, tilecoord.y); |
| 1261 | tile_type = GetTileType(_cur_ti.tile); |
| 1262 | } else { |
| 1263 | _cur_ti.tile = INVALID_TILE; |
| 1264 | tile_type = MP_VOID; |
| 1265 | } |
| 1266 | |
| 1267 | if (tile_type != MP_VOID) { |
no test coverage detected