Changes to API, fixes and performance improvments.

1) Layer functions now return an int and can terminate the generation.
2) This makes it possible to write much more accurate and faster biome finders.
3) The generator structure LayerStack is now stack allocatable and no longer requires a free.
4) Adjustments to make targets.
This commit is contained in:
Cubitect 2020-08-09 18:52:58 +02:00
parent 65de91ef26
commit 6097e42ea6
9 changed files with 1436 additions and 762 deletions

View File

@ -24,12 +24,16 @@ static DWORD WINAPI searchCompactBiomesThread(LPVOID data)
int64_t s;
int mcversion = MC_1_14;
LayerStack g = setupGenerator(mcversion);
LayerStack g;
setupGenerator(&g, mcversion);
int *cache = allocCache(&g.layers[L_VORONOI_ZOOM_1], w, h);
for (s = info.seedStart; s != info.seedEnd; s++)
{
if (checkForBiomes(&g, cache, s, ax, az, w, h, info.filter, info.minscale))
if (!hasAllTemps(&g, s, 0, 0))
continue;
if (checkForBiomes(&g, L_VORONOI_ZOOM_1, cache, s, ax, az, w, h, info.filter, 1) > 0)
{
int x, z;
if (info.withHut)
@ -70,7 +74,6 @@ static DWORD WINAPI searchCompactBiomesThread(LPVOID data)
}
}
freeGenerator(g);
free(cache);
#ifdef USE_PTHREAD

View File

@ -70,20 +70,15 @@ int main(int argc, char *argv[])
{
featureConfig = SWAMP_HUT_CONFIG;
seedFileName = "./seeds/quadhutbases_1_13_Q1.txt";
// setupGeneratorMC113() biome generation is slower and unnecessary.
// We are only interested in the biomes on land, which haven't changed
// since MC 1.7 except for some modified variants.
g = setupGenerator(MC_1_7);
// Use the 1.13 Hills layer to get the correct modified biomes.
g.layers[L_HILLS_64].getMap = mapHills113;
}
else
{
featureConfig = FEATURE_CONFIG;
seedFileName = "./seeds/quadhutbases_1_7_Q1.txt";
g = setupGenerator(MC_1_7);
}
setupGenerator(&g, mcversion);
//seedFileName = "./seeds/quadbases_Q1b.txt";
if (access(seedFileName, F_OK))
@ -208,7 +203,6 @@ int main(int argc, char *argv[])
}
free(biomeCache);
freeGenerator(g);
return 0;
}

1290
finders.c

File diff suppressed because it is too large Load Diff

View File

@ -94,33 +94,22 @@ STRUCT(Pos)
int x, z;
};
STRUCT(BiomeFilter)
{
// bitfield for required temperature categories, including special variants
uint64_t tempCat;
// bitfield for the required ocean types
uint64_t oceansToFind;
// bitfield of required biomes without modification bit
uint64_t biomesToFind;
// bitfield of required modified biomes
uint64_t modifiedToFind; // TODO: add checks for bamboo_jungle*
// bitfields for biomes required at their respecive layers
uint64_t tempsToFind; // Special (1:1024)
uint64_t otempToFind; // OceanTemp (1:256)
uint64_t majorToFind; // Biome (1:256)
uint64_t edgesToFind; // Edge (1:64) [mod64: as special case for bamboo]
// bitfields for biomes to find at RareBiome(1:64), Shore(1:16) and Mix(1:4)
// layers for (biomeID < 64) and modified (biomeID >= 128 && biomeID < 192)
uint64_t raresToFind, raresToFindM;
uint64_t shoreToFind, shoreToFindM;
uint64_t riverToFind, riverToFindM;
uint64_t oceanToFind; // all required ocean types
// check that there is a minimum of both special and normal temperatures
int tempNormal, tempSpecial;
// check for the temperatures specified by tempCnt (1:1024)
int doTempCheck;
// check for mushroom potential
int requireMushroom;
// combine a more detailed mushroom and temperature check (1:256)
int doShroomAndTempCheck;
// early check for 1.13 ocean types (1:256)
int doOceanTypeCheck;
//
int doMajorBiomeCheck;
// pre-generation biome checks in layer L_BIOME_256
int checkBiomePotential;
//
int doScale4Check;
int specialCnt; // number of special temperature categories required
};
#ifdef __cplusplus
@ -277,7 +266,7 @@ int isTreasureChunk(int64_t seed, const int chunkX, const int chunkZ);
/* Returns the biome for the specified block position.
* (Alternatives should be considered first in performance critical code.)
*/
int getBiomeAtPos(const LayerStack g, const Pos pos);
int getBiomeAtPos(const LayerStack *g, const Pos pos);
/* Finds a suitable pseudo-random location in the specified area.
* This function is used to determine the positions of spawn and strongholds.
@ -468,21 +457,35 @@ int64_t getHouseList(const int64_t worldSeed, const int chunkX, const int chunkZ
*/
BiomeFilter setupBiomeFilter(const int *biomeList, int listLen);
/* Tries to determine if the biomes configured in the filter will generate in
* this seed within the specified area. The smallest layer scale checked is
* given by 'minscale'. Lowering this value terminate the search earlier and
* yield more false positives.
/* Starts to generate the specified area and checks if all biomes in the filter
* are present. If so, the area will be fully generated inside the cache
* (if != NULL) up to the entry 'layerID', and the return value will be > 0.
* Otherwise, the contents of 'cache' is undefined and a value <= 0 is returned.
* More aggressive filtering can be enabled with 'protoCheck' which may yield
* some false negatives in exchange for speed.
*
* @g : generator (will be modified!)
* @layerID : layer enum of generation entry point
* @cache : working buffer, and output (if != NULL)
* @seed : world seed
* @x,z,w,h : requested area
* @filter : biomes to be checked for
* @protoCheck : enables more aggressive filtering when non-zero
*/
int64_t checkForBiomes(
LayerStack * g,
int * cache,
const int64_t seed,
const int blockX,
const int blockZ,
const unsigned int width,
const unsigned int height,
const BiomeFilter filter,
const int minscale);
int checkForBiomes(
LayerStack * g,
int layerID,
int * cache,
int64_t seed,
int x,
int z,
unsigned int w,
unsigned int h,
BiomeFilter filter,
int protoCheck
);
int hasAllTemps(LayerStack *g, int64_t seed, int x1024, int z1024);
#ifdef __cplusplus
}

View File

