MCPcopy Create free account
hub / github.com/OpenTTD/OpenTTD / GreyscaleToMapHeights

Function GreyscaleToMapHeights

src/heightmap.cpp:307–397  ·  view source on GitHub ↗

* Converts a given greyscale map to something that fits in OTTD map system * and create a map of that data. * @param img_width the with of the image in pixels/tiles * @param img_height the height of the image in pixels/tiles * @param map the input map */

Source from the content-addressed store, hash-verified

305 * @param map the input map
306 */
307static void GreyscaleToMapHeights(uint img_width, uint img_height, std::span<const uint8_t> map)
308{
309 /* Defines the detail of the aspect ratio (to avoid doubles) */
310 const uint num_div = 16384;
311 /* Ensure multiplication with num_div does not cause overflows. */
312 static_assert(num_div <= std::numeric_limits<uint>::max() / MAX_HEIGHTMAP_SIDE_LENGTH_IN_PIXELS);
313
314 uint width, height;
315 uint row, col;
316 uint row_pad = 0, col_pad = 0;
317 uint img_scale;
318 uint img_row, img_col;
319 TileIndex tile;
320
321 /* Get map size and calculate scale and padding values */
322 switch (_settings_game.game_creation.heightmap_rotation) {
323 default: NOT_REACHED();
324 case HM_COUNTER_CLOCKWISE:
325 width = Map::SizeX();
326 height = Map::SizeY();
327 break;
328 case HM_CLOCKWISE:
329 width = Map::SizeY();
330 height = Map::SizeX();
331 break;
332 }
333
334 if ((img_width * num_div) / img_height > ((width * num_div) / height)) {
335 /* Image is wider than map - center vertically */
336 img_scale = (width * num_div) / img_width;
337 row_pad = (1 + height - ((img_height * img_scale) / num_div)) / 2;
338 } else {
339 /* Image is taller than map - center horizontally */
340 img_scale = (height * num_div) / img_height;
341 col_pad = (1 + width - ((img_width * img_scale) / num_div)) / 2;
342 }
343
344 if (_settings_game.construction.freeform_edges) {
345 for (uint x = 0; x < Map::SizeX(); x++) MakeVoid(TileXY(x, 0));
346 for (uint y = 0; y < Map::SizeY(); y++) MakeVoid(TileXY(0, y));
347 }
348
349 /* Form the landscape */
350 for (row = 0; row < height; row++) {
351 for (col = 0; col < width; col++) {
352 switch (_settings_game.game_creation.heightmap_rotation) {
353 default: NOT_REACHED();
354 case HM_COUNTER_CLOCKWISE: tile = TileXY(col, row); break;
355 case HM_CLOCKWISE: tile = TileXY(row, col); break;
356 }
357
358 /* Check if current tile is within the 1-pixel map edge or padding regions */
359 if ((!_settings_game.construction.freeform_edges && DistanceFromEdge(tile) <= 1) ||
360 (row < row_pad) || (row >= (height - row_pad - (_settings_game.construction.freeform_edges ? 0 : 1))) ||
361 (col < col_pad) || (col >= (width - col_pad - (_settings_game.construction.freeform_edges ? 0 : 1)))) {
362 SetTileHeight(tile, 0);
363 } else {
364 /* Use nearest neighbour resizing to scale map data.

Callers 1

LoadHeightmapFunction · 0.85

Calls 7

NOT_REACHEDFunction · 0.85
MakeVoidFunction · 0.85
TileXYFunction · 0.85
DistanceFromEdgeFunction · 0.85
SetTileHeightFunction · 0.85
IsInnerTileFunction · 0.85
MakeClearFunction · 0.85

Tested by

no test coverage detected