mirror of
https://github.com/Cubitect/cubiomes.git
synced 2025-09-24 04:03:39 -04:00
Refactored layer functions for const Layers args + optimisations.
This commit is contained in:
parent
470a42968c
commit
b26f4eb1f7
@ -97,10 +97,8 @@ int main(int argc, char *argv[])
|
||||
// so we can test the biome at these positions.
|
||||
Pos qhpos[4];
|
||||
|
||||
// Setup a dummy layer for Layer 19: Biome, to make preliminary seed tests.
|
||||
Layer layerBiomeDummy;
|
||||
layerBiomeDummy.scale = 256;
|
||||
setupLayer(&layerBiomeDummy, NULL, 200, NULL);
|
||||
// layerSeed for Layer 19: Biome, to make preliminary seed tests.
|
||||
int64_t lsBiome = g.layers[L_BIOME_256].layerSeed;
|
||||
|
||||
|
||||
int areaX = (regPosX << 1) + 1;
|
||||
@ -137,12 +135,13 @@ int main(int argc, char *argv[])
|
||||
// generator is quite bad, the "mcNextRand() mod 6" check has a period
|
||||
// pattern of ~3 on the high seed-bits, which means we can avoid
|
||||
// checking all 16 high-bit combinations.
|
||||
int64_t ss, cs;
|
||||
for (j = 0; j < 5; j++)
|
||||
{
|
||||
seed = base + ((j+0x53) << 48);
|
||||
setWorldSeed(&layerBiomeDummy, seed);
|
||||
setChunkSeed(&layerBiomeDummy, areaX+1, areaZ+1);
|
||||
if (mcNextInt(&layerBiomeDummy, 6) == 5)
|
||||
ss = getStartSeed(seed, lsBiome);
|
||||
cs = getChunkSeed(ss, areaX+1, areaZ+1);
|
||||
if (mcFirstInt(cs, 6) == 5)
|
||||
break;
|
||||
}
|
||||
if (j >= 5)
|
||||
@ -158,10 +157,9 @@ int main(int argc, char *argv[])
|
||||
/** Pre-Generation Checks **/
|
||||
// We can check that at least one swamp could generate in this area
|
||||
// before doing the biome generator checks.
|
||||
setWorldSeed(&layerBiomeDummy, seed);
|
||||
|
||||
setChunkSeed(&layerBiomeDummy, areaX+1, areaZ+1);
|
||||
if (mcNextInt(&layerBiomeDummy, 6) != 5)
|
||||
ss = getStartSeed(seed, lsBiome);
|
||||
cs = getChunkSeed(ss, areaX+1, areaZ+1);
|
||||
if (mcFirstInt(cs, 6) != 5)
|
||||
continue;
|
||||
|
||||
// This seed base does not seem to contain many quad huts, so make
|
||||
@ -170,12 +168,12 @@ int main(int argc, char *argv[])
|
||||
if (hits == 0 && (j & 0xfff) == 0xfff)
|
||||
{
|
||||
swpc = 0;
|
||||
setChunkSeed(&layerBiomeDummy, areaX, areaZ+1);
|
||||
swpc += mcNextInt(&layerBiomeDummy, 6) == 5;
|
||||
setChunkSeed(&layerBiomeDummy, areaX+1, areaZ);
|
||||
swpc += mcNextInt(&layerBiomeDummy, 6) == 5;
|
||||
setChunkSeed(&layerBiomeDummy, areaX, areaZ);
|
||||
swpc += mcNextInt(&layerBiomeDummy, 6) == 5;
|
||||
cs = getChunkSeed(ss, areaX, areaZ+1);
|
||||
swpc += mcFirstInt(cs, 6) == 5;
|
||||
cs = getChunkSeed(ss, areaX+1, areaZ);
|
||||
swpc += mcFirstInt(cs, 6) == 5;
|
||||
cs = getChunkSeed(ss, areaX, areaZ);
|
||||
swpc += mcFirstInt(cs, 6) == 5;
|
||||
|
||||
if (swpc < (j > 0x1000 ? 2 : 1))
|
||||
break;
|
||||
|
29
finders.c
29
finders.c
@ -993,7 +993,7 @@ Pos findBiomePosition(
|
||||
{
|
||||
for (i = 0, j = 2; i < width*height; i++)
|
||||
{
|
||||
if (!isValid[map[i] & 0xff]) continue;
|
||||
if (!biomeExists(map[i]) || !isValid[map[i]]) continue;
|
||||
if ((found == 0 || nextInt(seed, j++) == 0))
|
||||
{
|
||||
out.x = (x1 + i%width) << 2;
|
||||
@ -1007,7 +1007,7 @@ Pos findBiomePosition(
|
||||
{
|
||||
for (i = 0; i < width*height; i++)
|
||||
{
|
||||
if (isValid[map[i] & 0xff] &&
|
||||
if (biomeExists(map[i]) && isValid[map[i]] &&
|
||||
(found == 0 || nextInt(seed, found + 1) == 0))
|
||||
{
|
||||
out.x = (x1 + i%width) << 2;
|
||||
@ -1063,7 +1063,7 @@ int areBiomesViable(
|
||||
|
||||
for (i = 0; i < width*height; i++)
|
||||
{
|
||||
if (!isValid[ map[i] & 0xff ])
|
||||
if (!biomeExists(map[i]) || !isValid[ map[i] ])
|
||||
{
|
||||
if (cache == NULL) free(map);
|
||||
return 0;
|
||||
@ -1601,11 +1601,6 @@ int64_t filterAllTempCats(
|
||||
|
||||
map = cache ? cache : allocCache(lFilterSpecial, sX, sZ);
|
||||
|
||||
// Construct a dummy Edge,Special layer.
|
||||
Layer layerSpecial;
|
||||
layerSpecial.scale = 1024;
|
||||
setupLayer(&layerSpecial, NULL, 3, NULL);
|
||||
|
||||
int64_t sidx, hits, seed;
|
||||
int types[9];
|
||||
int specialCnt;
|
||||
@ -1623,14 +1618,14 @@ int64_t filterAllTempCats(
|
||||
// tested for without going through the previous layers. (We'll get
|
||||
// false positives due to Oceans, but this works fine to rule out some
|
||||
// seeds early on.)
|
||||
setWorldSeed(&layerSpecial, seed);
|
||||
int64_t ss = getStartSeed(seed, lFilterSpecial->layerSeed);
|
||||
specialCnt = 0;
|
||||
for (i = 0; i < sX; i++)
|
||||
{
|
||||
for (j = 0; j < sZ; j++)
|
||||
{
|
||||
setChunkSeed(&layerSpecial, (int64_t)(i+pX), (int64_t)(j+pZ));
|
||||
if (mcNextInt(&layerSpecial, 13) == 0)
|
||||
int64_t cs = getChunkSeed(ss, i+pX, j+pZ);
|
||||
if (mcFirstInt(cs, 13) == 0)
|
||||
specialCnt++;
|
||||
}
|
||||
}
|
||||
@ -1956,15 +1951,15 @@ int64_t checkForBiomes(
|
||||
// temperature categories present.
|
||||
if (filter.tempNormal || filter.tempSpecial)
|
||||
{
|
||||
ss = processWorldSeed(seed, lspecial->baseSeed);
|
||||
ss = getStartSeed(seed, lspecial->layerSeed);
|
||||
|
||||
types[0] = types[1] = 0;
|
||||
for (z = 0; z < areaHeight1024; z++)
|
||||
{
|
||||
for (x = 0; x < areaWidth1024; x++)
|
||||
{
|
||||
cs = getChunkSeed(ss, (int64_t)(x + areaX1024), (int64_t)(z + areaZ1024));
|
||||
types[(cs >> 24) % 13 == 0]++;
|
||||
cs = getChunkSeed(ss, x + areaX1024, z + areaZ1024);
|
||||
types[mcFirstInt(cs, 13) == 0]++;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1977,14 +1972,14 @@ int64_t checkForBiomes(
|
||||
// Check there is a mushroom island, provided there is an ocean.
|
||||
if (filter.requireMushroom)
|
||||
{
|
||||
ss = processWorldSeed(seed, lmushroom->baseSeed);
|
||||
ss = getStartSeed(seed, lmushroom->layerSeed);
|
||||
|
||||
for (z = 0; z < areaHeight256; z++)
|
||||
{
|
||||
for (x = 0; x < areaWidth256; x++)
|
||||
{
|
||||
cs = getChunkSeed(ss, (int64_t)(x + areaX256), (int64_t)(z + areaZ256));
|
||||
if ((cs >> 24) % 100 == 0)
|
||||
if (mcFirstInt(cs, 100) == 0)
|
||||
{
|
||||
goto after_protomushroom;
|
||||
}
|
||||
@ -1997,7 +1992,7 @@ int64_t checkForBiomes(
|
||||
|
||||
if (filter.checkBiomePotential)
|
||||
{
|
||||
ss = processWorldSeed(seed, lbiomes->baseSeed);
|
||||
ss = getStartSeed(seed, lbiomes->layerSeed);
|
||||
|
||||
potential = 0;
|
||||
required = filter.biomesToFind & (
|
||||
|
28
generator.c
28
generator.c
@ -6,22 +6,25 @@
|
||||
#include <string.h>
|
||||
|
||||
|
||||
void setupLayer(Layer *l, Layer *p, int s, void (*getMap)(Layer *layer, int *out, int x, int z, int w, int h))
|
||||
|
||||
void setupLayer(Layer *l, Layer *p, int s,
|
||||
void (*getMap)(const Layer * RESTRICT, int *, int, int, int, int))
|
||||
{
|
||||
setBaseSeed(l, s);
|
||||
l->layerSeed = getLayerSeed(s);
|
||||
l->startSalt = 0;
|
||||
l->startSeed = 0;
|
||||
l->p = p;
|
||||
l->p2 = NULL;
|
||||
l->scale = 0;
|
||||
l->getMap = getMap;
|
||||
l->oceanRnd = NULL;
|
||||
}
|
||||
|
||||
void setupMultiLayer(Layer *l, Layer *p1, Layer *p2, int s, void (*getMap)(Layer *layer, int *out, int x, int z, int w, int h))
|
||||
void setupMultiLayer(Layer *l, Layer *p1, Layer *p2, int s,
|
||||
void (*getMap)(const Layer * RESTRICT, int *, int, int, int, int))
|
||||
{
|
||||
setBaseSeed(l, s);
|
||||
l->p = p1;
|
||||
setupLayer(l, p1, s, getMap);
|
||||
l->p2 = p2;
|
||||
l->getMap = getMap;
|
||||
l->oceanRnd = NULL;
|
||||
}
|
||||
|
||||
|
||||
@ -54,7 +57,7 @@ static LayerStack setupGeneratorImpl(const int mcversion, const int largeBiomes)
|
||||
g.layers = (Layer *) calloc(g.layerCnt, sizeof(Layer));
|
||||
Layer *l = g.layers;
|
||||
|
||||
// LAYER PARENT SEED LAYER_FUNCTION
|
||||
// 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_ADD_ISLAND_2048], &l[L_ZOOM_2048], 1, mapAddIsland);
|
||||
@ -79,11 +82,11 @@ static LayerStack setupGeneratorImpl(const int mcversion, const int largeBiomes)
|
||||
mcversion != MCBE ? mapBiome : mapBiomeBE);
|
||||
|
||||
if (mcversion <= MC_1_13)
|
||||
setupLayer(&l[L_ZOOM_128], &l[L_BIOME_256], 1000, mapZoom);
|
||||
setupLayer(&l[L_ZOOM_128], &l[L_BIOME_256], 1000, mapZoom);
|
||||
else
|
||||
{
|
||||
setupLayer(&l[L14_BAMBOO_256], &l[L_BIOME_256], 1001, mapAddBamboo);
|
||||
setupLayer(&l[L_ZOOM_128], &l[L14_BAMBOO_256], 1000, mapZoom);
|
||||
setupLayer(&l[L14_BAMBOO_256], &l[L_BIOME_256], 1001, mapAddBamboo);
|
||||
setupLayer(&l[L_ZOOM_128], &l[L14_BAMBOO_256], 1000, mapZoom);
|
||||
}
|
||||
|
||||
setupLayer(&l[L_ZOOM_64], &l[L_ZOOM_128], 1001, mapZoom);
|
||||
@ -204,6 +207,7 @@ static void getMaxArea(Layer *layer, int areaX, int areaZ, int *maxX, int *maxZ)
|
||||
layer->getMap != mapIsland &&
|
||||
layer->getMap != mapSpecial &&
|
||||
layer->getMap != mapBiome &&
|
||||
layer->getMap != mapRareBiome &&
|
||||
layer->getMap != mapRiverInit &&
|
||||
layer->getMap != mapRiverMix &&
|
||||
layer->getMap != mapOceanTemp)
|
||||
@ -245,7 +249,7 @@ void applySeed(LayerStack *g, int64_t seed)
|
||||
setWorldSeed(&g->layers[L_VORONOI_ZOOM_1], seed);
|
||||
}
|
||||
|
||||
void genArea(Layer *layer, int *out, int areaX, int areaZ, int areaWidth, int areaHeight)
|
||||
void 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);
|
||||
|
378
layers.h
378
layers.h
@ -13,29 +13,11 @@
|
||||
#define NULL ((void*)0)
|
||||
#endif
|
||||
|
||||
#define SIMD_NOTIFY 0
|
||||
|
||||
#if defined USE_SIMD && __AVX2__
|
||||
#include <emmintrin.h>
|
||||
#include <smmintrin.h>
|
||||
#include <immintrin.h>
|
||||
#if SIMD_NOTIFY
|
||||
#warning "Using AVX2 extensions."
|
||||
#endif
|
||||
#elif defined USE_SIMD && defined __SSE4_2__
|
||||
#include <emmintrin.h>
|
||||
#include <smmintrin.h>
|
||||
#if SIMD_NOTIFY
|
||||
#warning "Using SSE4.2 extensions."
|
||||
#endif
|
||||
#else
|
||||
//#warning "Using no SIMD extensions."
|
||||
#endif
|
||||
#define RESTRICT __restrict
|
||||
#define REGISTER register
|
||||
|
||||
#define STRUCT(S) typedef struct S S; struct S
|
||||
|
||||
#define OPT_O2 __attribute__((optimize("O2")))
|
||||
|
||||
|
||||
enum BiomeID
|
||||
{
|
||||
@ -164,16 +146,15 @@ STRUCT(OceanRnd)
|
||||
|
||||
STRUCT(Layer)
|
||||
{
|
||||
int64_t baseSeed; // Generator seed (depends only on layer hierarchy)
|
||||
int64_t worldSeed; // based on the seed of the world
|
||||
|
||||
int64_t chunkSeed; // randomiser seed
|
||||
int64_t layerSeed; // (depends only on layer salt)
|
||||
int64_t startSalt; // (world seed dependent) for RND ints beyond the first
|
||||
int64_t startSeed; // (world seed dependent) starting point for chunk seeds
|
||||
|
||||
OceanRnd *oceanRnd; // world seed dependent data for ocean temperatures
|
||||
|
||||
int scale; // map scale of this layer (map entry = scale x scale blocks)
|
||||
|
||||
void (*getMap)(Layer *layer, int *out, int x, int z, int w, int h);
|
||||
void (*getMap)(const Layer * RESTRICT, int * RESTRICT, int, int, int, int);
|
||||
|
||||
Layer *p, *p2; // parent layers
|
||||
};
|
||||
@ -284,306 +265,107 @@ static inline int isBiomeSnowy(int id)
|
||||
return biomeExists(id) && biomes[id].temp < 0.1;
|
||||
}
|
||||
|
||||
static inline int mcNextInt(Layer *layer, int mod)
|
||||
|
||||
/**
|
||||
* The seed pipeline:
|
||||
*
|
||||
* Salt of Layer -> layerSeed (ls)
|
||||
* layerSeed (ls) + worldSeed (ws) -> startSalt (st) + startSeed (ss)
|
||||
* startSeed (ls) + coords (x,z) -> chunkSeed (cs)
|
||||
*
|
||||
* The chunkSeed alone is enough to generate the first RND integer with:
|
||||
* mcFirstInt(cs, mod)
|
||||
* subsequent RND integers are generated by stepping the chunkSeed forwards,
|
||||
* salted with startSalt:
|
||||
* cs_next = mcStepSeed(cs, st)
|
||||
*/
|
||||
|
||||
static inline int64_t mcStepSeed(int64_t s, int64_t salt)
|
||||
{
|
||||
int ret = (int)((layer->chunkSeed >> 24) % (int64_t)mod);
|
||||
return s * (s * 6364136223846793005LL + 1442695040888963407LL) + salt;
|
||||
}
|
||||
|
||||
static inline int mcFirstInt(int64_t s, int mod)
|
||||
{
|
||||
int ret = (int)((s >> 24) % mod);
|
||||
if (ret < 0)
|
||||
{
|
||||
ret += mod;
|
||||
}
|
||||
|
||||
layer->chunkSeed *= layer->chunkSeed * 6364136223846793005LL + 1442695040888963407LL;
|
||||
layer->chunkSeed += layer->worldSeed;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static inline int64_t processWorldSeed(register int64_t ws, const int64_t bs)
|
||||
static inline int mcIsFirstZero(int64_t s, int mod)
|
||||
{
|
||||
ws *= ws * 6364136223846793005LL + 1442695040888963407LL;
|
||||
ws += bs;
|
||||
ws *= ws * 6364136223846793005LL + 1442695040888963407LL;
|
||||
ws += bs;
|
||||
ws *= ws * 6364136223846793005LL + 1442695040888963407LL;
|
||||
ws += bs;
|
||||
ws *= ws * 6364136223846793005LL + 1442695040888963407LL;
|
||||
return ws;
|
||||
return (int)((s >> 24) % mod) == 0;
|
||||
}
|
||||
|
||||
static inline int64_t getChunkSeed(register int64_t ss, const int64_t x, const int64_t z)
|
||||
static inline int64_t getChunkSeed(int64_t ss, int x, int z)
|
||||
{
|
||||
ss += x;
|
||||
ss *= ss * 6364136223846793005LL + 1442695040888963407LL;
|
||||
ss += z;
|
||||
ss *= ss * 6364136223846793005LL + 1442695040888963407LL;
|
||||
ss += x;
|
||||
ss *= ss * 6364136223846793005LL + 1442695040888963407LL;
|
||||
ss += z;
|
||||
int64_t cs = ss + x;
|
||||
cs = mcStepSeed(cs, z);
|
||||
cs = mcStepSeed(cs, x);
|
||||
cs = mcStepSeed(cs, z);
|
||||
return cs;
|
||||
}
|
||||
|
||||
static inline int64_t getLayerSeed(int64_t salt)
|
||||
{
|
||||
int64_t ls = mcStepSeed(salt, salt);
|
||||
ls = mcStepSeed(ls, salt);
|
||||
ls = mcStepSeed(ls, salt);
|
||||
return ls;
|
||||
}
|
||||
|
||||
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 = mcStepSeed(ss, 0);
|
||||
return ss;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static inline void setChunkSeed(Layer *layer, int64_t chunkX, int64_t chunkZ)
|
||||
{
|
||||
layer->chunkSeed = layer->worldSeed;
|
||||
layer->chunkSeed *= layer->chunkSeed * 6364136223846793005LL + 1442695040888963407LL;
|
||||
layer->chunkSeed += chunkX;
|
||||
layer->chunkSeed *= layer->chunkSeed * 6364136223846793005LL + 1442695040888963407LL;
|
||||
layer->chunkSeed += chunkZ;
|
||||
layer->chunkSeed *= layer->chunkSeed * 6364136223846793005LL + 1442695040888963407LL;
|
||||
layer->chunkSeed += chunkX;
|
||||
layer->chunkSeed *= layer->chunkSeed * 6364136223846793005LL + 1442695040888963407LL;
|
||||
layer->chunkSeed += chunkZ;
|
||||
}
|
||||
|
||||
static inline void setBaseSeed(Layer *layer, int64_t seed)
|
||||
{
|
||||
layer->baseSeed = seed;
|
||||
layer->baseSeed *= layer->baseSeed * 6364136223846793005LL + 1442695040888963407LL;
|
||||
layer->baseSeed += seed;
|
||||
layer->baseSeed *= layer->baseSeed * 6364136223846793005LL + 1442695040888963407LL;
|
||||
layer->baseSeed += seed;
|
||||
layer->baseSeed *= layer->baseSeed * 6364136223846793005LL + 1442695040888963407LL;
|
||||
layer->baseSeed += seed;
|
||||
|
||||
layer->p = NULL;
|
||||
layer->worldSeed = 0;
|
||||
layer->chunkSeed = 0;
|
||||
}
|
||||
|
||||
#if defined USE_SIMD && __AVX2__
|
||||
|
||||
static inline __m256i set8ChunkSeeds(int ws, __m256i xs, __m256i zs)
|
||||
{
|
||||
__m256i out = _mm256_set1_epi32(ws);
|
||||
__m256i mul = _mm256_set1_epi32(1284865837);
|
||||
__m256i add = _mm256_set1_epi32(4150755663);
|
||||
out = _mm256_add_epi32(xs, _mm256_mullo_epi32(out, _mm256_add_epi32(add, _mm256_mullo_epi32(out, mul))));
|
||||
out = _mm256_add_epi32(zs, _mm256_mullo_epi32(out, _mm256_add_epi32(add, _mm256_mullo_epi32(out, mul))));
|
||||
out = _mm256_add_epi32(xs, _mm256_mullo_epi32(out, _mm256_add_epi32(add, _mm256_mullo_epi32(out, mul))));
|
||||
return _mm256_add_epi32(zs, _mm256_mullo_epi32(out, _mm256_add_epi32(add, _mm256_mullo_epi32(out, mul))));
|
||||
}
|
||||
|
||||
static inline __m256i mc8NextInt(__m256i* cs, int ws, int mask)
|
||||
{
|
||||
__m256i andm = _mm256_set1_epi32(mask);
|
||||
__m256i ret = _mm256_and_si256(andm, _mm256_srli_epi32(*cs, 24));
|
||||
*cs = _mm256_add_epi32(_mm256_set1_epi32(ws), _mm256_mullo_epi32(*cs, _mm256_add_epi32(_mm256_set1_epi32(4150755663), _mm256_mullo_epi32(*cs, _mm256_set1_epi32(1284865837)))));
|
||||
return _mm256_add_epi32(ret, _mm256_and_si256(andm, _mm256_cmpgt_epi32(_mm256_set1_epi32(0), ret)));
|
||||
}
|
||||
|
||||
static inline __m256i select8Random2(__m256i* cs, int ws, __m256i a1, __m256i a2)
|
||||
{
|
||||
__m256i cmp = _mm256_cmpeq_epi32(_mm256_set1_epi32(0), mc8NextInt(cs, ws, 0x1));
|
||||
return _mm256_or_si256(_mm256_and_si256(cmp, a1), _mm256_andnot_si256(cmp, a2));
|
||||
}
|
||||
|
||||
static inline __m256i select8Random4(__m256i* cs, int ws, __m256i a1, __m256i a2, __m256i a3, __m256i a4)
|
||||
{
|
||||
__m256i val = mc8NextInt(cs, ws, 0x3);
|
||||
__m256i v2 = _mm256_set1_epi32(2);
|
||||
__m256i cmp1 = _mm256_cmpeq_epi32(val, _mm256_set1_epi32(0));
|
||||
__m256i cmp2 = _mm256_cmpeq_epi32(v2, val);
|
||||
__m256i cmp3 = _mm256_cmpgt_epi32(v2, val);
|
||||
return _mm256_or_si256(
|
||||
_mm256_and_si256(cmp3, _mm256_or_si256(_mm256_and_si256(cmp1, a1), _mm256_andnot_si256(cmp1, a2))),
|
||||
_mm256_andnot_si256(cmp3, _mm256_or_si256(_mm256_and_si256(cmp2, a3), _mm256_andnot_si256(cmp2, a4)))
|
||||
);
|
||||
}
|
||||
|
||||
static inline __m256i select8ModeOrRandom(__m256i* cs, int ws, __m256i a1, __m256i a2, __m256i a3, __m256i a4)
|
||||
{
|
||||
__m256i cmp1 = _mm256_cmpeq_epi32(a1, a2);
|
||||
__m256i cmp2 = _mm256_cmpeq_epi32(a1, a3);
|
||||
__m256i cmp3 = _mm256_cmpeq_epi32(a1, a4);
|
||||
__m256i cmp4 = _mm256_cmpeq_epi32(a2, a3);
|
||||
__m256i cmp5 = _mm256_cmpeq_epi32(a2, a4);
|
||||
__m256i cmp6 = _mm256_cmpeq_epi32(a3, a4);
|
||||
__m256i isa1 = _mm256_or_si256(
|
||||
_mm256_andnot_si256(cmp6, cmp1),
|
||||
_mm256_or_si256 (
|
||||
_mm256_andnot_si256(cmp5, cmp2),
|
||||
_mm256_andnot_si256(cmp4, cmp3)
|
||||
)
|
||||
);
|
||||
__m256i isa2 = _mm256_or_si256(
|
||||
_mm256_andnot_si256(cmp3, cmp4),
|
||||
_mm256_andnot_si256(cmp2, cmp5)
|
||||
);
|
||||
__m256i isa3 = _mm256_andnot_si256(cmp1, cmp6);
|
||||
|
||||
return _mm256_or_si256(
|
||||
_mm256_andnot_si256(
|
||||
_mm256_or_si256(
|
||||
isa1,
|
||||
_mm256_or_si256(isa2, isa3)
|
||||
),
|
||||
select8Random4(cs, ws, a1, a2, a3, a4)
|
||||
),
|
||||
_mm256_or_si256(
|
||||
_mm256_and_si256(isa1, a1),
|
||||
_mm256_or_si256(
|
||||
_mm256_and_si256(isa2, a2),
|
||||
_mm256_and_si256(isa3, a3)
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
#elif defined USE_SIMD && defined __SSE4_2__
|
||||
|
||||
static inline __m128i set4ChunkSeeds(int ws, __m128i xs, __m128i zs)
|
||||
{
|
||||
__m128i out = _mm_set1_epi32(ws);
|
||||
__m128i mul = _mm_set1_epi32(1284865837);
|
||||
__m128i add = _mm_set1_epi32(4150755663);
|
||||
out = _mm_add_epi32(xs, _mm_mullo_epi32(out, _mm_add_epi32(add, _mm_mullo_epi32(out, mul))));
|
||||
out = _mm_add_epi32(zs, _mm_mullo_epi32(out, _mm_add_epi32(add, _mm_mullo_epi32(out, mul))));
|
||||
out = _mm_add_epi32(xs, _mm_mullo_epi32(out, _mm_add_epi32(add, _mm_mullo_epi32(out, mul))));
|
||||
return _mm_add_epi32(zs, _mm_mullo_epi32(out, _mm_add_epi32(add, _mm_mullo_epi32(out, mul))));
|
||||
}
|
||||
|
||||
static inline __m128i mc4NextInt(__m128i* cs, int ws, int mask)
|
||||
{
|
||||
__m128i andm = _mm_set1_epi32(mask);
|
||||
__m128i ret = _mm_and_si128(andm, _mm_srli_epi32(*cs, 24));
|
||||
*cs = _mm_add_epi32( _mm_set1_epi32(ws), _mm_mullo_epi32(*cs, _mm_add_epi32(_mm_set1_epi32(4150755663), _mm_mullo_epi32(*cs, _mm_set1_epi32(1284865837)))));
|
||||
return _mm_add_epi32(ret, _mm_and_si128(andm, _mm_cmplt_epi32(ret, _mm_set1_epi32(0))));
|
||||
}
|
||||
|
||||
static inline __m128i select4Random2(__m128i* cs, int ws, __m128i a1, __m128i a2)
|
||||
{
|
||||
__m128i cmp = _mm_cmpeq_epi32(_mm_set1_epi32(0), mc4NextInt(cs, ws, 0x1));
|
||||
return _mm_or_si128(_mm_and_si128(cmp, a1), _mm_andnot_si128(cmp, a2));
|
||||
}
|
||||
|
||||
static inline __m128i select4Random4(__m128i* cs, int ws, __m128i a1, __m128i a2, __m128i a3, __m128i a4)
|
||||
{
|
||||
__m128i val = mc4NextInt(cs, ws, 0x3);
|
||||
__m128i v2 = _mm_set1_epi32(2);
|
||||
__m128i cmp1 = _mm_cmpeq_epi32(val, _mm_set1_epi32(0));
|
||||
__m128i cmp2 = _mm_cmpeq_epi32(val, v2);
|
||||
__m128i cmp3 = _mm_cmplt_epi32(val, v2);
|
||||
return _mm_or_si128(
|
||||
_mm_and_si128(cmp3, _mm_or_si128(_mm_and_si128(cmp1, a1), _mm_andnot_si128(cmp1, a2))),
|
||||
_mm_andnot_si128(cmp3, _mm_or_si128(_mm_and_si128(cmp2, a3), _mm_andnot_si128(cmp2, a4)))
|
||||
);
|
||||
}
|
||||
|
||||
static inline __m128i select4ModeOrRandom(__m128i* cs, int ws, __m128i a1, __m128i a2, __m128i a3, __m128i a4)
|
||||
{
|
||||
//((a == b)&(c != d) | (a == c)&(b != d) | (a == d)&(b != c))&a | ((b == c)&(a != d) | (b == d)&(a != c))&b | ((c == d)&(a != b))&c
|
||||
__m128i cmp1 = _mm_cmpeq_epi32(a1, a2);
|
||||
__m128i cmp2 = _mm_cmpeq_epi32(a1, a3);
|
||||
__m128i cmp3 = _mm_cmpeq_epi32(a1, a4);
|
||||
__m128i cmp4 = _mm_cmpeq_epi32(a2, a3);
|
||||
__m128i cmp5 = _mm_cmpeq_epi32(a2, a4);
|
||||
__m128i cmp6 = _mm_cmpeq_epi32(a3, a4);
|
||||
__m128i isa1 = _mm_or_si128(
|
||||
_mm_andnot_si128(cmp6, cmp1),
|
||||
_mm_or_si128 (
|
||||
_mm_andnot_si128(cmp5, cmp2),
|
||||
_mm_andnot_si128(cmp4, cmp3)
|
||||
)
|
||||
);
|
||||
__m128i isa2 = _mm_or_si128(
|
||||
_mm_andnot_si128(cmp3, cmp4),
|
||||
_mm_andnot_si128(cmp2, cmp5)
|
||||
);
|
||||
__m128i isa3 = _mm_andnot_si128(cmp1, cmp6);
|
||||
return _mm_or_si128(
|
||||
_mm_andnot_si128(
|
||||
_mm_or_si128(
|
||||
isa1,
|
||||
_mm_or_si128(isa2, isa3)
|
||||
),
|
||||
select4Random4(cs, ws, a1, a2, a3, a4)
|
||||
),
|
||||
_mm_or_si128(
|
||||
_mm_and_si128(isa1, a1),
|
||||
_mm_or_si128(
|
||||
_mm_and_si128(isa2, a2),
|
||||
_mm_and_si128(isa3, a3)
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static inline int selectRandom2(Layer *l, int a1, int a2)
|
||||
{
|
||||
int i = mcNextInt(l, 2);
|
||||
return i == 0 ? a1 : a2;
|
||||
}
|
||||
|
||||
static inline int selectRandom4(Layer *l, int a1, int a2, int a3, int a4)
|
||||
{
|
||||
int i = mcNextInt(l, 4);
|
||||
return i == 0 ? a1 : i == 1 ? a2 : i == 2 ? a3 : a4;
|
||||
}
|
||||
|
||||
static inline int selectModeOrRandom(Layer *l, int a1, int a2, int a3, int a4)
|
||||
{
|
||||
int rndarg = selectRandom4(l, a1, a2, a3, a4);
|
||||
|
||||
if (a2 == a3 && a3 == a4) return a2;
|
||||
if (a1 == a2 && a1 == a3) return a1;
|
||||
if (a1 == a2 && a1 == a4) return a1;
|
||||
if (a1 == a3 && a1 == a4) return a1;
|
||||
if (a1 == a2 && a3 != a4) return a1;
|
||||
if (a1 == a3 && a2 != a4) return a1;
|
||||
if (a1 == a4 && a2 != a3) return a1;
|
||||
if (a2 == a3 && a1 != a4) return a2;
|
||||
if (a2 == a4 && a1 != a3) return a2;
|
||||
if (a3 == a4 && a1 != a2) return a3;
|
||||
|
||||
return rndarg;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
//==============================================================================
|
||||
// Layers
|
||||
//==============================================================================
|
||||
|
||||
// A null layer does nothing, and can be used to apply a layer to existing data.
|
||||
void mapNull(Layer *l, int * __restrict out, int x, int z, int w, int h);
|
||||
void mapNull (const Layer * RESTRICT, int * RESTRICT, 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(Layer *l, int * __restrict out, int x, int z, int w, int h);
|
||||
void mapSkip (const Layer * RESTRICT, int * RESTRICT, int, int, int, int);
|
||||
|
||||
void mapIsland(Layer *l, int * __restrict out, int x, int z, int w, int h);
|
||||
void mapZoom(Layer *l, int * __restrict out, int x, int z, int w, int h);
|
||||
void mapAddIsland(Layer *l, int * __restrict out, int x, int z, int w, int h);
|
||||
void mapRemoveTooMuchOcean(Layer *l, int * __restrict out, int x, int z, int w, int h);
|
||||
void mapAddSnow(Layer *l, int * __restrict out, int x, int z, int w, int h);
|
||||
void mapCoolWarm(Layer *l, int * __restrict out, int x, int z, int w, int h);
|
||||
void mapHeatIce(Layer *l, int * __restrict out, int x, int z, int w, int h);
|
||||
void mapSpecial(Layer *l, int * __restrict out, int x, int z, int w, int h);
|
||||
void mapAddMushroomIsland(Layer *l, int * __restrict out, int x, int z, int w, int h);
|
||||
void mapDeepOcean(Layer *l, int * __restrict out, int x, int z, int w, int h);
|
||||
void mapBiome(Layer *l, int * __restrict out, int x, int z, int w, int h);
|
||||
void mapBiomeBE(Layer *l, int * __restrict out, int x, int z, int w, int h);
|
||||
void mapAddBamboo(Layer *l, int * __restrict out, int x, int z, int w, int h);
|
||||
void mapRiverInit(Layer *l, int * __restrict out, int x, int z, int w, int h);
|
||||
void mapBiomeEdge(Layer *l, int * __restrict out, int x, int z, int w, int h);
|
||||
void mapHills(Layer *l, int * __restrict out, int x, int z, int w, int h);
|
||||
void mapRiver(Layer *l, int * __restrict out, int x, int z, int w, int h);
|
||||
void mapSmooth(Layer *l, int * __restrict out, int x, int z, int w, int h);
|
||||
void mapRareBiome(Layer *l, int * __restrict out, int x, int z, int w, int h);
|
||||
void mapShore(Layer *l, int * __restrict out, int x, int z, int w, int h);
|
||||
void mapRiverMix(Layer *l, int * __restrict out, int x, int z, int w, int h);
|
||||
void mapIsland (const Layer * RESTRICT, int * RESTRICT, int, int, int, int);
|
||||
void mapZoom (const Layer * RESTRICT, int * RESTRICT, int, int, int, int);
|
||||
void mapAddIsland (const Layer * RESTRICT, int * RESTRICT, int, int, int, int);
|
||||
void mapRemoveTooMuchOcean (const Layer * RESTRICT, int * RESTRICT, int, int, int, int);
|
||||
void mapAddSnow (const Layer * RESTRICT, int * RESTRICT, int, int, int, int);
|
||||
void mapCoolWarm (const Layer * RESTRICT, int * RESTRICT, int, int, int, int);
|
||||
void mapHeatIce (const Layer * RESTRICT, int * RESTRICT, int, int, int, int);
|
||||
void mapSpecial (const Layer * RESTRICT, int * RESTRICT, int, int, int, int);
|
||||
void mapAddMushroomIsland (const Layer * RESTRICT, int * RESTRICT, int, int, int, int);
|
||||
void mapDeepOcean (const Layer * RESTRICT, int * RESTRICT, int, int, int, int);
|
||||
void mapBiome (const Layer * RESTRICT, int * RESTRICT, int, int, int, int);
|
||||
void mapBiomeBE (const Layer * RESTRICT, int * RESTRICT, int, int, int, int);
|
||||
void mapAddBamboo (const Layer * RESTRICT, int * RESTRICT, int, int, int, int);
|
||||
void mapRiverInit (const Layer * RESTRICT, int * RESTRICT, int, int, int, int);
|
||||
void mapBiomeEdge (const Layer * RESTRICT, int * RESTRICT, int, int, int, int);
|
||||
void mapHills (const Layer * RESTRICT, int * RESTRICT, int, int, int, int);
|
||||
void mapRiver (const Layer * RESTRICT, int * RESTRICT, int, int, int, int);
|
||||
void mapSmooth (const Layer * RESTRICT, int * RESTRICT, int, int, int, int);
|
||||
void mapRareBiome (const Layer * RESTRICT, int * RESTRICT, int, int, int, int);
|
||||
void mapShore (const Layer * RESTRICT, int * RESTRICT, int, int, int, int);
|
||||
void mapRiverMix (const Layer * RESTRICT, int * RESTRICT, int, int, int, int);
|
||||
|
||||
// 1.13 layers
|
||||
void mapHills113(Layer *l, int * __restrict out, int x, int z, int w, int h);
|
||||
void mapOceanTemp(Layer *l, int * __restrict out, int areaX, int areaZ, int areaWidth, int areaHeight);
|
||||
void mapOceanMix(Layer *l, int * __restrict out, int areaX, int areaZ, int areaWidth, int areaHeight);
|
||||
void mapHills113 (const Layer * RESTRICT, int * RESTRICT, int, int, int, int);
|
||||
void mapOceanTemp (const Layer * RESTRICT, int * RESTRICT, int, int, int, int);
|
||||
void mapOceanMix (const Layer * RESTRICT, int * RESTRICT, int, int, int, int);
|
||||
|
||||
void mapVoronoiZoom(Layer *l, int * __restrict out, int x, int z, int w, int h);
|
||||
// final layer 1:1
|
||||
void mapVoronoiZoom (const Layer * RESTRICT, int * RESTRICT, int, int, int, int);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
Loading…
x
Reference in New Issue
Block a user