@ -7,8 +7,7 @@
void setupLayer(Layer *l, Layer *p, int s,
void (*getMap)(const Layer *, int *, int, int, int, int))
void setupLayer(Layer *l, Layer *p, int s, mapfunc_t getMap)
{
l->layerSeed = getLayerSeed(s);
l->startSalt = 0;
@ -16,27 +15,65 @@ void setupLayer(Layer *l, Layer *p, int s,
l->p = p;
l->p2 = NULL;
l->scale = 0;
l->edge = 0;
l->getMap = getMap;
l->oceanRnd = NULL;
l->data = NULL;
}
void setupMultiLayer(Layer *l, Layer *p1, Layer *p2, int s,
void (*getMap)(const Layer *, int *, int, int, int, int))
void setupMultiLayer(Layer *l, Layer *p1, Layer *p2, int s, mapfunc_t getMap)
{
setupLayer(l, p1, s, getMap);
l->p2 = p2;
}
static void setupScale(Layer *l, int scale)
{
l->scale = scale;
int m = 1;
if (l->getMap == mapZoom) {
int e = 0;
mapfunc_t map = l->getMap;
if (map == mapZoom)
{
m = 2;
} else if (l->getMap == mapVoronoiZoom) {
m = 4;
e = 2; // from ((w>>1)+1)<<1
}
else if (map == mapVoronoiZoom)
{
m = 4;
e = 8; // from ((w>>2)+2)<<2
}
else if (map == mapOceanMix)
{
e = 17;
}
else if (
map == mapAddIsland ||
map == mapRemoveTooMuchOcean ||
map == mapAddSnow ||
map == mapCoolWarm ||
map == mapHeatIce ||
map == mapAddMushroomIsland ||
map == mapDeepOcean ||
map == mapBiomeEdge ||
map == mapHills ||
map == mapHills113 ||
map == mapRiver ||
map == mapSmooth ||
map == mapShore
)
{
e = 2;
}
else
{
e = 0;
}
l->edge = e;
if (l->p) {
setupScale(l->p, scale * m);
}
@ -45,21 +82,19 @@ static void setupScale(Layer *l, int scale)
}
}
static LayerStack setupGeneratorImpl(const int mcversion, const int largeBiomes)
static void setupGeneratorImpl(LayerStack *g, int mcversion, int largeBiomes)
{
if (biomes[plains].id == 0)
{
fprintf(stderr, "Warning: The biomes have to be initialised first using initBiomes() before any generator can be used.\n");
}
LayerStack g;
g.layerCnt = L_NUM;
g.layers = (Layer *) calloc(g.layerCnt, sizeof(Layer));
Layer *l = g.layers;
memset(g, 0, sizeof(LayerStack));
Layer *l = g->layers;
// LAYER PARENT SALT LAYER_FUNCTION
setupLayer(&l[L_ISLAND_4096], NULL, 1, mapIsland);
setupLayer(&l[L_ZOOM_2048], &l[L_ISLAND_4096], 2000, mapZoom);
setupLayer(&l[L_ZOOM_2048], &l[L_ISLAND_4096], 2000, mapZoomIsland);
setupLayer(&l[L_ADD_ISLAND_2048], &l[L_ZOOM_2048], 1, mapAddIsland);
setupLayer(&l[L_ZOOM_1024], &l[L_ADD_ISLAND_2048], 2001, mapZoom);
setupLayer(&l[L_ADD_ISLAND_1024A], &l[L_ZOOM_1024], 2, mapAddIsland);
@ -130,50 +165,39 @@ static LayerStack setupGeneratorImpl(const int mcversion, const int largeBiomes)
if (mcversion <= MC_1_12)
{
setupLayer(&l[L_VORONOI_ZOOM_1], &l[L_RIVER_MIX_4], 10, mapVoronoiZoom);
setupLayer(&l[L_VORONOI_ZOOM_1], &l[L_RIVER_MIX_4], 10, mapVoronoiZoom);
g->entry_4 = &l[L_RIVER_MIX_4];
}
else
{
// ocean variants
setupLayer(&l[L13_OCEAN_TEMP_256], NULL, 2, mapOceanTemp);
l[L13_OCEAN_TEMP_256].oceanRnd = (OceanRnd *) malloc(sizeof(OceanRnd));
setupLayer(&l[L13_ZOOM_128], &l[L13_OCEAN_TEMP_256], 2001, mapZoom);
setupLayer(&l[L13_ZOOM_64], &l[L13_ZOOM_128], 2002, mapZoom);
setupLayer(&l[L13_ZOOM_32], &l[L13_ZOOM_64], 2003, mapZoom);
setupLayer(&l[L13_ZOOM_16], &l[L13_ZOOM_32], 2004, mapZoom);
setupLayer(&l[L13_ZOOM_8], &l[L13_ZOOM_16], 2005, mapZoom);
setupLayer(&l[L13_ZOOM_4], &l[L13_ZOOM_8], 2006, mapZoom);
setupLayer(&l[L13_OCEAN_TEMP_256], NULL, 2, mapOceanTemp);
l[L13_OCEAN_TEMP_256].oceanRnd = &g->oceanRnd;
setupLayer(&l[L13_ZOOM_128], &l[L13_OCEAN_TEMP_256], 2001, mapZoom);
setupLayer(&l[L13_ZOOM_64], &l[L13_ZOOM_128], 2002, mapZoom);
setupLayer(&l[L13_ZOOM_32], &l[L13_ZOOM_64], 2003, mapZoom);
setupLayer(&l[L13_ZOOM_16], &l[L13_ZOOM_32], 2004, mapZoom);
setupLayer(&l[L13_ZOOM_8], &l[L13_ZOOM_16], 2005, mapZoom);
setupLayer(&l[L13_ZOOM_4], &l[L13_ZOOM_8], 2006, mapZoom);
setupMultiLayer(&l[L13_OCEAN_MIX_4], &l[L_RIVER_MIX_4], &l[L13_ZOOM_4], 100, mapOceanMix);
setupLayer(&l[L_VORONOI_ZOOM_1], &l[L13_OCEAN_MIX_4], 10, mapVoronoiZoom);
setupLayer(&l[L_VORONOI_ZOOM_1], &l[L13_OCEAN_MIX_4], 10, mapVoronoiZoom);
g->entry_4 = &l[L13_OCEAN_MIX_4];
}
setupScale(&l[L_VORONOI_ZOOM_1], 1);
return g;
g->entry_1 = &l[L_VORONOI_ZOOM_1];
}
LayerStack setupGenerator(const int mcversion)
void setupGenerator(LayerStack *g, int mcversion)
{
return setupGeneratorImpl(mcversion, 0);
setupGeneratorImpl(g, mcversion, 0);
}
LayerStack setupLargeBiomesGenerator(const int mcversion)
void setupLargeBiomesGenerator(LayerStack *g, int mcversion)
{
return setupGeneratorImpl(mcversion, 1);
}
void freeGenerator(LayerStack g)
{
int i;
for(i = 0; i < g.layerCnt; i++)
{
if (g.layers[i].oceanRnd != NULL)
free(g.layers[i].oceanRnd);
}
free(g.layers);
setupGeneratorImpl(g, mcversion, 1);
}
@ -187,36 +211,18 @@ static void getMaxArea(const Layer *layer, int areaX, int areaZ, int *maxX, int
if (layer->getMap == mapZoom)
{
areaX = (areaX >> 1) + 2;
areaZ = (areaZ >> 1) + 2;
areaX >>= 1;
areaZ >>= 1;
}
else if (layer->getMap == mapVoronoiZoom)
{
areaX = (areaX >> 2) + 3;
areaZ = (areaZ >> 2) + 3;
}
else if (layer->getMap == mapOceanMix)
{
areaX += 17;
areaZ += 17;
}
else
{
if (layer->getMap != mapNull &&
layer->getMap != mapSkip &&
layer->getMap != mapIsland &&
layer->getMap != mapSpecial &&
layer->getMap != mapBiome &&
layer->getMap != mapRareBiome &&
layer->getMap != mapRiverInit &&
layer->getMap != mapRiverMix &&
layer->getMap != mapOceanTemp)
{
areaX += 2;
areaZ += 2;
}
areaX >>= 2;
areaZ >>= 2;
}
areaX += layer->edge;
areaZ += layer->edge;
if (areaX > *maxX) *maxX = areaX;
if (areaZ > *maxZ) *maxZ = areaZ;
@ -249,10 +255,10 @@ void applySeed(LayerStack *g, int64_t seed)
setWorldSeed(&g->layers[L_VORONOI_ZOOM_1], seed);
}
void genArea(const Layer *layer, int *out, int areaX, int areaZ, int areaWidth, int areaHeight)
int genArea(const Layer *layer, int *out, int areaX, int areaZ, int areaWidth, int areaHeight)
{
memset(out, 0, areaWidth*areaHeight*sizeof(*out));
layer->getMap(layer, out, areaX, areaZ, areaWidth, areaHeight);
return layer->getMap(layer, out, areaX, areaZ, areaWidth, areaHeight);
}

View File

@ -6,7 +6,7 @@
/* Minecraft versions */
enum MCversion
{
MC_1_7, MC_1_8, MC_1_9, MC_1_10, MC_1_11, MC_1_12, MC_1_13, MC_1_14,
MC_1_7, MC_1_8, MC_1_9, MC_1_10, MC_1_11, MC_1_12, MC_1_13, MC_1_14,
MC_1_15, MC_1_16,
MC_BE = 128
};
@ -80,6 +80,58 @@ enum
};
STRUCT(LayerStack)
{
Layer layers[L_NUM];
Layer *entry_1; // entry layer, scale (1:1) [L_VORONOI_ZOOM_1]
Layer *entry_4; // entry layer, scale (1:4) [L_RIVER_MIX_4|L13_OCEAN_MIX_4]
OceanRnd oceanRnd;
};
typedef int (*mapfunc_t)(const Layer *, int *, int, int, int, int);
#ifdef __cplusplus
extern "C"
{
#endif
/* Initialise an instance of a generator. */
void setupGenerator(LayerStack *g, int mcversion);
/* Initialise an instance of a generator with largeBiomes configuration. */
void setupLargeBiomesGenerator(LayerStack *g, int mcversion);
/* Calculates the minimum size of the buffers required to generate an area of
* dimensions 'sizeX' by 'sizeZ' at the specified layer.
*/
int calcRequiredBuf(const Layer *layer, int areaX, int areaZ);
/* Allocates an amount of memory required to generate an area of dimensions
* 'sizeX' by 'sizeZ' for the magnification of the given layer.
*/
int *allocCache(const Layer *layer, int sizeX, int sizeZ);
/* Set up custom layers. */
void setupLayer(Layer *l, Layer *p, int s, mapfunc_t getMap);
void setupMultiLayer(Layer *l, Layer *p1, Layer *p2, int s, mapfunc_t getMap);
/* Sets the world seed for the generator */
void applySeed(LayerStack *g, int64_t seed);
/* Generates the specified area using the current generator settings and stores
* the biomeIDs in 'out'.
* The biomeIDs will be indexed in the form: out[x + z*areaWidth]
* It is recommended that 'out' is allocated using allocCache() for the correct
* buffer size.
*/
int genArea(const Layer *layer, int *out, int areaX, int areaZ, int areaWidth, int areaHeight);
/******************************** BIOME TABLES *********************************
* The biome tables below are lists of the biomes that can be present at some
* notable layers. Of cause, layers that are applied later in the hierarchy will
@ -187,53 +239,6 @@ static const int BIOMES_L_RIVER_MIX_4[] =
};
STRUCT(LayerStack)
{
Layer *layers;
int layerCnt;
};
#ifdef __cplusplus
extern "C"
{
#endif
/* Initialise an instance of a generator. */
LayerStack setupGenerator(const int mcversion);
/* Initialise an instance of a generator with largeBiomes configuration. */
LayerStack setupLargeBiomesGenerator(const int mcversion);
/* Cleans up and frees the generator layers */
void freeGenerator(LayerStack g);
/* Calculates the minimum size of the buffers required to generate an area of
* dimensions 'sizeX' by 'sizeZ' at the specified layer.
*/
int calcRequiredBuf(const Layer *layer, int areaX, int areaZ);
/* Allocates an amount of memory required to generate an area of dimensions
* 'sizeX' by 'sizeZ' for the magnification of the current top layer.
*/
int *allocCache(const Layer *layer, int sizeX, int sizeZ);
/* Set up custom layers. */
void setupLayer(Layer *l, Layer *p, int s, void (*getMap)(const Layer *, int *, int, int, int, int));
void setupMultiLayer(Layer *l, Layer *p1, Layer *p2, int s, void (*getMap)(const Layer *, int *, int, int, int, int));
/* Sets the world seed for the generator */
void applySeed(LayerStack *g, int64_t seed);
/* Generates the specified area using the current generator settings and stores
* the biomeIDs in 'out'.
* The biomeIDs will be indexed in the form: out[x + z*areaWidth]
* It is recommended that 'out' is allocated using allocCache() for the correct
* buffer size.
*/
void genArea(const Layer *layer, int *out, int areaX, int areaZ, int areaWidth, int areaHeight);
#ifdef __cplusplus
}

