mirror of
https://github.com/OpenRCT2/OpenRCT2
synced 2025-12-24 00:03:11 +01:00
Compile mapgen.c as C++
This commit is contained in:
committed by
GitHub
parent
36236d8c97
commit
a292917e50
@@ -21,6 +21,7 @@
|
||||
/* End PBXAggregateTarget section */
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
4C31B2E41FB6115600F6A38A /* MapGen.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C31B2E21FB6115600F6A38A /* MapGen.cpp */; };
|
||||
4C4C1E981F58226500560300 /* TrackDesign.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C4C1E971F58226500560300 /* TrackDesign.cpp */; };
|
||||
4C5DFF421FAC69D200CB093A /* Date.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C5DFF401FAC69D200CB093A /* Date.cpp */; };
|
||||
4C6AC20F1F9E1693004324AA /* Station.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C6AC20D1F9E1693004324AA /* Station.cpp */; };
|
||||
@@ -455,7 +456,6 @@
|
||||
F76C87A01EC4E88400FA49E2 /* map.c in Sources */ = {isa = PBXBuildFile; fileRef = F76C85681EC4E7CD00FA49E2 /* map.c */; };
|
||||
F76C87A21EC4E88400FA49E2 /* map_animation.c in Sources */ = {isa = PBXBuildFile; fileRef = F76C856A1EC4E7CD00FA49E2 /* map_animation.c */; };
|
||||
F76C87A41EC4E88500FA49E2 /* map_helpers.c in Sources */ = {isa = PBXBuildFile; fileRef = F76C856C1EC4E7CD00FA49E2 /* map_helpers.c */; };
|
||||
F76C87A61EC4E88500FA49E2 /* mapgen.c in Sources */ = {isa = PBXBuildFile; fileRef = F76C856E1EC4E7CD00FA49E2 /* mapgen.c */; };
|
||||
F76C87A81EC4E88500FA49E2 /* money_effect.c in Sources */ = {isa = PBXBuildFile; fileRef = F76C85701EC4E7CD00FA49E2 /* money_effect.c */; };
|
||||
F76C87A91EC4E88500FA49E2 /* park.c in Sources */ = {isa = PBXBuildFile; fileRef = F76C85711EC4E7CD00FA49E2 /* park.c */; };
|
||||
F76C87AB1EC4E88500FA49E2 /* particle.c in Sources */ = {isa = PBXBuildFile; fileRef = F76C85731EC4E7CD00FA49E2 /* particle.c */; };
|
||||
@@ -613,6 +613,9 @@
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
4C31B2E61FB7352900F6A38A /* Scenery.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Scenery.h; sourceTree = "<group>"; };
|
||||
4C31B2E21FB6115600F6A38A /* MapGen.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MapGen.cpp; sourceTree = "<group>"; };
|
||||
4C31B2E31FB6115600F6A38A /* MapGen.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MapGen.h; sourceTree = "<group>"; };
|
||||
4C31B2E51FB6116100F6A38A /* Location.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Location.h; sourceTree = "<group>"; };
|
||||
4C4C1E971F58226500560300 /* TrackDesign.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TrackDesign.cpp; sourceTree = "<group>"; };
|
||||
4C4C1E991F5832AA00560300 /* TrackDesign.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TrackDesign.h; sourceTree = "<group>"; };
|
||||
4C5DFF401FAC69D200CB093A /* Date.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Date.cpp; sourceTree = "<group>"; };
|
||||
@@ -1367,8 +1370,6 @@
|
||||
F76C856B1EC4E7CD00FA49E2 /* map_animation.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = map_animation.h; sourceTree = "<group>"; };
|
||||
F76C856C1EC4E7CD00FA49E2 /* map_helpers.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = map_helpers.c; sourceTree = "<group>"; };
|
||||
F76C856D1EC4E7CD00FA49E2 /* map_helpers.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = map_helpers.h; sourceTree = "<group>"; };
|
||||
F76C856E1EC4E7CD00FA49E2 /* mapgen.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = mapgen.c; sourceTree = "<group>"; };
|
||||
F76C856F1EC4E7CD00FA49E2 /* mapgen.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = mapgen.h; sourceTree = "<group>"; };
|
||||
F76C85701EC4E7CD00FA49E2 /* money_effect.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = money_effect.c; sourceTree = "<group>"; };
|
||||
F76C85711EC4E7CD00FA49E2 /* park.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = park.c; sourceTree = "<group>"; };
|
||||
F76C85721EC4E7CD00FA49E2 /* park.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = park.h; sourceTree = "<group>"; };
|
||||
@@ -2554,14 +2555,15 @@
|
||||
F76C85651EC4E7CD00FA49E2 /* footpath.h */,
|
||||
F76C85661EC4E7CD00FA49E2 /* Fountain.cpp */,
|
||||
F76C85671EC4E7CD00FA49E2 /* Fountain.h */,
|
||||
4C31B2E51FB6116100F6A38A /* Location.h */,
|
||||
F76C85681EC4E7CD00FA49E2 /* map.c */,
|
||||
F76C85691EC4E7CD00FA49E2 /* map.h */,
|
||||
F76C856A1EC4E7CD00FA49E2 /* map_animation.c */,
|
||||
F76C856B1EC4E7CD00FA49E2 /* map_animation.h */,
|
||||
F76C856C1EC4E7CD00FA49E2 /* map_helpers.c */,
|
||||
F76C856D1EC4E7CD00FA49E2 /* map_helpers.h */,
|
||||
F76C856E1EC4E7CD00FA49E2 /* mapgen.c */,
|
||||
F76C856F1EC4E7CD00FA49E2 /* mapgen.h */,
|
||||
4C31B2E21FB6115600F6A38A /* MapGen.cpp */,
|
||||
4C31B2E31FB6115600F6A38A /* MapGen.h */,
|
||||
F76C85701EC4E7CD00FA49E2 /* money_effect.c */,
|
||||
F76C85711EC4E7CD00FA49E2 /* park.c */,
|
||||
F76C85721EC4E7CD00FA49E2 /* park.h */,
|
||||
@@ -3312,6 +3314,7 @@
|
||||
4C93F1911F8B747A00A9330D /* SwingingInverterShip.cpp in Sources */,
|
||||
4C93F1461F8B744400A9330D /* LayDownRollerCoaster.cpp in Sources */,
|
||||
4C93F1991F8B748200A9330D /* Chairlift.cpp in Sources */,
|
||||
4C31B2E41FB6115600F6A38A /* MapGen.cpp in Sources */,
|
||||
4C6AC20F1F9E1693004324AA /* Station.cpp in Sources */,
|
||||
C64644FE1F3FA4120026AC2D /* Main.cpp in Sources */,
|
||||
4C93F16B1F8B745700A9330D /* CircusShow.cpp in Sources */,
|
||||
@@ -3533,7 +3536,6 @@
|
||||
F76C87A01EC4E88400FA49E2 /* map.c in Sources */,
|
||||
F76C87A21EC4E88400FA49E2 /* map_animation.c in Sources */,
|
||||
F76C87A41EC4E88500FA49E2 /* map_helpers.c in Sources */,
|
||||
F76C87A61EC4E88500FA49E2 /* mapgen.c in Sources */,
|
||||
F76C87A81EC4E88500FA49E2 /* money_effect.c in Sources */,
|
||||
F76C87A91EC4E88500FA49E2 /* park.c in Sources */,
|
||||
F76C87AB1EC4E88500FA49E2 /* particle.c in Sources */,
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
#include <openrct2/interface/land_tool.h>
|
||||
#include <openrct2/interface/widget.h>
|
||||
#include <openrct2/util/util.h>
|
||||
#include <openrct2/world/mapgen.h>
|
||||
#include <openrct2/world/MapGen.h>
|
||||
#include <openrct2/windows/dropdown.h>
|
||||
|
||||
enum {
|
||||
|
||||
@@ -16,36 +16,41 @@
|
||||
|
||||
#include "../common.h"
|
||||
#include <math.h>
|
||||
#include <vector>
|
||||
|
||||
#include "../Context.h"
|
||||
#include "../Imaging.h"
|
||||
#include "../core/Guard.hpp"
|
||||
#include "../core/Math.hpp"
|
||||
#include "../core/String.hpp"
|
||||
#include "../core/Util.hpp"
|
||||
#include "../game.h"
|
||||
#include "../Imaging.h"
|
||||
#include "../localisation/string_ids.h"
|
||||
#include "../object.h"
|
||||
#include "../platform/platform.h"
|
||||
#include "../util/util.h"
|
||||
#include "map.h"
|
||||
#include "map_helpers.h"
|
||||
#include "mapgen.h"
|
||||
#include "MapGen.h"
|
||||
#include "scenery.h"
|
||||
|
||||
#pragma region Height map struct
|
||||
|
||||
static struct {
|
||||
static struct
|
||||
{
|
||||
uint32 width, height;
|
||||
uint8 *mono_bitmap;
|
||||
uint8 * mono_bitmap;
|
||||
} _heightMapData = {
|
||||
.width = 0,
|
||||
.height = 0,
|
||||
.mono_bitmap = NULL
|
||||
0,
|
||||
0,
|
||||
nullptr
|
||||
};
|
||||
|
||||
#pragma endregion Height map struct
|
||||
|
||||
#pragma region Random objects
|
||||
|
||||
static const char *GrassTrees[] = {
|
||||
static const char * GrassTrees[] = {
|
||||
// Dark
|
||||
"TCF ", // Caucasian Fir Tree
|
||||
"TRF ", // Red Fir Tree
|
||||
@@ -61,7 +66,7 @@ static const char *GrassTrees[] = {
|
||||
"TEL ", // European Larch Tree
|
||||
};
|
||||
|
||||
static const char *DesertTrees[] = {
|
||||
static const char * DesertTrees[] = {
|
||||
"TMP ", // Monkey-Puzzle Tree
|
||||
"THL ", // Honey Locust Tree
|
||||
"TH1 ", // Canary Palm Tree
|
||||
@@ -72,7 +77,7 @@ static const char *DesertTrees[] = {
|
||||
"TSC ", // Cactus
|
||||
};
|
||||
|
||||
static const char *SnowTrees[] = {
|
||||
static const char * SnowTrees[] = {
|
||||
"TCFS ", // Snow-covered Caucasian Fir Tree
|
||||
"TNSS ", // Snow-covered Norway Spruce Tree
|
||||
"TRF3 ", // Snow-covered Red Fir Tree
|
||||
@@ -82,21 +87,19 @@ static const char *SnowTrees[] = {
|
||||
#pragma endregion
|
||||
|
||||
// Randomly chosen base terrains. We rarely want a whole map made out of chequerboard or rock.
|
||||
static const uint8 BaseTerrain[] = { TERRAIN_GRASS, TERRAIN_SAND, TERRAIN_SAND_LIGHT, TERRAIN_DIRT, TERRAIN_ICE };
|
||||
static const uint8 BaseTerrain[] = {TERRAIN_GRASS, TERRAIN_SAND, TERRAIN_SAND_LIGHT, TERRAIN_DIRT, TERRAIN_ICE};
|
||||
|
||||
#define BLOB_HEIGHT 255
|
||||
|
||||
static void mapgen_place_trees();
|
||||
static void mapgen_set_water_level(sint32 waterLevel);
|
||||
static void mapgen_blobs(sint32 count, sint32 lowSize, sint32 highSize, sint32 lowHeight, sint32 highHeight);
|
||||
static void mapgen_blob(sint32 cx, sint32 cy, sint32 size, sint32 height);
|
||||
static void mapgen_smooth_height(sint32 iterations);
|
||||
static void mapgen_set_height();
|
||||
|
||||
static void mapgen_simplex(mapgen_settings *settings);
|
||||
static void mapgen_simplex(mapgen_settings * settings);
|
||||
|
||||
static sint32 _heightSize;
|
||||
static uint8 *_height;
|
||||
static uint8 * _height;
|
||||
|
||||
static sint32 get_height(sint32 x, sint32 y)
|
||||
{
|
||||
@@ -112,16 +115,18 @@ static void set_height(sint32 x, sint32 y, sint32 height)
|
||||
_height[x + y * _heightSize] = height;
|
||||
}
|
||||
|
||||
void mapgen_generate_blank(mapgen_settings *settings)
|
||||
void mapgen_generate_blank(mapgen_settings * settings)
|
||||
{
|
||||
sint32 x, y;
|
||||
rct_tile_element *tileElement;
|
||||
rct_tile_element * tileElement;
|
||||
|
||||
map_clear_all_elements();
|
||||
|
||||
map_init(settings->mapSize);
|
||||
for (y = 1; y < settings->mapSize - 1; y++) {
|
||||
for (x = 1; x < settings->mapSize - 1; x++) {
|
||||
for (y = 1; y < settings->mapSize - 1; y++)
|
||||
{
|
||||
for (x = 1; x < settings->mapSize - 1; x++)
|
||||
{
|
||||
tileElement = map_get_surface_element_at(x, y);
|
||||
tile_element_set_terrain(tileElement, settings->floor);
|
||||
tile_element_set_terrain_edge(tileElement, settings->wall);
|
||||
@@ -133,12 +138,12 @@ void mapgen_generate_blank(mapgen_settings *settings)
|
||||
mapgen_set_water_level(settings->water_level);
|
||||
}
|
||||
|
||||
void mapgen_generate(mapgen_settings *settings)
|
||||
void mapgen_generate(mapgen_settings * settings)
|
||||
{
|
||||
sint32 x, y, mapSize, floorTexture, wallTexture, waterLevel;
|
||||
rct_tile_element *tileElement;
|
||||
rct_tile_element * tileElement;
|
||||
|
||||
util_srand((sint32)platform_get_ticks());
|
||||
util_srand((sint32) platform_get_ticks());
|
||||
|
||||
mapSize = settings->mapSize;
|
||||
floorTexture = settings->floor;
|
||||
@@ -146,11 +151,13 @@ void mapgen_generate(mapgen_settings *settings)
|
||||
waterLevel = settings->water_level;
|
||||
|
||||
if (floorTexture == -1)
|
||||
floorTexture = BaseTerrain[util_rand() % countof(BaseTerrain)];
|
||||
floorTexture = BaseTerrain[util_rand() % Util::CountOf(BaseTerrain)];
|
||||
|
||||
if (wallTexture == -1) {
|
||||
if (wallTexture == -1)
|
||||
{
|
||||
// Base edge type on surface type
|
||||
switch (floorTexture) {
|
||||
switch (floorTexture)
|
||||
{
|
||||
case TERRAIN_DIRT:
|
||||
wallTexture = TERRAIN_EDGE_WOOD_RED;
|
||||
break;
|
||||
@@ -167,8 +174,10 @@ void mapgen_generate(mapgen_settings *settings)
|
||||
|
||||
// Initialise the base map
|
||||
map_init(mapSize);
|
||||
for (y = 1; y < mapSize - 1; y++) {
|
||||
for (x = 1; x < mapSize - 1; x++) {
|
||||
for (y = 1; y < mapSize - 1; y++)
|
||||
{
|
||||
for (x = 1; x < mapSize - 1; x++)
|
||||
{
|
||||
tileElement = map_get_surface_element_at(x, y);
|
||||
tile_element_set_terrain(tileElement, floorTexture);
|
||||
tile_element_set_terrain_edge(tileElement, wallTexture);
|
||||
@@ -179,40 +188,28 @@ void mapgen_generate(mapgen_settings *settings)
|
||||
|
||||
// Create the temporary height map and initialise
|
||||
_heightSize = mapSize * 2;
|
||||
_height = (uint8*)malloc(_heightSize * _heightSize * sizeof(uint8));
|
||||
_height = new uint8[_heightSize * _heightSize];
|
||||
memset(_height, 0, _heightSize * _heightSize * sizeof(uint8));
|
||||
|
||||
if (1) {
|
||||
mapgen_simplex(settings);
|
||||
mapgen_smooth_height(2 + (util_rand() % 6));
|
||||
} else {
|
||||
// Keep overwriting the map with rough circular blobs of different sizes and heights.
|
||||
// This procedural method can produce intersecting contour like land and lakes.
|
||||
// Large blobs, general shape of map
|
||||
mapgen_blobs(6, _heightSize / 2, _heightSize * 4, 4, 16);
|
||||
// Medium blobs
|
||||
mapgen_blobs(12, _heightSize / 16, _heightSize / 8, 4, 18);
|
||||
// Small blobs, small hills and lakes
|
||||
mapgen_blobs(32, _heightSize / 32, _heightSize / 16, 4, 18);
|
||||
|
||||
// Smooth the land so that there aren't cliffs round every blob.
|
||||
mapgen_smooth_height(2);
|
||||
}
|
||||
|
||||
// Set the game map to the height map
|
||||
mapgen_set_height();
|
||||
free(_height);
|
||||
delete[] _height;
|
||||
|
||||
// Set the tile slopes so that there are no cliffs
|
||||
while (map_smooth(1, 1, mapSize - 1, mapSize - 1)) { }
|
||||
while (map_smooth(1, 1, mapSize - 1, mapSize - 1)) {}
|
||||
|
||||
// Add the water
|
||||
mapgen_set_water_level(waterLevel);
|
||||
|
||||
// Add sandy beaches
|
||||
sint32 beachTexture = floorTexture;
|
||||
if (settings->floor == -1 && floorTexture == TERRAIN_GRASS) {
|
||||
switch (util_rand() % 4) {
|
||||
if (settings->floor == -1 && floorTexture == TERRAIN_GRASS)
|
||||
{
|
||||
switch (util_rand() % 4)
|
||||
{
|
||||
case 0:
|
||||
beachTexture = TERRAIN_SAND;
|
||||
break;
|
||||
@@ -221,8 +218,10 @@ void mapgen_generate(mapgen_settings *settings)
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (y = 1; y < mapSize - 1; y++) {
|
||||
for (x = 1; x < mapSize - 1; x++) {
|
||||
for (y = 1; y < mapSize - 1; y++)
|
||||
{
|
||||
for (x = 1; x < mapSize - 1; x++)
|
||||
{
|
||||
tileElement = map_get_surface_element_at(x, y);
|
||||
|
||||
if (tileElement->base_height < waterLevel + 6)
|
||||
@@ -240,12 +239,12 @@ void mapgen_generate(mapgen_settings *settings)
|
||||
static void mapgen_place_tree(sint32 type, sint32 x, sint32 y)
|
||||
{
|
||||
sint32 surfaceZ;
|
||||
rct_tile_element *tileElement;
|
||||
rct_scenery_entry *sceneryEntry = get_small_scenery_entry(type);
|
||||
rct_tile_element * tileElement;
|
||||
rct_scenery_entry * sceneryEntry = get_small_scenery_entry(type);
|
||||
|
||||
surfaceZ = tile_element_height(x * 32 + 16, y * 32 + 16) / 8;
|
||||
tileElement = tile_element_insert(x, y, surfaceZ, (1 | 2 | 4 | 8));
|
||||
assert(tileElement != NULL);
|
||||
assert(tileElement != nullptr);
|
||||
tileElement->clearance_height = surfaceZ + (sceneryEntry->small_scenery.height >> 3);
|
||||
|
||||
tileElement->type = TILE_ELEMENT_TYPE_SCENERY | (util_rand() & 3);
|
||||
@@ -259,66 +258,79 @@ static void mapgen_place_tree(sint32 type, sint32 x, sint32 y)
|
||||
*/
|
||||
static void mapgen_place_trees()
|
||||
{
|
||||
sint32 numGrassTreeIds = 0, numDesertTreeIds = 0, numSnowTreeIds = 0;
|
||||
sint32 *grassTreeIds = (sint32*)malloc(countof(GrassTrees) * sizeof(sint32));
|
||||
sint32 *desertTreeIds = (sint32*)malloc(countof(DesertTrees) * sizeof(sint32));
|
||||
sint32 *snowTreeIds = (sint32*)malloc(countof(SnowTrees) * sizeof(sint32));
|
||||
std::vector<sint32> grassTreeIds(Util::CountOf(GrassTrees), 0);
|
||||
std::vector<sint32> desertTreeIds(Util::CountOf(DesertTrees), 0);
|
||||
std::vector<sint32> snowTreeIds(Util::CountOf(SnowTrees), 0);
|
||||
|
||||
for (sint32 i = 0; i < object_entry_group_counts[OBJECT_TYPE_SMALL_SCENERY]; i++) {
|
||||
rct_scenery_entry *sceneryEntry = get_small_scenery_entry(i);
|
||||
rct_object_entry_extended *entry = &object_entry_groups[OBJECT_TYPE_SMALL_SCENERY].entries[i];
|
||||
for (sint32 i = 0; i < object_entry_group_counts[OBJECT_TYPE_SMALL_SCENERY]; i++)
|
||||
{
|
||||
rct_scenery_entry * sceneryEntry = get_small_scenery_entry(i);
|
||||
rct_object_entry_extended * entry = &object_entry_groups[OBJECT_TYPE_SMALL_SCENERY].entries[i];
|
||||
|
||||
if (sceneryEntry == NULL)
|
||||
if (sceneryEntry == nullptr)
|
||||
continue;
|
||||
|
||||
sint32 j;
|
||||
for (j = 0; j < countof(GrassTrees); j++)
|
||||
uint32 j;
|
||||
for (j = 0; j < Util::CountOf(GrassTrees); j++)
|
||||
{
|
||||
if (strncmp(GrassTrees[j], entry->name, 8) == 0)
|
||||
break;
|
||||
if (j != countof(GrassTrees)) {
|
||||
grassTreeIds[numGrassTreeIds++] = i;
|
||||
}
|
||||
if (j != Util::CountOf(GrassTrees))
|
||||
{
|
||||
grassTreeIds.push_back(i);
|
||||
continue;
|
||||
}
|
||||
|
||||
for (j = 0; j < countof(DesertTrees); j++)
|
||||
for (j = 0; j < Util::CountOf(DesertTrees); j++)
|
||||
{
|
||||
if (strncmp(DesertTrees[j], entry->name, 8) == 0)
|
||||
break;
|
||||
if (j != countof(DesertTrees)) {
|
||||
desertTreeIds[numDesertTreeIds++] = i;
|
||||
}
|
||||
if (j != Util::CountOf(DesertTrees))
|
||||
{
|
||||
desertTreeIds.push_back(i);
|
||||
continue;
|
||||
}
|
||||
|
||||
for (j = 0; j < countof(SnowTrees); j++)
|
||||
for (j = 0; j < Util::CountOf(SnowTrees); j++)
|
||||
{
|
||||
if (strncmp(SnowTrees[j], entry->name, 8) == 0)
|
||||
break;
|
||||
if (j != countof(SnowTrees)) {
|
||||
snowTreeIds[numSnowTreeIds++] = i;
|
||||
}
|
||||
if (j != Util::CountOf(SnowTrees))
|
||||
{
|
||||
snowTreeIds.push_back(i);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
sint32 availablePositionsCount = 0;
|
||||
struct { sint32 x; sint32 y; } tmp, *pos, *availablePositions;
|
||||
availablePositions = malloc(MAXIMUM_MAP_SIZE_TECHNICAL * MAXIMUM_MAP_SIZE_TECHNICAL * sizeof(tmp));
|
||||
LocationXY32 tmp, pos;
|
||||
|
||||
std::vector<LocationXY32> availablePositions;
|
||||
|
||||
// Create list of available tiles
|
||||
for (sint32 y = 1; y < gMapSize - 1; y++) {
|
||||
for (sint32 x = 1; x < gMapSize - 1; x++) {
|
||||
rct_tile_element *tileElement = map_get_surface_element_at(x, y);
|
||||
for (sint32 y = 1; y < gMapSize - 1; y++)
|
||||
{
|
||||
for (sint32 x = 1; x < gMapSize - 1; x++)
|
||||
{
|
||||
rct_tile_element * tileElement = map_get_surface_element_at(x, y);
|
||||
|
||||
// Exclude water tiles
|
||||
if (map_get_water_height(tileElement) > 0)
|
||||
continue;
|
||||
|
||||
pos = &availablePositions[availablePositionsCount++];
|
||||
pos->x = x;
|
||||
pos->y = y;
|
||||
pos.x = x;
|
||||
pos.y = y;
|
||||
availablePositions.push_back(pos);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// Shuffle list
|
||||
for (sint32 i = 0; i < availablePositionsCount; i++) {
|
||||
sint32 rindex = util_rand() % availablePositionsCount;
|
||||
for (uint32 i = 0; i < availablePositions.size(); i++)
|
||||
{
|
||||
uint32 rindex = util_rand() % availablePositions.size();
|
||||
if (rindex == i)
|
||||
continue;
|
||||
|
||||
@@ -329,49 +341,46 @@ static void mapgen_place_trees()
|
||||
|
||||
// Place trees
|
||||
float treeToLandRatio = (10 + (util_rand() % 30)) / 100.0f;
|
||||
sint32 numTrees = max(4, (sint32)(availablePositionsCount * treeToLandRatio));
|
||||
sint32 numTrees = Math::Max(4, (sint32) (availablePositions.size() * treeToLandRatio));
|
||||
|
||||
for (sint32 i = 0; i < numTrees; i++) {
|
||||
pos = &availablePositions[i];
|
||||
for (sint32 i = 0; i < numTrees; i++)
|
||||
{
|
||||
pos = availablePositions[i];
|
||||
|
||||
sint32 type = -1;
|
||||
rct_tile_element *tileElement = map_get_surface_element_at(pos->x, pos->y);
|
||||
switch (tile_element_get_terrain(tileElement)) {
|
||||
rct_tile_element * tileElement = map_get_surface_element_at(pos.x, pos.y);
|
||||
switch (tile_element_get_terrain(tileElement))
|
||||
{
|
||||
case TERRAIN_GRASS:
|
||||
case TERRAIN_DIRT:
|
||||
case TERRAIN_GRASS_CLUMPS:
|
||||
if (numGrassTreeIds == 0)
|
||||
if (grassTreeIds.size() == 0)
|
||||
break;
|
||||
|
||||
type = grassTreeIds[util_rand() % numGrassTreeIds];
|
||||
type = grassTreeIds[util_rand() % grassTreeIds.size()];
|
||||
break;
|
||||
|
||||
case TERRAIN_SAND:
|
||||
case TERRAIN_SAND_DARK:
|
||||
case TERRAIN_SAND_LIGHT:
|
||||
if (numDesertTreeIds == 0)
|
||||
if (desertTreeIds.size() == 0)
|
||||
break;
|
||||
|
||||
if (util_rand() % 4 == 0)
|
||||
type = desertTreeIds[util_rand() % numDesertTreeIds];
|
||||
type = desertTreeIds[util_rand() % desertTreeIds.size()];
|
||||
break;
|
||||
|
||||
case TERRAIN_ICE:
|
||||
if (numSnowTreeIds == 0)
|
||||
if (snowTreeIds.size() == 0)
|
||||
break;
|
||||
|
||||
type = snowTreeIds[util_rand() % numSnowTreeIds];
|
||||
type = snowTreeIds[util_rand() % snowTreeIds.size()];
|
||||
break;
|
||||
}
|
||||
|
||||
if (type != -1)
|
||||
mapgen_place_tree(type, pos->x, pos->y);
|
||||
mapgen_place_tree(type, pos.x, pos.y);
|
||||
}
|
||||
|
||||
free(availablePositions);
|
||||
free(grassTreeIds);
|
||||
free(desertTreeIds);
|
||||
free(snowTreeIds);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -380,12 +389,14 @@ static void mapgen_place_trees()
|
||||
static void mapgen_set_water_level(sint32 waterLevel)
|
||||
{
|
||||
sint32 x, y, mapSize;
|
||||
rct_tile_element *tileElement;
|
||||
rct_tile_element * tileElement;
|
||||
|
||||
mapSize = gMapSize;
|
||||
|
||||
for (y = 1; y < mapSize - 1; y++) {
|
||||
for (x = 1; x < mapSize - 1; x++) {
|
||||
for (y = 1; y < mapSize - 1; y++)
|
||||
{
|
||||
for (x = 1; x < mapSize - 1; x++)
|
||||
{
|
||||
tileElement = map_get_surface_element_at(x, y);
|
||||
if (tileElement->base_height < waterLevel)
|
||||
tileElement->properties.surface.terrain |= (waterLevel / 2);
|
||||
@@ -393,194 +404,6 @@ static void mapgen_set_water_level(sint32 waterLevel)
|
||||
}
|
||||
}
|
||||
|
||||
static void mapgen_blobs(sint32 count, sint32 lowSize, sint32 highSize, sint32 lowHeight, sint32 highHeight)
|
||||
{
|
||||
sint32 i;
|
||||
sint32 sizeRange = highSize - lowSize;
|
||||
sint32 heightRange = highHeight - lowHeight;
|
||||
|
||||
sint32 border = 2 + (util_rand() % 24);
|
||||
sint32 borderRange = _heightSize - (border * 2);
|
||||
for (i = 0; i < count; i++) {
|
||||
sint32 radius = lowSize + (util_rand() % sizeRange);
|
||||
mapgen_blob(
|
||||
border + (util_rand() % borderRange),
|
||||
border + (util_rand() % borderRange),
|
||||
(sint32)(M_PI * radius * radius),
|
||||
lowHeight + (util_rand() % heightRange)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets any holes within a new created blob to the specified height.
|
||||
*/
|
||||
static void mapgen_blob_fill(sint32 height)
|
||||
{
|
||||
// For each square find out whether it is landlocked by BLOB_HEIGHT and then fill it if it is
|
||||
sint32 left = 0,
|
||||
top = 0,
|
||||
right = _heightSize - 1,
|
||||
bottom = _heightSize - 1;
|
||||
|
||||
uint8 *landX = (uint8*)malloc(_heightSize * _heightSize * sizeof(uint8));
|
||||
sint32 firstLand, lastLand;
|
||||
|
||||
// Check each row and see if each tile is between first land x and last land x
|
||||
for (sint32 y = top; y <= bottom; y++) {
|
||||
// Calculate first land
|
||||
firstLand = -1;
|
||||
for (sint32 xx = left; xx <= right; xx++) {
|
||||
if (get_height(xx, y) == BLOB_HEIGHT) {
|
||||
firstLand = xx;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
lastLand = -1;
|
||||
if (firstLand >= 0) {
|
||||
// Calculate last land
|
||||
for (sint32 xx = right; xx >= left; xx--) {
|
||||
if (get_height(xx, y) == BLOB_HEIGHT) {
|
||||
lastLand = xx;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// No land on this row
|
||||
continue;
|
||||
}
|
||||
|
||||
for (sint32 x = left; x <= right; x++)
|
||||
if (x >= firstLand && x <= lastLand)
|
||||
landX[x * _heightSize + y] = 1;
|
||||
}
|
||||
|
||||
// Do the same for Y
|
||||
for (sint32 x = left; x <= right; x++) {
|
||||
// Calculate first land
|
||||
firstLand = -1;
|
||||
for (sint32 yy = top; yy <= bottom; yy++) {
|
||||
if (get_height(x, yy) == BLOB_HEIGHT) {
|
||||
firstLand = yy;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
lastLand = -1;
|
||||
if (firstLand >= 0) {
|
||||
// Calculate last land
|
||||
for (sint32 yy = bottom; yy >= top; yy--) {
|
||||
if (get_height(x, yy) == BLOB_HEIGHT) {
|
||||
lastLand = yy;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// No land on this row
|
||||
continue;
|
||||
}
|
||||
|
||||
for (sint32 y = top; y <= bottom; y++) {
|
||||
if (y >= firstLand && y <= lastLand && landX[x * _heightSize + y]) {
|
||||
// Not only do we know it's landlocked to both x and y
|
||||
// we can change the land too
|
||||
set_height(x, y, BLOB_HEIGHT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Replace all the BLOB_HEIGHT with the actual land height
|
||||
for (sint32 x = left; x <= right; x++)
|
||||
for (sint32 y = top; y <= bottom; y++)
|
||||
if (get_height(x, y) == BLOB_HEIGHT)
|
||||
set_height(x, y, height);
|
||||
|
||||
free(landX);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a rough circular blob of tiles of the specified size to the specified height.
|
||||
*/
|
||||
static void mapgen_blob(sint32 cx, sint32 cy, sint32 size, sint32 height)
|
||||
{
|
||||
sint32 x, y, currentSize, direction;
|
||||
|
||||
x = cx;
|
||||
y = cy;
|
||||
currentSize = 1;
|
||||
direction = 0;
|
||||
set_height(x, y, BLOB_HEIGHT);
|
||||
|
||||
while (currentSize < size) {
|
||||
if (util_rand() % 2 == 0) {
|
||||
set_height(x, y, BLOB_HEIGHT);
|
||||
currentSize++;
|
||||
}
|
||||
|
||||
switch (direction) {
|
||||
case 0:
|
||||
if (y == 0) {
|
||||
currentSize = size;
|
||||
break;
|
||||
}
|
||||
|
||||
y--;
|
||||
if (get_height(x + 1, y) != BLOB_HEIGHT)
|
||||
direction = 1;
|
||||
else if (get_height(x, y - 1) != BLOB_HEIGHT)
|
||||
direction = 0;
|
||||
else if (get_height(x - 1, y) != BLOB_HEIGHT)
|
||||
direction = 3;
|
||||
break;
|
||||
case 1:
|
||||
if (x == _heightSize - 1) {
|
||||
currentSize = size;
|
||||
break;
|
||||
}
|
||||
|
||||
x++;
|
||||
if (get_height(x, y + 1) != BLOB_HEIGHT)
|
||||
direction = 2;
|
||||
else if (get_height(x + 1, y) != BLOB_HEIGHT)
|
||||
direction = 1;
|
||||
else if (get_height(x, y - 1) != BLOB_HEIGHT)
|
||||
direction = 0;
|
||||
break;
|
||||
case 2:
|
||||
if (y == _heightSize - 1) {
|
||||
currentSize = size;
|
||||
break;
|
||||
}
|
||||
|
||||
y++;
|
||||
if (get_height(x - 1, y) != BLOB_HEIGHT)
|
||||
direction = 3;
|
||||
else if (get_height(x, y + 1) != BLOB_HEIGHT)
|
||||
direction = 2;
|
||||
else if (get_height(x + 1, y) != BLOB_HEIGHT)
|
||||
direction = 1;
|
||||
break;
|
||||
case 3:
|
||||
if (x == 0) {
|
||||
currentSize = size;
|
||||
break;
|
||||
}
|
||||
|
||||
x--;
|
||||
if (get_height(x, y - 1) != BLOB_HEIGHT)
|
||||
direction = 0;
|
||||
else if (get_height(x - 1, y) != BLOB_HEIGHT)
|
||||
direction = 3;
|
||||
else if (get_height(x, y + 1) != BLOB_HEIGHT)
|
||||
direction = 2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
mapgen_blob_fill(height);
|
||||
}
|
||||
|
||||
/**
|
||||
* Smooths the height map.
|
||||
*/
|
||||
@@ -588,23 +411,30 @@ static void mapgen_smooth_height(sint32 iterations)
|
||||
{
|
||||
sint32 i, x, y, xx, yy, avg;
|
||||
sint32 arraySize = _heightSize * _heightSize * sizeof(uint8);
|
||||
uint8 *copyHeight = malloc(arraySize);
|
||||
uint8 * copyHeight = new uint8[arraySize];
|
||||
|
||||
for (i = 0; i < iterations; i++) {
|
||||
for (i = 0; i < iterations; i++)
|
||||
{
|
||||
memcpy(copyHeight, _height, arraySize);
|
||||
for (y = 1; y < _heightSize - 1; y++) {
|
||||
for (x = 1; x < _heightSize - 1; x++) {
|
||||
for (y = 1; y < _heightSize - 1; y++)
|
||||
{
|
||||
for (x = 1; x < _heightSize - 1; x++)
|
||||
{
|
||||
avg = 0;
|
||||
for (yy = -1; yy <= 1; yy++)
|
||||
{
|
||||
for (xx = -1; xx <= 1; xx++)
|
||||
{
|
||||
avg += copyHeight[(y + yy) * _heightSize + (x + xx)];
|
||||
}
|
||||
}
|
||||
avg /= 9;
|
||||
set_height(x, y, avg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
free(copyHeight);
|
||||
delete[] copyHeight;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -613,11 +443,13 @@ static void mapgen_smooth_height(sint32 iterations)
|
||||
static void mapgen_set_height()
|
||||
{
|
||||
sint32 x, y, heightX, heightY, mapSize;
|
||||
rct_tile_element *tileElement;
|
||||
rct_tile_element * tileElement;
|
||||
|
||||
mapSize = _heightSize / 2;
|
||||
for (y = 1; y < mapSize - 1; y++) {
|
||||
for (x = 1; x < mapSize - 1; x++) {
|
||||
for (y = 1; y < mapSize - 1; y++)
|
||||
{
|
||||
for (x = 1; x < mapSize - 1; x++)
|
||||
{
|
||||
heightX = x * 2;
|
||||
heightY = y * 2;
|
||||
|
||||
@@ -629,7 +461,7 @@ static void mapgen_set_height()
|
||||
uint8 baseHeight = (q00 + q01 + q10 + q11) / 4;
|
||||
|
||||
tileElement = map_get_surface_element_at(x, y);
|
||||
tileElement->base_height = max(2, baseHeight * 2);
|
||||
tileElement->base_height = Math::Max(2, baseHeight * 2);
|
||||
tileElement->clearance_height = tileElement->base_height;
|
||||
|
||||
if (q00 > baseHeight)
|
||||
@@ -661,15 +493,18 @@ static uint8 perm[512];
|
||||
|
||||
static void noise_rand()
|
||||
{
|
||||
for (sint32 i = 0; i < countof(perm); i++)
|
||||
for (uint32 i = 0; i < Util::CountOf(perm); i++)
|
||||
{
|
||||
perm[i] = util_rand() & 0xFF;
|
||||
}
|
||||
}
|
||||
|
||||
static float fractal_noise(sint32 x, sint32 y, float frequency, sint32 octaves, float lacunarity, float persistence)
|
||||
{
|
||||
float total = 0.0f;
|
||||
float amplitude = persistence;
|
||||
for (sint32 i = 0; i < octaves; i++) {
|
||||
for (sint32 i = 0; i < octaves; i++)
|
||||
{
|
||||
total += generate(x * frequency, y * frequency) * amplitude;
|
||||
frequency *= lacunarity;
|
||||
amplitude *= persistence;
|
||||
@@ -691,7 +526,7 @@ static float generate(float x, float y)
|
||||
sint32 i = fast_floor(xs);
|
||||
sint32 j = fast_floor(ys);
|
||||
|
||||
float t = (float)(i + j) * G2;
|
||||
float t = (float) (i + j) * G2;
|
||||
float X0 = i - t; // Unskew the cell origin back to (x,y) space
|
||||
float Y0 = j - t;
|
||||
float x0 = x - X0; // The x,y distances from the cell origin
|
||||
@@ -700,8 +535,16 @@ static float generate(float x, float y)
|
||||
// For the 2D case, the simplex shape is an equilateral triangle.
|
||||
// Determine which simplex we are in.
|
||||
sint32 i1, j1; // Offsets for second (middle) corner of simplex in (i,j) coords
|
||||
if (x0 > y0) { i1 = 1; j1 = 0; } // lower triangle, XY order: (0,0)->(1,0)->(1,1)
|
||||
else { i1 = 0; j1 = 1; } // upper triangle, YX order: (0,0)->(0,1)->(1,1)
|
||||
if (x0 > y0)
|
||||
{
|
||||
i1 = 1;
|
||||
j1 = 0;
|
||||
} // lower triangle, XY order: (0,0)->(1,0)->(1,1)
|
||||
else
|
||||
{
|
||||
i1 = 0;
|
||||
j1 = 1;
|
||||
} // upper triangle, YX order: (0,0)->(0,1)->(1,1)
|
||||
|
||||
// A step of (1,0) in (i,j) means a step of (1-c,-c) in (x,y), and
|
||||
// a step of (0,1) in (i,j) means a step of (-c,1-c) in (x,y), where
|
||||
@@ -718,22 +561,34 @@ static float generate(float x, float y)
|
||||
|
||||
// Calculate the contribution from the three corners
|
||||
float t0 = 0.5f - x0 * x0 - y0 * y0;
|
||||
if (t0 < 0.0f) n0 = 0.0f;
|
||||
else {
|
||||
if (t0 < 0.0f)
|
||||
{
|
||||
n0 = 0.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
t0 *= t0;
|
||||
n0 = t0 * t0 * grad(perm[ii + perm[jj]], x0, y0);
|
||||
}
|
||||
|
||||
float t1 = 0.5f - x1 * x1 - y1 * y1;
|
||||
if (t1 < 0.0f) n1 = 0.0f;
|
||||
else {
|
||||
if (t1 < 0.0f)
|
||||
{
|
||||
n1 = 0.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
t1 *= t1;
|
||||
n1 = t1 * t1 * grad(perm[ii + i1 + perm[jj + j1]], x1, y1);
|
||||
}
|
||||
|
||||
float t2 = 0.5f - x2 * x2 - y2 * y2;
|
||||
if (t2 < 0.0f) n2 = 0.0f;
|
||||
else {
|
||||
if (t2 < 0.0f)
|
||||
{
|
||||
n2 = 0.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
t2 *= t2;
|
||||
n2 = t2 * t2 * grad(perm[ii + 1 + perm[jj + 1]], x2, y2);
|
||||
}
|
||||
@@ -745,7 +600,7 @@ static float generate(float x, float y)
|
||||
|
||||
static sint32 fast_floor(float x)
|
||||
{
|
||||
return (x > 0) ? ((sint32)x) : (((sint32)x) - 1);
|
||||
return (x > 0) ? ((sint32) x) : (((sint32) x) - 1);
|
||||
}
|
||||
|
||||
static float grad(sint32 hash, float x, float y)
|
||||
@@ -756,7 +611,7 @@ static float grad(sint32 hash, float x, float y)
|
||||
return ((h & 1) != 0 ? -u : u) + ((h & 2) != 0 ? -2.0f * v : 2.0f * v);
|
||||
}
|
||||
|
||||
static void mapgen_simplex(mapgen_settings *settings)
|
||||
static void mapgen_simplex(mapgen_settings * settings)
|
||||
{
|
||||
sint32 x, y;
|
||||
|
||||
@@ -767,12 +622,14 @@ static void mapgen_simplex(mapgen_settings *settings)
|
||||
sint32 high = settings->simplex_high;
|
||||
|
||||
noise_rand();
|
||||
for (y = 0; y < _heightSize; y++) {
|
||||
for (x = 0; x < _heightSize; x++) {
|
||||
float noiseValue = clamp(-1.0f, fractal_noise(x, y, freq, octaves, 2.0f, 0.65f), 1.0f);
|
||||
for (y = 0; y < _heightSize; y++)
|
||||
{
|
||||
for (x = 0; x < _heightSize; x++)
|
||||
{
|
||||
float noiseValue = Math::Clamp(-1.0f, fractal_noise(x, y, freq, octaves, 2.0f, 0.65f), 1.0f);
|
||||
float normalisedNoiseValue = (noiseValue + 1.0f) / 2.0f;
|
||||
|
||||
set_height(x, y, low + (sint32)(normalisedNoiseValue * high));
|
||||
set_height(x, y, low + (sint32) (normalisedNoiseValue * high));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -781,15 +638,16 @@ static void mapgen_simplex(mapgen_settings *settings)
|
||||
|
||||
#pragma region Heightmap
|
||||
|
||||
bool mapgen_load_heightmap(const utf8 *path)
|
||||
bool mapgen_load_heightmap(const utf8 * path)
|
||||
{
|
||||
const char* extension = path_get_extension(path);
|
||||
uint8 *pixels;
|
||||
const char * extension = path_get_extension(path);
|
||||
uint8 * pixels;
|
||||
size_t pitch;
|
||||
uint32 numChannels;
|
||||
uint32 width, height;
|
||||
|
||||
if (strcicmp(extension, ".png") == 0) {
|
||||
if (String::Equals(extension, ".png", false))
|
||||
{
|
||||
sint32 bitDepth;
|
||||
if (!image_io_png_read(&pixels, &width, &height, true, path, &bitDepth))
|
||||
{
|
||||
@@ -801,8 +659,10 @@ bool mapgen_load_heightmap(const utf8 *path)
|
||||
numChannels = 4;
|
||||
pitch = width * numChannels;
|
||||
}
|
||||
else if (strcicmp(extension, ".bmp") == 0) {
|
||||
if (!context_read_bmp((void *)&pixels, &width, &height, path)) {
|
||||
else if (strcicmp(extension, ".bmp") == 0)
|
||||
{
|
||||
if (!context_read_bmp((void **) &pixels, &width, &height, path))
|
||||
{
|
||||
// ReadBMP contains context_show_error calls
|
||||
return false;
|
||||
}
|
||||
@@ -816,20 +676,22 @@ bool mapgen_load_heightmap(const utf8 *path)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (width != height) {
|
||||
if (width != height)
|
||||
{
|
||||
context_show_error(STR_HEIGHT_MAP_ERROR, STR_ERROR_WIDTH_AND_HEIGHT_DO_NOT_MATCH);
|
||||
free(pixels);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (width > MAXIMUM_MAP_SIZE_PRACTICAL) {
|
||||
if (width > MAXIMUM_MAP_SIZE_PRACTICAL)
|
||||
{
|
||||
context_show_error(STR_HEIGHT_MAP_ERROR, STR_ERROR_HEIHGT_MAP_TOO_BIG);
|
||||
width = height = min(height, MAXIMUM_MAP_SIZE_PRACTICAL);
|
||||
width = height = Math::Min(height, (uint32)MAXIMUM_MAP_SIZE_PRACTICAL);
|
||||
}
|
||||
|
||||
// Allocate memory for the height map values, one byte pixel
|
||||
free(_heightMapData.mono_bitmap);
|
||||
_heightMapData.mono_bitmap = (uint8*)malloc(width * height);
|
||||
delete[] _heightMapData.mono_bitmap;
|
||||
_heightMapData.mono_bitmap = new uint8[width * height];
|
||||
_heightMapData.width = width;
|
||||
_heightMapData.height = height;
|
||||
|
||||
@@ -854,8 +716,7 @@ bool mapgen_load_heightmap(const utf8 *path)
|
||||
*/
|
||||
void mapgen_unload_heightmap()
|
||||
{
|
||||
free(_heightMapData.mono_bitmap);
|
||||
_heightMapData.mono_bitmap = NULL;
|
||||
SafeDeleteArray(_heightMapData.mono_bitmap);
|
||||
_heightMapData.width = 0;
|
||||
_heightMapData.height = 0;
|
||||
}
|
||||
@@ -863,10 +724,10 @@ void mapgen_unload_heightmap()
|
||||
/**
|
||||
* Applies box blur to the surface N times
|
||||
*/
|
||||
static void mapgen_smooth_heightmap(uint8 *src, sint32 strength)
|
||||
static void mapgen_smooth_heightmap(uint8 * src, sint32 strength)
|
||||
{
|
||||
// Create buffer to store one channel
|
||||
uint8 *dest = (uint8*)malloc(_heightMapData.width * _heightMapData.height);
|
||||
uint8 * dest = new uint8[_heightMapData.width * _heightMapData.height];
|
||||
|
||||
for (sint32 i = 0; i < strength; i++)
|
||||
{
|
||||
@@ -884,8 +745,8 @@ static void mapgen_smooth_heightmap(uint8 *src, sint32 strength)
|
||||
{
|
||||
// Clamp x and y so they stay within the image
|
||||
// This assumes the height map is not tiled, and increases the weight of the edges
|
||||
const sint32 readX = clamp((sint32)x + offsetX, 0, (sint32)_heightMapData.width - 1);
|
||||
const sint32 readY = clamp((sint32)y + offsetY, 0, (sint32)_heightMapData.height - 1);
|
||||
const sint32 readX = Math::Clamp((sint32) x + offsetX, 0, (sint32) _heightMapData.width - 1);
|
||||
const sint32 readY = Math::Clamp((sint32) y + offsetY, 0, (sint32) _heightMapData.height - 1);
|
||||
heightSum += src[readX + readY * _heightMapData.width];
|
||||
}
|
||||
}
|
||||
@@ -905,17 +766,17 @@ static void mapgen_smooth_heightmap(uint8 *src, sint32 strength)
|
||||
}
|
||||
}
|
||||
|
||||
free(dest);
|
||||
delete[] dest;
|
||||
}
|
||||
|
||||
void mapgen_generate_from_heightmap(mapgen_settings *settings)
|
||||
void mapgen_generate_from_heightmap(mapgen_settings * settings)
|
||||
{
|
||||
openrct2_assert(_heightMapData.width == _heightMapData.height, "Invalid height map size");
|
||||
openrct2_assert(_heightMapData.mono_bitmap != NULL, "No height map loaded");
|
||||
openrct2_assert(_heightMapData.mono_bitmap != nullptr, "No height map loaded");
|
||||
openrct2_assert(settings->simplex_high != settings->simplex_low, "Low and high setting cannot be the same");
|
||||
|
||||
// Make a copy of the original height map that we can edit
|
||||
uint8 *dest = (uint8*)malloc(_heightMapData.width * _heightMapData.height);
|
||||
uint8 * dest = new uint8[_heightMapData.width * _heightMapData.height];
|
||||
memcpy(dest, _heightMapData.mono_bitmap, _heightMapData.width * _heightMapData.width);
|
||||
|
||||
map_init(_heightMapData.width + 2); // + 2 for the black tiles around the map
|
||||
@@ -938,15 +799,15 @@ void mapgen_generate_from_heightmap(mapgen_settings *settings)
|
||||
for (uint32 x = 0; x < _heightMapData.width; x++)
|
||||
{
|
||||
uint8 value = dest[x + y * _heightMapData.width];
|
||||
maxValue = max(maxValue, value);
|
||||
minValue = min(minValue, value);
|
||||
maxValue = Math::Max(maxValue, value);
|
||||
minValue = Math::Min(minValue, value);
|
||||
}
|
||||
}
|
||||
|
||||
if (minValue == maxValue)
|
||||
{
|
||||
context_show_error(STR_HEIGHT_MAP_ERROR, STR_ERROR_CANNOT_NORMALIZE);
|
||||
free(dest);
|
||||
delete[] dest;
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -962,11 +823,11 @@ void mapgen_generate_from_heightmap(mapgen_settings *settings)
|
||||
for (uint32 x = 0; x < _heightMapData.width; x++)
|
||||
{
|
||||
// The x and y axis are flipped in the world, so this uses y for x and x for y.
|
||||
rct_tile_element *const surfaceElement = map_get_surface_element_at(y + 1, x + 1);
|
||||
rct_tile_element * const surfaceElement = map_get_surface_element_at(y + 1, x + 1);
|
||||
|
||||
// Read value from bitmap, and convert its range
|
||||
uint8 value = dest[x + y * _heightMapData.width];
|
||||
value = (uint8)((float)(value - minValue) / rangeIn * rangeOut) + settings->simplex_low;
|
||||
value = (uint8) ((float) (value - minValue) / rangeIn * rangeOut) + settings->simplex_low;
|
||||
surfaceElement->base_height = value;
|
||||
|
||||
// Floor to even number
|
||||
@@ -1003,7 +864,7 @@ void mapgen_generate_from_heightmap(mapgen_settings *settings)
|
||||
}
|
||||
|
||||
// Clean up
|
||||
free(dest);
|
||||
delete[] dest;
|
||||
}
|
||||
|
||||
#pragma endregion
|
||||
@@ -14,12 +14,12 @@
|
||||
*****************************************************************************/
|
||||
#pragma endregion
|
||||
|
||||
#ifndef _MAPGEN_H_
|
||||
#define _MAPGEN_H_
|
||||
#pragma once
|
||||
|
||||
#include "../common.h"
|
||||
|
||||
typedef struct mapgen_settings {
|
||||
typedef struct mapgen_settings
|
||||
{
|
||||
// Base
|
||||
sint32 mapSize;
|
||||
sint32 height;
|
||||
@@ -47,15 +47,13 @@ typedef struct mapgen_settings {
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void mapgen_generate_blank(mapgen_settings *settings);
|
||||
void mapgen_generate(mapgen_settings *settings);
|
||||
void mapgen_generate_custom_simplex(mapgen_settings *settings);
|
||||
bool mapgen_load_heightmap(const utf8 *path);
|
||||
void mapgen_generate_blank(mapgen_settings * settings);
|
||||
void mapgen_generate(mapgen_settings * settings);
|
||||
void mapgen_generate_custom_simplex(mapgen_settings * settings);
|
||||
bool mapgen_load_heightmap(const utf8 * path);
|
||||
void mapgen_unload_heightmap();
|
||||
void mapgen_generate_from_heightmap(mapgen_settings *settings);
|
||||
void mapgen_generate_from_heightmap(mapgen_settings * settings);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user