458
layers.c
View File

@ -3,13 +3,6 @@
#include <string.h>
#include <stdio.h>
#if __GNUC__
#define PREFETCH(PTR) __builtin_prefetch(PTR)
#define EXPECT(COND,VAL) __builtin_expect(COND,VAL)
#else
#define PREFETCH(PTR)
#define EXPECT(COND,VAL) (COND)
#endif
static void oceanRndInit(OceanRnd *rnd, int64_t seed);
@ -24,7 +17,7 @@ void initAddBiome(int id, int tempCat, int biometype, float temp, float height)
biomes[id].tempCat = tempCat;
}
void createMutation(int id)
static void createMutation(int id)
{
biomes[id].mutated = id + 128;
biomes[id+128] = biomes[id];
@ -157,22 +150,7 @@ void setWorldSeed(Layer *layer, int64_t worldSeed)
}
void mapNull(const Layer * l, int * out, int x, int z, int w, int h)
{
}
void mapSkip(const Layer * l, int * out, int x, int z, int w, int h)
{
if (l->p == NULL)
{
printf("mapSkip() requires a non-null parent layer.\n");
exit(1);
}
l->p->getMap(l->p, out, x, z, w, h);
}
void mapIsland(const Layer * l, int * out, int x, int z, int w, int h)
int mapIsland(const Layer * l, int * out, int x, int z, int w, int h)
{
int64_t ss = l->startSeed;
int64_t cs;
@ -191,12 +169,11 @@ void mapIsland(const Layer * l, int * out, int x, int z, int w, int h)
{
out[-x + -z * w] = 1;
}
return 0;
}
/// This is the most common layer, and generally the second most performance
/// critical after mapAddIsland.
void mapZoom(const Layer * l, int * out, int x, int z, int w, int h)
int mapZoomIsland(const Layer * l, int * out, int x, int z, int w, int h)
{
int pX = x >> 1;
int pZ = z >> 1;
@ -204,18 +181,18 @@ void mapZoom(const Layer * l, int * out, int x, int z, int w, int h)
int pH = ((z + h) >> 1) - pZ + 1;
int i, j;
l->p->getMap(l->p, out, pX, pZ, pW, pH);
int err = l->p->getMap(l->p, out, pX, pZ, pW, pH);
if (EXPECT(err, 0))
return err;
int newW = (pW) << 1;
int newH = (pH) << 1;
int idx, v00, v01;
int idx, v00, v01, v10, v11;
int *buf = (int*) malloc((newW+1)*(newH+1)*sizeof(*buf));
const int st = (int)l->startSalt;
const int ss = (int)l->startSeed;
int isHighestZoom = l->p->getMap == mapIsland;
for (j = 0; j < pH; j++)
{
idx = (j << 1) * newW;
@ -223,10 +200,20 @@ void mapZoom(const Layer * l, int * out, int x, int z, int w, int h)
v00 = out[(j+0)*pW];
v01 = out[(j+1)*pW];
for (i = 0; i < pW; i++)
for (i = 0; i < pW; i++, v00 = v10, v01 = v11)
{
int v10 = out[i+1 + (j+0)*pW];
int v11 = out[i+1 + (j+1)*pW];
v10 = out[i+1 + (j+0)*pW];
v11 = out[i+1 + (j+1)*pW];
if (v00 == v01 && v00 == v10 && v00 == v11)
{
buf[idx] = v00;
buf[idx + 1] = v00;
buf[idx + newW] = v00;
buf[idx + newW + 1] = v00;
idx += 2;
continue;
}
int chunkX = (i + pX) << 1;
int chunkZ = (j + pZ) << 1;
@ -248,42 +235,11 @@ void mapZoom(const Layer * l, int * out, int x, int z, int w, int h)
cs += st;
buf[idx] = (cs >> 24) & 1 ? v10 : v00;
if (isHighestZoom)
{
//selectRandom4
cs *= cs * 1284865837 + 4150755663;
cs += st;
int r = (cs >> 24) & 3;
buf[idx + newW] = r==0 ? v00 : r==1 ? v10 : r==2 ? v01 : v11;
}
else
{
//selectModeOrRandom
int v;
if (v10 == v01 && v01 == v11) v = v10;
else if (v00 == v10 && v00 == v01) v = v00;
else if (v00 == v10 && v00 == v11) v = v00;
else if (v00 == v01 && v00 == v11) v = v00;
else if (v00 == v10 && v01 != v11) v = v00;
else if (v00 == v01 && v10 != v11) v = v00;
else if (v00 == v11 && v10 != v01) v = v00;
else if (v10 == v01 && v00 != v11) v = v10;
else if (v10 == v11 && v00 != v01) v = v10;
else if (v01 == v11 && v00 != v10) v = v01;
else
{
cs *= cs * 1284865837 + 4150755663;
cs += st;
int r = (cs >> 24) & 3;
v = r==0 ? v00 : r==1 ? v10 : r==2 ? v01 : v11;
}
buf[idx + newW] = v;
}
cs *= cs * 1284865837 + 4150755663;
cs += st;
int r = (cs >> 24) & 3;
buf[idx + newW] = r==0 ? v00 : r==1 ? v10 : r==2 ? v01 : v11;
idx++;
v00 = v10;
v01 = v11;
}
}
@ -293,10 +249,110 @@ void mapZoom(const Layer * l, int * out, int x, int z, int w, int h)
}
free(buf);
return 0;
}
/// This is the most common layer, and generally the second most performance
/// critical after mapAddIsland.
int mapZoom(const Layer * l, int * out, int x, int z, int w, int h)
{
int pX = x >> 1;
int pZ = z >> 1;
int pW = ((x + w) >> 1) - pX + 1;
int pH = ((z + h) >> 1) - pZ + 1;
int i, j;
int err = l->p->getMap(l->p, out, pX, pZ, pW, pH);
if (EXPECT(err, 0))
return err;
int newW = (pW) << 1;
int newH = (pH) << 1;
int idx, v00, v01, v10, v11;
int *buf = (int*) malloc((newW+1)*(newH+1)*sizeof(*buf));
const int st = (int)l->startSalt;
const int ss = (int)l->startSeed;
for (j = 0; j < pH; j++)
{
idx = (j << 1) * newW;
v00 = out[(j+0)*pW];
v01 = out[(j+1)*pW];
for (i = 0; i < pW; i++, v00 = v10, v01 = v11)
{
v10 = out[i+1 + (j+0)*pW];
v11 = out[i+1 + (j+1)*pW];
if (v00 == v01 && v00 == v10 && v00 == v11)
{
buf[idx] = v00;
buf[idx + 1] = v00;
buf[idx + newW] = v00;
buf[idx + newW + 1] = v00;
idx += 2;
continue;
}
int chunkX = (i + pX) << 1;
int chunkZ = (j + pZ) << 1;
int cs = ss;
cs += chunkX;
cs *= cs * 1284865837 + 4150755663;
cs += chunkZ;
cs *= cs * 1284865837 + 4150755663;
cs += chunkX;
cs *= cs * 1284865837 + 4150755663;
cs += chunkZ;
buf[idx] = v00;
buf[idx + newW] = (cs >> 24) & 1 ? v01 : v00;
idx++;
cs *= cs * 1284865837 + 4150755663;
cs += st;
buf[idx] = (cs >> 24) & 1 ? v10 : v00;
int v;
if (v10 == v01 && v01 == v11) v = v10;
else if (v00 == v10 && v00 == v01) v = v00;
else if (v00 == v10 && v00 == v11) v = v00;
else if (v00 == v01 && v00 == v11) v = v00;
else if (v00 == v10 && v01 != v11) v = v00;
else if (v00 == v01 && v10 != v11) v = v00;
else if (v00 == v11 && v10 != v01) v = v00;
else if (v10 == v01 && v00 != v11) v = v10;
else if (v10 == v11 && v00 != v01) v = v10;
else if (v01 == v11 && v00 != v10) v = v01;
else
{
cs *= cs * 1284865837 + 4150755663;
cs += st;
int r = (cs >> 24) & 3;
v = r==0 ? v00 : r==1 ? v10 : r==2 ? v01 : v11;
}
buf[idx + newW] = v;
idx++;
}
}
for (j = 0; j < h; j++)
{
memcpy(&out[j*w], &buf[(j + (z & 1))*newW + (x & 1)], w*sizeof(int));
}
free(buf);
return 0;
}
/// This is the most performance crittical layer, especially for getBiomeAtPos.
void mapAddIsland(const Layer * l, int * out, int x, int z, int w, int h)
int mapAddIsland(const Layer * l, int * out, int x, int z, int w, int h)
{
int pX = x - 1;
int pZ = z - 1;
@ -304,7 +360,9 @@ void mapAddIsland(const Layer * l, int * out, int x, int z, int w, int h)
int pH = h + 2;
int i, j;
l->p->getMap(l->p, out, pX, pZ, pW, pH);
int err = l->p->getMap(l->p, out, pX, pZ, pW, pH);
if (EXPECT(err, 0))
return err;
int64_t st = l->startSalt;
int64_t ss = l->startSeed;
@ -402,10 +460,12 @@ void mapAddIsland(const Layer * l, int * out, int x, int z, int w, int h)
v02 = vt2; vt2 = v22;
}
}
return 0;
}
void mapRemoveTooMuchOcean(const Layer * l, int * out, int x, int z, int w, int h)
int mapRemoveTooMuchOcean(const Layer * l, int * out, int x, int z, int w, int h)
{
int pX = x - 1;
int pZ = z - 1;
@ -413,7 +473,9 @@ void mapRemoveTooMuchOcean(const Layer * l, int * out, int x, int z, int w, int
int pH = h + 2;
int i, j;
l->p->getMap(l->p, out, pX, pZ, pW, pH);
int err = l->p->getMap(l->p, out, pX, pZ, pW, pH);
if (EXPECT(err, 0))
return err;
int64_t ss = l->startSeed;
int64_t cs;
@ -440,10 +502,12 @@ void mapRemoveTooMuchOcean(const Layer * l, int * out, int x, int z, int w, int
}
}
}
return 0;
}
void mapAddSnow(const Layer * l, int * out, int x, int z, int w, int h)
int mapAddSnow(const Layer * l, int * out, int x, int z, int w, int h)
{
int pX = x - 1;
int pZ = z - 1;
@ -451,8 +515,10 @@ void mapAddSnow(const Layer * l, int * out, int x, int z, int w, int h)
int pH = h + 2;
int i, j;
l->p->getMap(l->p, out, pX, pZ, pW, pH);
int err = l->p->getMap(l->p, out, pX, pZ, pW, pH);
if (EXPECT(err, 0))
return err;
int64_t ss = l->startSeed;
int64_t cs;
@ -480,10 +546,12 @@ void mapAddSnow(const Layer * l, int * out, int x, int z, int w, int h)
}
}
}
return 0;
}
void mapCoolWarm(const Layer * l, int * out, int x, int z, int w, int h)
int mapCoolWarm(const Layer * l, int * out, int x, int z, int w, int h)
{
int pX = x - 1;
int pZ = z - 1;
@ -491,7 +559,9 @@ void mapCoolWarm(const Layer * l, int * out, int x, int z, int w, int h)
int pH = h + 2;
int i, j;
l->p->getMap(l->p, out, pX, pZ, pW, pH);
int err = l->p->getMap(l->p, out, pX, pZ, pW, pH);
if (EXPECT(err, 0))
return err;
for (j = 0; j < h; j++)
{
@ -515,10 +585,12 @@ void mapCoolWarm(const Layer * l, int * out, int x, int z, int w, int h)
out[i + j*w] = v11;
}
}
return 0;
}
void mapHeatIce(const Layer * l, int * out, int x, int z, int w, int h)
int mapHeatIce(const Layer * l, int * out, int x, int z, int w, int h)
{
int pX = x - 1;
int pZ = z - 1;
@ -526,7 +598,9 @@ void mapHeatIce(const Layer * l, int * out, int x, int z, int w, int h)
int pH = h + 2;
int i, j;
l->p->getMap(l->p, out, pX, pZ, pW, pH);
int err = l->p->getMap(l->p, out, pX, pZ, pW, pH);
if (EXPECT(err, 0))
return err;
for (j = 0; j < h; j++)
{
@ -550,12 +624,16 @@ void mapHeatIce(const Layer * l, int * out, int x, int z, int w, int h)
out[i + j*w] = v11;
}
}
return 0;
}
void mapSpecial(const Layer * l, int * out, int x, int z, int w, int h)
int mapSpecial(const Layer * l, int * out, int x, int z, int w, int h)
{
l->p->getMap(l->p, out, x, z, w, h);
int err = l->p->getMap(l->p, out, x, z, w, h);
if (EXPECT(err, 0))
return err;
int64_t st = l->startSalt;
int64_t ss = l->startSeed;
@ -580,10 +658,12 @@ void mapSpecial(const Layer * l, int * out, int x, int z, int w, int h)
}
}
}
return 0;
}
void mapAddMushroomIsland(const Layer * l, int * out, int x, int z, int w, int h)
int mapAddMushroomIsland(const Layer * l, int * out, int x, int z, int w, int h)
{
int pX = x - 1;
int pZ = z - 1;
@ -591,7 +671,9 @@ void mapAddMushroomIsland(const Layer * l, int * out, int x, int z, int w, int h
int pH = h + 2;
int i, j;
l->p->getMap(l->p, out, pX, pZ, pW, pH);
int err = l->p->getMap(l->p, out, pX, pZ, pW, pH);
if (EXPECT(err, 0))
return err;
int64_t ss = l->startSeed;
int64_t cs;
@ -615,10 +697,12 @@ void mapAddMushroomIsland(const Layer * l, int * out, int x, int z, int w, int h
out[i + j*w] = v11;
}
}
return 0;
}
void mapDeepOcean(const Layer * l, int * out, int x, int z, int w, int h)
int mapDeepOcean(const Layer * l, int * out, int x, int z, int w, int h)
{
int pX = x - 1;
int pZ = z - 1;
@ -626,7 +710,9 @@ void mapDeepOcean(const Layer * l, int * out, int x, int z, int w, int h)
int pH = h + 2;
int i, j;
l->p->getMap(l->p, out, pX, pZ, pW, pH);
int err = l->p->getMap(l->p, out, pX, pZ, pW, pH);
if (EXPECT(err, 0))
return err;
for (j = 0; j < h; j++)
{
@ -671,6 +757,8 @@ void mapDeepOcean(const Layer * l, int * out, int x, int z, int w, int h)
out[i + j*w] = v11;
}
}
return 0;
}
@ -679,9 +767,11 @@ const int lushBiomes[] = {forest, dark_forest, mountains, plains, birch_forest,
const int coldBiomes[] = {forest, mountains, taiga, plains};
const int snowBiomes[] = {snowy_tundra, snowy_tundra, snowy_tundra, snowy_taiga};
void mapBiome(const Layer * l, int * out, int x, int z, int w, int h)
int mapBiome(const Layer * l, int * out, int x, int z, int w, int h)
{
l->p->getMap(l->p, out, x, z, w, h);
int err = l->p->getMap(l->p, out, x, z, w, h);
if (EXPECT(err, 0))
return err;
int64_t ss = l->startSeed;
int64_t cs;
@ -693,8 +783,8 @@ void mapBiome(const Layer * l, int * out, int x, int z, int w, int h)
{
int idx = i + j*w;
int id = out[idx];
int hasHighBit = (id & 0xf00) >> 8;
id &= -0xf01;
int hasHighBit = (id & 0xf00);
id &= ~0xf00;
if (getBiomeType(id) == Ocean || id == mushroom_fields)
{
@ -704,7 +794,8 @@ void mapBiome(const Layer * l, int * out, int x, int z, int w, int h)
cs = getChunkSeed(ss, i + x, j + z);
switch(id){
switch (id)
{
case Warm:
if (hasHighBit) out[idx] = mcFirstIsZero(cs, 3) ? badlands_plateau : wooded_badlands_plateau;
else out[idx] = warmBiomes[mcFirstInt(cs, 6)];
@ -725,14 +816,18 @@ void mapBiome(const Layer * l, int * out, int x, int z, int w, int h)
}
}
}
return 0;
}
const int lushBiomesBE[] = {forest, dark_forest, mountains, plains, plains, plains, birch_forest, swamp};
void mapBiomeBE(const Layer * l, int * out, int x, int z, int w, int h)
int mapBiomeBE(const Layer * l, int * out, int x, int z, int w, int h)
{
l->p->getMap(l->p, out, x, z, w, h);
int err = l->p->getMap(l->p, out, x, z, w, h);
if (EXPECT(err, 0))
return err;
int64_t ss = l->startSeed;
int64_t cs;
@ -744,8 +839,8 @@ void mapBiomeBE(const Layer * l, int * out, int x, int z, int w, int h)
{
int idx = i + j*w;
int id = out[idx];
int hasHighBit = (id & 0xf00) >> 8;
id &= -0xf01;
int hasHighBit = (id & 0xf00);
id &= ~0xf00;
if (getBiomeType(id) == Ocean || id == mushroom_fields)
{
@ -755,7 +850,8 @@ void mapBiomeBE(const Layer * l, int * out, int x, int z, int w, int h)
cs = getChunkSeed(ss, i + x, j + z);
switch(id){
switch (id)
{
case Warm:
if (hasHighBit) out[idx] = mcFirstIsZero(cs, 3) ? badlands_plateau : wooded_badlands_plateau;
else out[idx] = warmBiomes[mcFirstInt(cs, 6)];
@ -776,12 +872,16 @@ void mapBiomeBE(const Layer * l, int * out, int x, int z, int w, int h)
}
}
}
return 0;
}
void mapRiverInit(const Layer * l, int * out, int x, int z, int w, int h)
int mapRiverInit(const Layer * l, int * out, int x, int z, int w, int h)
{
l->p->getMap(l->p, out, x, z, w, h);
int err = l->p->getMap(l->p, out, x, z, w, h);
if (EXPECT(err, 0))
return err;
int64_t ss = l->startSeed;
int64_t cs;
@ -802,12 +902,16 @@ void mapRiverInit(const Layer * l, int * out, int x, int z, int w, int h)
}
}
}
return 0;
}
void mapAddBamboo(const Layer * l, int * out, int x, int z, int w, int h)
int mapAddBamboo(const Layer * l, int * out, int x, int z, int w, int h)
{
l->p->getMap(l->p, out, x, z, w, h);
int err = l->p->getMap(l->p, out, x, z, w, h);
if (EXPECT(err, 0))
return err;
int64_t ss = l->startSeed;
int64_t cs;
@ -827,6 +931,8 @@ void mapAddBamboo(const Layer * l, int * out, int x, int z, int w, int h)
}
}
}
return 0;
}
@ -844,7 +950,7 @@ static inline int replaceEdge(int *out, int idx, int v10, int v21, int v01, int
return 1;
}
void mapBiomeEdge(const Layer * l, int * out, int x, int z, int w, int h)
int mapBiomeEdge(const Layer * l, int * out, int x, int z, int w, int h)
{
int pX = x - 1;
int pZ = z - 1;
@ -852,7 +958,9 @@ void mapBiomeEdge(const Layer * l, int * out, int x, int z, int w, int h)
int pH = h + 2;
int i, j;
l->p->getMap(l->p, out, pX, pZ, pW, pH);
int err = l->p->getMap(l->p, out, pX, pZ, pW, pH);
if (EXPECT(err, 0))
return err;
for (j = 0; j < h; j++)
{
@ -894,7 +1002,7 @@ void mapBiomeEdge(const Layer * l, int * out, int x, int z, int w, int h)
v21 != bamboo_jungle && v01 != bamboo_jungle)
out[i + j*w] = v11;
else
out[i + j*w] = jungleEdge;
out[i + j*w] = jungle_edge;
}
else
{
@ -908,10 +1016,12 @@ void mapBiomeEdge(const Layer * l, int * out, int x, int z, int w, int h)
}
}
}
return 0;
}
void mapHills(const Layer * l, int * out, int x, int z, int w, int h)
int mapHills(const Layer * l, int * out, int x, int z, int w, int h)
{
int pX = x - 1;
int pZ = z - 1;
@ -926,12 +1036,19 @@ void mapHills(const Layer * l, int * out, int x, int z, int w, int h)
exit(1);
}
buf = (int *) malloc(pW*pH*sizeof(int));
int err = l->p->getMap(l->p, out, pX, pZ, pW, pH);
if (EXPECT(err, 0))
return err;
l->p->getMap(l->p, out, pX, pZ, pW, pH);
buf = (int *) malloc(pW*pH*sizeof(int));
memcpy(buf, out, pW*pH*sizeof(int));
l->p2->getMap(l->p2, out, pX, pZ, pW, pH);
err = l->p2->getMap(l->p2, out, pX, pZ, pW, pH);
if (EXPECT(err, 0))
{
free(buf);
return err;
}
int64_t st = l->startSalt;
int64_t ss = l->startSeed;
@ -1035,10 +1152,11 @@ void mapHills(const Layer * l, int * out, int x, int z, int w, int h)
}
free(buf);
return 0;
}
void mapHills113(const Layer * l, int * out, int x, int z, int w, int h)
int mapHills113(const Layer * l, int * out, int x, int z, int w, int h)
{
int pX = x - 1;
int pZ = z - 1;
@ -1053,12 +1171,19 @@ void mapHills113(const Layer * l, int * out, int x, int z, int w, int h)
exit(1);
}
buf = (int *) malloc(pW*pH*sizeof(int));
int err = l->p->getMap(l->p, out, pX, pZ, pW, pH);
if (EXPECT(err, 0))
return err;
l->p->getMap(l->p, out, pX, pZ, pW, pH);
buf = (int *) malloc(pW*pH*sizeof(int));
memcpy(buf, out, pW*pH*sizeof(int));
l->p2->getMap(l->p2, out, pX, pZ, pW, pH);
err = l->p2->getMap(l->p2, out, pX, pZ, pW, pH);
if (EXPECT(err, 0))
{
free(buf);
return err;
}
int64_t st = l->startSalt;
int64_t ss = l->startSeed;
@ -1174,6 +1299,7 @@ void mapHills113(const Layer * l, int * out, int x, int z, int w, int h)
}
free(buf);
return 0;
}
@ -1183,7 +1309,7 @@ static inline int reduceID(int id)
return id >= 2 ? 2 + (id & 1) : id;
}
void mapRiver(const Layer * l, int * out, int x, int z, int w, int h)
int mapRiver(const Layer * l, int * out, int x, int z, int w, int h)
{
int pX = x - 1;
int pZ = z - 1;
@ -1191,7 +1317,9 @@ void mapRiver(const Layer * l, int * out, int x, int z, int w, int h)
int pH = h + 2;
int i, j;
l->p->getMap(l->p, out, pX, pZ, pW, pH);
int err = l->p->getMap(l->p, out, pX, pZ, pW, pH);
if (EXPECT(err, 0))
return err;
for (j = 0; j < h; j++)
{
@ -1217,10 +1345,12 @@ void mapRiver(const Layer * l, int * out, int x, int z, int w, int h)
}
}
}
return 0;
}
void mapSmooth(const Layer * l, int * out, int x, int z, int w, int h)
int mapSmooth(const Layer * l, int * out, int x, int z, int w, int h)
{
int pX = x - 1;
int pZ = z - 1;
@ -1228,7 +1358,9 @@ void mapSmooth(const Layer * l, int * out, int x, int z, int w, int h)
int pH = h + 2;
int i, j;
l->p->getMap(l->p, out, pX, pZ, pW, pH);
int err = l->p->getMap(l->p, out, pX, pZ, pW, pH);
if (EXPECT(err, 0))
return err;
int64_t ss = l->startSeed;
int64_t cs;
@ -1267,14 +1399,18 @@ void mapSmooth(const Layer * l, int * out, int x, int z, int w, int h)
out[i + j * w] = v11;
}
}
return 0;
}
void mapRareBiome(const Layer * l, int * out, int x, int z, int w, int h)
int mapRareBiome(const Layer * l, int * out, int x, int z, int w, int h)
{
int i, j;
l->p->getMap(l->p, out, x, z, w, h);
int err = l->p->getMap(l->p, out, x, z, w, h);
if (EXPECT(err, 0))
return err;
int64_t ss = l->startSeed;
int64_t cs;
@ -1296,6 +1432,8 @@ void mapRareBiome(const Layer * l, int * out, int x, int z, int w, int h)
}
}
}
return 0;
}
@ -1316,7 +1454,7 @@ inline static int isBiomeJFTO(int id)
return biomeExists(id) && (getBiomeType(id) == Jungle || id == forest || id == taiga || isOceanic(id));
}
void mapShore(const Layer * l, int * out, int x, int z, int w, int h)
int mapShore(const Layer * l, int * out, int x, int z, int w, int h)
{
int pX = x - 1;
int pZ = z - 1;
@ -1324,7 +1462,9 @@ void mapShore(const Layer * l, int * out, int x, int z, int w, int h)
int pH = h + 2;
int i, j;
l->p->getMap(l->p, out, pX, pZ, pW, pH);
int err = l->p->getMap(l->p, out, pX, pZ, pW, pH);
if (EXPECT(err, 0))
return err;
for (j = 0; j < h; j++)
{
@ -1360,7 +1500,7 @@ void mapShore(const Layer * l, int * out, int x, int z, int w, int h)
}
else
{
out[i + j*w] = jungleEdge;
out[i + j*w] = jungle_edge;
}
}
else if (v11 != mountains && v11 != wooded_mountains && v11 != mountain_edge)
@ -1404,10 +1544,12 @@ void mapShore(const Layer * l, int * out, int x, int z, int w, int h)
}
}
}
return 0;
}
void mapRiverMix(const Layer * l, int * out, int x, int z, int w, int h)
int mapRiverMix(const Layer * l, int * out, int x, int z, int w, int h)
{
int idx;
int len;
@ -1419,13 +1561,21 @@ void mapRiverMix(const Layer * l, int * out, int x, int z, int w, int h)
exit(1);
}
int err = l->p->getMap(l->p, out, x, z, w, h); // biome chain
if (EXPECT(err, 0))
return err;
len = w*h;
buf = (int *) malloc(len*sizeof(int));
l->p->getMap(l->p, out, x, z, w, h); // biome chain
memcpy(buf, out, len*sizeof(int));
l->p2->getMap(l->p2, out, x, z, w, h); // rivers
err = l->p2->getMap(l->p2, out, x, z, w, h); // rivers
if (EXPECT(err, 0))
{
free(buf);
return err;
}
for (idx = 0; idx < len; idx++)
{
@ -1452,6 +1602,7 @@ void mapRiverMix(const Layer * l, int * out, int x, int z, int w, int h)
}
free(buf);
return 0;
}
@ -1545,7 +1696,7 @@ static double getOceanTemp(const OceanRnd *rnd, double d1, double d2, double d3)
return lerp(t3, l1, l5);
}
void mapOceanTemp(const Layer * l, int * out, int x, int z, int w, int h)
int mapOceanTemp(const Layer * l, int * out, int x, int z, int w, int h)
{
int i, j;
OceanRnd *rnd = l->oceanRnd;
@ -1568,10 +1719,12 @@ void mapOceanTemp(const Layer * l, int * out, int x, int z, int w, int h)
out[i + j*w] = ocean;
}
}
return 0;
}
void mapOceanMix(const Layer * l, int * out, int x, int z, int w, int h)
int mapOceanMix(const Layer * l, int * out, int x, int z, int w, int h)
{
int *land, *otyp;
int i, j;
@ -1583,7 +1736,9 @@ void mapOceanMix(const Layer * l, int * out, int x, int z, int w, int h)
exit(1);
}
l->p2->getMap(l->p2, out, x, z, w, h);
int err = l->p2->getMap(l->p2, out, x, z, w, h);
if (EXPECT(err, 0))
return err;
otyp = (int *) malloc(w*h*sizeof(int));
memcpy(otyp, out, w*h*sizeof(int));
@ -1612,7 +1767,12 @@ void mapOceanMix(const Layer * l, int * out, int x, int z, int w, int h)
lw = lx1 - lx0;
lh = lz1 - lz0;
l->p->getMap(l->p, out, x+lx0, z+lz0, lw, lh);
err = l->p->getMap(l->p, out, x+lx0, z+lz0, lw, lh);
if (EXPECT(err, 0))
{
free(otyp);
return err;
}
land = (int *) malloc(lw*lh*sizeof(int));
memcpy(land, out, lw*lh*sizeof(int));
@ -1680,10 +1840,12 @@ void mapOceanMix(const Layer * l, int * out, int x, int z, int w, int h)
free(land);
free(otyp);
return 0;
}
void mapVoronoiZoom(const Layer * l, int * out, int x, int z, int w, int h)
int mapVoronoiZoom(const Layer * l, int * out, int x, int z, int w, int h)
{
x -= 2;
z -= 2;
@ -1691,13 +1853,16 @@ void mapVoronoiZoom(const Layer * l, int * out, int x, int z, int w, int h)
int pZ = z >> 2;
int pW = ((x + w) >> 2) - pX + 2;
int pH = ((z + h) >> 2) - pZ + 2;
int err = l->p->getMap(l->p, out, pX, pZ, pW, pH);
if (EXPECT(err, 0))
return err;
int newW = pW << 2;
int newH = pH << 2;
int i, j;
int *buf = (int *) malloc((newW+1)*(newH+1)*sizeof(*buf));
l->p->getMap(l->p, out, pX, pZ, pW, pH);
int64_t st = l->startSalt;
int64_t ss = l->startSeed;
int64_t cs;
@ -1706,17 +1871,29 @@ void mapVoronoiZoom(const Layer * l, int * out, int x, int z, int w, int h)
{
int v00 = out[(j+0)*pW];
int v01 = out[(j+1)*pW];
int v10, v11;
for (i = 0; i < pW-1; i++)
for (i = 0; i < pW-1; i++, v00 = v10, v01 = v11)
{
int ii, jj;
int *pbuf = buf + (j << 2) * newW + (i << 2);
// try to prefetch the relevant rows to help prevent cache misses
PREFETCH( pbuf + newW*0 );
PREFETCH( pbuf + newW*1 );
PREFETCH( pbuf + newW*2 );
PREFETCH( pbuf + newW*3 );
PREFETCH( pbuf + newW*0, 1, 1 );
PREFETCH( pbuf + newW*1, 1, 1 );
PREFETCH( pbuf + newW*2, 1, 1 );
PREFETCH( pbuf + newW*3, 1, 1 );
v10 = out[i+1 + (j+0)*pW];
v11 = out[i+1 + (j+1)*pW];
if (v00 == v01 && v00 == v10 && v00 == v11)
{
for (jj = 0; jj < 4; jj++)
for (ii = 0; ii < 4; ii++)
pbuf[ii + jj*newW] = v00;
continue;
}
cs = getChunkSeed(ss, (i+pX) << 2, (j+pZ) << 2);
int64_t da1 = (mcFirstInt(cs, 1024) - 512) * 36;
@ -1738,9 +1915,6 @@ void mapVoronoiZoom(const Layer * l, int * out, int x, int z, int w, int h)
cs = mcStepSeed(cs, st);
int64_t dd2 = (mcFirstInt(cs, 1024) - 512) * 36 + 40*1024;
int v10 = out[i+1 + (j+0)*pW];
int v11 = out[i+1 + (j+1)*pW];
for (jj = 0; jj < 4; jj++)
{
int mj = 10240*jj;
@ -1771,9 +1945,6 @@ void mapVoronoiZoom(const Layer * l, int * out, int x, int z, int w, int h)
p[ii] = v;
}
}
v00 = v10;
v01 = v11;
}
}
@ -1783,6 +1954,7 @@ void mapVoronoiZoom(const Layer * l, int * out, int x, int z, int w, int h)
}
free(buf);
return 0;
}

View File

@ -13,9 +13,16 @@
#define NULL ((void*)0)
#endif
#define STRUCT(S) typedef struct S S; struct S
#if __GNUC__
#define PREFETCH(PTR,RW,LOC) __builtin_prefetch(PTR,RW,LOC)
#define EXPECT(COND,VAL) __builtin_expect(COND,VAL)
#else
#define PREFETCH(PTR)
#define EXPECT(COND,VAL) (COND)
#endif
enum BiomeID
{
@ -61,8 +68,8 @@ enum BiomeID
wooded_mountains, extremeHillsPlus = wooded_mountains,
savanna,
savanna_plateau, savannaPlateau = savanna_plateau,
badlands, mesa = badlands,
wooded_badlands_plateau, mesaPlateau_F = wooded_badlands_plateau,
badlands, mesa = badlands,
wooded_badlands_plateau, mesaPlateau_F = wooded_badlands_plateau,
badlands_plateau, mesaPlateau = badlands_plateau,
// 40 -- 1.13
small_end_islands,
@ -78,9 +85,9 @@ enum BiomeID
// 50
deep_frozen_ocean, frozenDeepOcean = deep_frozen_ocean,
BIOME_NUM,
the_void = 127,
// mutated variants
sunflower_plains = plains+128,
desert_lakes = desert+128,
@ -149,10 +156,12 @@ STRUCT(Layer)
int64_t startSeed; // (world seed dependent) starting point for chunk seeds
OceanRnd *oceanRnd; // world seed dependent data for ocean temperatures
void *data; // generic data for custom layers
int scale; // map scale of this layer (map entry = scale x scale blocks)
int edge; // maximum border required from parent layer
void (*getMap)(const Layer *, int *, int, int, int, int);
int (*getMap)(const Layer *, int *, int, int, int, int);
Layer *p, *p2; // parent layers
};
@ -313,12 +322,19 @@ static inline int64_t getLayerSeed(int64_t salt)
return ls;
}
static inline int64_t getStartSalt(int64_t ws, int64_t ls)
{
int64_t st = ws;
st = mcStepSeed(st, ls);
st = mcStepSeed(st, ls);
st = mcStepSeed(st, ls);
return st;
}
static inline int64_t getStartSeed(int64_t ws, int64_t ls)
{
int64_t ss = ws;
ss = mcStepSeed(ss, ls);
ss = mcStepSeed(ss, ls);
ss = mcStepSeed(ss, ls);
ss = getStartSalt(ss, ls);
ss = mcStepSeed(ss, 0);
return ss;
}
@ -329,41 +345,36 @@ static inline int64_t getStartSeed(int64_t ws, int64_t ls)
// Layers
//==============================================================================
// A null layer does nothing, and can be used to apply a layer to existing data.
void mapNull (const Layer *, int *, int, int, int, int);
// A skip layer simply calls its first parent without modification.
// This can be used as an easy way to skip a layer in a generator.
void mapSkip (const Layer *, int *, int, int, int, int);
void mapIsland (const Layer *, int *, int, int, int, int);
void mapZoom (const Layer *, int *, int, int, int, int);
void mapAddIsland (const Layer *, int *, int, int, int, int);
void mapRemoveTooMuchOcean (const Layer *, int *, int, int, int, int);
void mapAddSnow (const Layer *, int *, int, int, int, int);
void mapCoolWarm (const Layer *, int *, int, int, int, int);
void mapHeatIce (const Layer *, int *, int, int, int, int);
void mapSpecial (const Layer *, int *, int, int, int, int);
void mapAddMushroomIsland (const Layer *, int *, int, int, int, int);
void mapDeepOcean (const Layer *, int *, int, int, int, int);
void mapBiome (const Layer *, int *, int, int, int, int);
void mapBiomeBE (const Layer *, int *, int, int, int, int);
void mapAddBamboo (const Layer *, int *, int, int, int, int);
void mapRiverInit (const Layer *, int *, int, int, int, int);
void mapBiomeEdge (const Layer *, int *, int, int, int, int);
void mapHills (const Layer *, int *, int, int, int, int);
void mapRiver (const Layer *, int *, int, int, int, int);
void mapSmooth (const Layer *, int *, int, int, int, int);
void mapRareBiome (const Layer *, int *, int, int, int, int);
void mapShore (const Layer *, int *, int, int, int, int);
void mapRiverMix (const Layer *, int *, int, int, int, int);
int mapIsland (const Layer *, int *, int, int, int, int);
int mapZoomIsland (const Layer *, int *, int, int, int, int);
int mapZoom (const Layer *, int *, int, int, int, int);
int mapAddIsland (const Layer *, int *, int, int, int, int);
int mapRemoveTooMuchOcean (const Layer *, int *, int, int, int, int);
int mapAddSnow (const Layer *, int *, int, int, int, int);
int mapCoolWarm (const Layer *, int *, int, int, int, int);
int mapHeatIce (const Layer *, int *, int, int, int, int);
int mapSpecial (const Layer *, int *, int, int, int, int);
int mapAddMushroomIsland (const Layer *, int *, int, int, int, int);
int mapDeepOcean (const Layer *, int *, int, int, int, int);
int mapBiome (const Layer *, int *, int, int, int, int);
int mapBiomeBE (const Layer *, int *, int, int, int, int);
int mapAddBamboo (const Layer *, int *, int, int, int, int);
int mapRiverInit (const Layer *, int *, int, int, int, int);
int mapBiomeEdge (const Layer *, int *, int, int, int, int);
int mapHills (const Layer *, int *, int, int, int, int);
int mapRiver (const Layer *, int *, int, int, int, int);
int mapSmooth (const Layer *, int *, int, int, int, int);
int mapRareBiome (const Layer *, int *, int, int, int, int);
int mapShore (const Layer *, int *, int, int, int, int);
int mapRiverMix (const Layer *, int *, int, int, int, int);
// 1.13 layers
void mapHills113 (const Layer *, int *, int, int, int, int);
void mapOceanTemp (const Layer *, int *, int, int, int, int);
void mapOceanMix (const Layer *, int *, int, int, int, int);
int mapHills113 (const Layer *, int *, int, int, int, int);
int mapOceanTemp (const Layer *, int *, int, int, int, int);
int mapOceanMix (const Layer *, int *, int, int, int, int);
// final layer 1:1
void mapVoronoiZoom (const Layer *, int *, int, int, int, int);
int mapVoronoiZoom (const Layer *, int *, int, int, int, int);
#ifdef __cplusplus

View File

@ -2,8 +2,7 @@ CC = gcc
AR = ar
ARFLAGS = cr
override LDFLAGS = -lm
override CFLAGS += -Wall -fwrapv -march=native
#override CFLAGS += -DUSE_SIMD
override CFLAGS += -Wall -fwrapv
ifeq ($(OS),Windows_NT)
override CFLAGS += -D_WIN32
@ -13,15 +12,16 @@ else
#RM = rm
endif
.PHONY : all debug libcubiomes clean
.PHONY : all release debug libcubiomes clean
all: CFLAGS += -O3 -march=native
all: libcubiomes find_quadhuts find_compactbiomes clean
all: release
debug: CFLAGS += -DDEBUG -O0 -ggdb3
debug: find_quadhuts find_compactbiomes clean
debug: libcubiomes
release: CFLAGS += -O3 -march=native
release: libcubiomes find_quadhuts find_compactbiomes
libcubiomes: CFLAGS += -O3 -fPIC
libcubiomes: CFLAGS += -fPIC
libcubiomes: layers.o generator.o finders.o util.o
$(AR) $(ARFLAGS) libcubiomes.a $^