Switch to uint64_t for seeds to improving C99 compliance

This is a fairly major change. Some functions involving structures still need testing.
This commit is contained in:
Cubitect 2021-06-30 23:52:21 +02:00
parent 6fda1caff8
commit e12acff608
7 changed files with 363 additions and 385 deletions

188
finders.c
View File

@ -20,17 +20,18 @@
#endif #endif
//============================================================================== //==============================================================================
// Saving & Loading Seeds // Saving & Loading Seeds
//============================================================================== //==============================================================================
int64_t *loadSavedSeeds(const char *fnam, int64_t *scnt) uint64_t *loadSavedSeeds(const char *fnam, uint64_t *scnt)
{ {
FILE *fp = fopen(fnam, "r"); FILE *fp = fopen(fnam, "r");
int64_t seed, i; uint64_t seed, i;
int64_t *baseSeeds; uint64_t *baseSeeds;
if (fp == NULL) if (fp == NULL)
return NULL; return NULL;
@ -39,20 +40,20 @@ int64_t *loadSavedSeeds(const char *fnam, int64_t *scnt)
while (!feof(fp)) while (!feof(fp))
{ {
if (fscanf(fp, "%" PRId64, &seed) == 1) (*scnt)++; if (fscanf(fp, "%" PRId64, (int64_t*)&seed) == 1) (*scnt)++;
else while (!feof(fp) && fgetc(fp) != '\n'); else while (!feof(fp) && fgetc(fp) != '\n');
} }
if (*scnt == 0) if (*scnt == 0)
return NULL; return NULL;
baseSeeds = (int64_t*) calloc(*scnt, sizeof(*baseSeeds)); baseSeeds = (uint64_t*) calloc(*scnt, sizeof(*baseSeeds));
rewind(fp); rewind(fp);
for (i = 0; i < *scnt && !feof(fp);) for (i = 0; i < *scnt && !feof(fp);)
{ {
if (fscanf(fp, "%" PRId64, &baseSeeds[i]) == 1) i++; if (fscanf(fp, "%" PRId64, (int64_t*)&baseSeeds[i]) == 1) i++;
else while (!feof(fp) && fgetc(fp) != '\n'); else while (!feof(fp) && fgetc(fp) != '\n');
} }
@ -68,9 +69,9 @@ int64_t *loadSavedSeeds(const char *fnam, int64_t *scnt)
//============================================================================== //==============================================================================
void setAttemptSeed(int64_t *s, int cx, int cz) void setAttemptSeed(uint64_t *s, int cx, int cz)
{ {
*s ^= (cx >> 4) ^ ( (cz >> 4) << 4 ); *s ^= (uint64_t)(cx >> 4) ^ ( (uint64_t)(cz >> 4) << 4 );
setSeed(s, *s); setSeed(s, *s);
next(s, 31); next(s, 31);
} }
@ -134,7 +135,17 @@ int getStructureConfig(int structureType, int mc, StructureConfig *sconf)
} }
} }
int getStructurePos(int structureType, int mc, int64_t seed, int regX, int regZ, Pos *pos)
// like getFeaturePos(), but modifies the rng seed
static inline
void getRegPos(Pos *p, uint64_t *s, int rx, int rz, StructureConfig sc)
{
setSeed(s, rx*341873128712ULL + rz*132897987541ULL + *s + sc.salt);
p->x = (int)(((uint64_t)rx * sc.regionSize + nextInt(s, sc.chunkRange)) << 4);
p->z = (int)(((uint64_t)rz * sc.regionSize + nextInt(s, sc.chunkRange)) << 4);
}
int getStructurePos(int structureType, int mc, uint64_t seed, int regX, int regZ, Pos *pos)
{ {
StructureConfig sconf; StructureConfig sconf;
#if STRUCT_CONFIG_OVERRIDE #if STRUCT_CONFIG_OVERRIDE
@ -175,9 +186,9 @@ int getStructurePos(int structureType, int mc, int64_t seed, int regX, int regZ,
return nextInt(&seed, 5) == 0; return nextInt(&seed, 5) == 0;
case Treasure: case Treasure:
pos->x = (regX << 4) + 9; pos->x = (int)( ((uint32_t)regX << 4) + 9 );
pos->z = (regZ << 4) + 9; pos->z = (int)( ((uint32_t)regZ << 4) + 9 );
seed = regX*341873128712 + regZ*132897987541 + seed + sconf.salt; seed = regX*341873128712ULL + regZ*132897987541ULL + seed + sconf.salt;
setSeed(&seed, seed); setSeed(&seed, seed);
return nextFloat(&seed) < 0.01; return nextFloat(&seed) < 0.01;
@ -185,20 +196,16 @@ int getStructurePos(int structureType, int mc, int64_t seed, int regX, int regZ,
if (mc < MC_1_16) { if (mc < MC_1_16) {
setAttemptSeed(&seed, regX << 4, regZ << 4); setAttemptSeed(&seed, regX << 4, regZ << 4);
int valid = nextInt(&seed, 3) == 0; int valid = nextInt(&seed, 3) == 0;
pos->x = ((regX << 4) + nextInt(&seed, 8) + 4) << 4; pos->x = (int)((((uint64_t)regX << 4) + nextInt(&seed,8) + 4) << 4);
pos->z = ((regZ << 4) + nextInt(&seed, 8) + 4) << 4; pos->z = (int)((((uint64_t)regZ << 4) + nextInt(&seed,8) + 4) << 4);
return valid; return valid;
} else { } else {
setSeed(&seed, regX*341873128712 + regZ*132897987541 + seed + sconf.salt); getRegPos(pos, &seed, regX, regZ, sconf);
pos->x = (regX * sconf.regionSize + nextInt(&seed, sconf.chunkRange)) << 4;
pos->z = (regZ * sconf.regionSize + nextInt(&seed, sconf.chunkRange)) << 4;
return nextInt(&seed, 5) < 2; return nextInt(&seed, 5) < 2;
} }
case Bastion: case Bastion:
setSeed(&seed, regX*341873128712 + regZ*132897987541 + seed + sconf.salt); getRegPos(pos, &seed, regX, regZ, sconf);
pos->x = (regX * sconf.regionSize + nextInt(&seed, sconf.chunkRange)) << 4;
pos->z = (regZ * sconf.regionSize + nextInt(&seed, sconf.chunkRange)) << 4;
return nextInt(&seed, 5) >= 2; return nextInt(&seed, 5) >= 2;
default: default:
@ -209,12 +216,12 @@ int getStructurePos(int structureType, int mc, int64_t seed, int regX, int regZ,
return 0; return 0;
} }
int isMineshaftChunk(int64_t seed, int chunkX, int chunkZ) int isMineshaftChunk(uint64_t seed, int chunkX, int chunkZ)
{ {
int64_t s; uint64_t s;
setSeed(&s, seed); setSeed(&s, seed);
int64_t i = nextLong(&s); uint64_t i = nextLong(&s);
int64_t j = nextLong(&s); uint64_t j = nextLong(&s);
s = chunkX * i ^ chunkZ * j ^ seed; s = chunkX * i ^ chunkZ * j ^ seed;
setSeed(&s, s); setSeed(&s, s);
return nextDouble(&s) < 0.004; return nextDouble(&s) < 0.004;
@ -394,7 +401,7 @@ Pos getOptimalAfk(Pos p[4], int ax, int ay, int az, int *spcnt)
STRUCT(linked_seeds_t) STRUCT(linked_seeds_t)
{ {
int64_t seeds[100]; uint64_t seeds[100];
size_t len; size_t len;
linked_seeds_t *next; linked_seeds_t *next;
}; };
@ -402,13 +409,13 @@ STRUCT(linked_seeds_t)
STRUCT(threadinfo_t) STRUCT(threadinfo_t)
{ {
// seed range // seed range
int64_t start, end; uint64_t start, end;
const int64_t *lowBits; const uint64_t *lowBits;
int lowBitCnt; int lowBitCnt;
int lowBitN; int lowBitN;
// testing function // testing function
int (*check)(int64_t, void*); int (*check)(uint64_t, void*);
void *data; void *data;
// output // output
@ -440,7 +447,7 @@ static int mkdirp(char *path)
struct stat st; struct stat st;
if (stat(path, &st) == -1) if (stat(path, &st) == -1)
err = mkdir(path, 0773); err = mkdir(path, 0773);
else if (!(st.st_mode & S_IFDIR)) else if (!S_ISDIR(st.st_mode))
err = 1; err = 1;
p = q+1; p = q+1;
@ -461,17 +468,17 @@ static DWORD WINAPI searchAll48Thread(LPVOID data)
threadinfo_t *info = (threadinfo_t*)data; threadinfo_t *info = (threadinfo_t*)data;
int64_t seed = info->start; uint64_t seed = info->start;
int64_t end = info->end; uint64_t end = info->end;
linked_seeds_t *lp = &info->ls; linked_seeds_t *lp = &info->ls;
lp->len = 0; lp->len = 0;
lp->next = NULL; lp->next = NULL;
if (info->lowBits) if (info->lowBits)
{ {
int64_t hstep = 1LL << info->lowBitN; uint64_t hstep = 1ULL << info->lowBitN;
int64_t hmask = ~(hstep - 1); uint64_t hmask = ~(hstep - 1);
int64_t mid; uint64_t mid;
int idx; int idx;
mid = info->start & hmask; mid = info->start & hmask;
@ -483,14 +490,14 @@ static DWORD WINAPI searchAll48Thread(LPVOID data)
{ {
if (info->fp) if (info->fp)
{ {
fprintf(info->fp, "%" PRId64"\n", seed); fprintf(info->fp, "%" PRId64"\n", (int64_t)seed);
fflush(info->fp); fflush(info->fp);
} }
else else
{ {
lp->seeds[lp->len] = seed; lp->seeds[lp->len] = seed;
lp->len++; lp->len++;
if (lp->len >= sizeof(lp->seeds)/sizeof(int64_t)) if (lp->len >= sizeof(lp->seeds)/sizeof(uint64_t))
{ {
linked_seeds_t *n = linked_seeds_t *n =
(linked_seeds_t*) malloc(sizeof(linked_seeds_t)); (linked_seeds_t*) malloc(sizeof(linked_seeds_t));
@ -522,14 +529,14 @@ static DWORD WINAPI searchAll48Thread(LPVOID data)
{ {
if (info->fp) if (info->fp)
{ {
fprintf(info->fp, "%" PRId64"\n", seed); fprintf(info->fp, "%" PRId64"\n", (int64_t)seed);
fflush(info->fp); fflush(info->fp);
} }
else else
{ {
lp->seeds[lp->len] = seed; lp->seeds[lp->len] = seed;
lp->len++; lp->len++;
if (lp->len >= sizeof(lp->seeds)/sizeof(int64_t)) if (lp->len >= sizeof(lp->seeds)/sizeof(uint64_t))
{ {
linked_seeds_t *n = linked_seeds_t *n =
(linked_seeds_t*) malloc(sizeof(linked_seeds_t)); (linked_seeds_t*) malloc(sizeof(linked_seeds_t));
@ -554,14 +561,14 @@ static DWORD WINAPI searchAll48Thread(LPVOID data)
int searchAll48( int searchAll48(
int64_t ** seedbuf, uint64_t ** seedbuf,
int64_t * buflen, uint64_t * buflen,
const char * path, const char * path,
int threads, int threads,
const int64_t * lowBits, const uint64_t * lowBits,
int lowBitCnt, int lowBitCnt,
int lowBitN, int lowBitN,
int (*check)(int64_t s48, void *data), int (*check)(uint64_t s48, void *data),
void * data void * data
) )
{ {
@ -725,7 +732,7 @@ int searchAll48(
while (lp); while (lp);
} }
*seedbuf = (int64_t*) malloc((*buflen) * sizeof(int64_t)); *seedbuf = (uint64_t*) malloc((*buflen) * sizeof(uint64_t));
if (*seedbuf == NULL) if (*seedbuf == NULL)
exit(1); exit(1);
@ -735,7 +742,7 @@ int searchAll48(
linked_seeds_t *lp = &info[t].ls; linked_seeds_t *lp = &info[t].ls;
do do
{ {
memcpy(*seedbuf + i, lp->seeds, lp->len * sizeof(int64_t)); memcpy(*seedbuf + i, lp->seeds, lp->len * sizeof(uint64_t));
i += lp->len; i += lp->len;
linked_seeds_t *tmp = lp; linked_seeds_t *tmp = lp;
lp = lp->next; lp = lp->next;
@ -757,12 +764,12 @@ L_err:
} }
static inline static inline
int scanForQuadBits(const StructureConfig sconf, int radius, int64_t s48, int scanForQuadBits(const StructureConfig sconf, int radius, uint64_t s48,
int64_t lbit, int lbitn, int64_t invB, int64_t x, int64_t z, uint64_t lbit, int lbitn, uint64_t invB, int64_t x, int64_t z,
int64_t w, int64_t h, Pos *qplist, int n) int64_t w, int64_t h, Pos *qplist, int n)
{ {
const int64_t m = (1LL << lbitn); const uint64_t m = (1ULL << lbitn);
const int64_t A = 341873128712LL; const uint64_t A = 341873128712ULL;
// for lbitn=20: invB = 132477LL; // for lbitn=20: invB = 132477LL;
if (n < 1) if (n < 1)
@ -773,13 +780,13 @@ int scanForQuadBits(const StructureConfig sconf, int radius, int64_t s48,
int cnt = 0; int cnt = 0;
for (i = x; i <= x+w; i++) for (i = x; i <= x+w; i++)
{ {
int64_t sx = s48 + A * i; uint64_t sx = s48 + A * i;
j = (z & ~(m-1)) | ((lbit - sx) * invB & (m-1)); j = (z & ~(m-1)) | ((lbit - sx) * invB & (m-1));
if (j < z) if (j < z)
j += m; j += m;
for (; j <= z+h; j += m) for (; j <= z+h; j += m)
{ {
int64_t sp = moveStructure(s48, -i, -j); uint64_t sp = moveStructure(s48, -i, -j);
if ((sp & (m-1)) != lbit) if ((sp & (m-1)) != lbit)
continue; continue;
@ -798,18 +805,18 @@ int scanForQuadBits(const StructureConfig sconf, int radius, int64_t s48,
} }
int scanForQuads( int scanForQuads(
const StructureConfig sconf, int radius, int64_t s48, const StructureConfig sconf, int radius, uint64_t s48,
const int64_t *lowBits, int lowBitCnt, int lowBitN, int64_t salt, const uint64_t *lowBits, int lowBitCnt, int lowBitN, uint64_t salt,
int x, int z, int w, int h, Pos *qplist, int n) int x, int z, int w, int h, Pos *qplist, int n)
{ {
int i, cnt = 0; int i, cnt = 0;
int64_t invB; uint64_t invB;
if (lowBitN == 20) if (lowBitN == 20)
invB = 132477LL; invB = 132477ULL;
else if (lowBitN == 48) else if (lowBitN == 48)
invB = 211541297333629LL; invB = 211541297333629ULL;
else else
invB = mulInv(132897987541LL, (1LL << lowBitN)); invB = mulInv(132897987541ULL, (1ULL << lowBitN));
for (i = 0; i < lowBitCnt; i++) for (i = 0; i < lowBitCnt; i++)
{ {
@ -846,7 +853,7 @@ Pos findBiomePosition(
const int centerZ, const int centerZ,
const int range, const int range,
const char *isValid, const char *isValid,
int64_t *seed, uint64_t *seed,
int *passes int *passes
) )
{ {
@ -1009,10 +1016,10 @@ const char* getValidStrongholdBiomes(int mc)
} }
} }
Pos initFirstStronghold(StrongholdIter *sh, int mc, int64_t s48) Pos initFirstStronghold(StrongholdIter *sh, int mc, uint64_t s48)
{ {
double dist, angle; double dist, angle;
int64_t rnds; uint64_t rnds;
Pos p; Pos p;
setSeed(&rnds, s48); setSeed(&rnds, s48);
@ -1080,7 +1087,7 @@ int nextStronghold(StrongholdIter *sh, const LayerStack *g, int *cache)
} }
int findStrongholds(const int mc, const LayerStack *g, int *cache, int findStrongholds(const int mc, const LayerStack *g, int *cache,
Pos *locations, int64_t worldSeed, int maxSH, int maxRing) Pos *locations, uint64_t worldSeed, int maxSH, int maxRing)
{ {
const char *validStrongholdBiomes = getValidStrongholdBiomes(mc); const char *validStrongholdBiomes = getValidStrongholdBiomes(mc);
int i, x, z; int i, x, z;
@ -1089,7 +1096,7 @@ int findStrongholds(const int mc, const LayerStack *g, int *cache,
int currentRing = 0; int currentRing = 0;
int currentCount = 0; int currentCount = 0;
int perRing = 3; int perRing = 3;
int64_t rnd; uint64_t rnd;
setSeed(&rnd, worldSeed); setSeed(&rnd, worldSeed);
double angle = nextDouble(&rnd) * PI * 2.0; double angle = nextDouble(&rnd) * PI * 2.0;
@ -1156,7 +1163,7 @@ int findStrongholds(const int mc, const LayerStack *g, int *cache,
} }
static double getGrassProbability(int64_t seed, int biome, int x, int z) static double getGrassProbability(uint64_t seed, int biome, int x, int z)
{ {
(void) seed, (void) biome, (void) x, (void) z; (void) seed, (void) biome, (void) x, (void) z;
// TODO: Use ChunkGeneratorOverworld.generateHeightmap for better estimate. // TODO: Use ChunkGeneratorOverworld.generateHeightmap for better estimate.
@ -1230,7 +1237,7 @@ static const char* getValidSpawnBiomes()
} }
Pos getSpawn(const int mcversion, const LayerStack *g, int *cache, int64_t worldSeed) Pos getSpawn(const int mcversion, const LayerStack *g, int *cache, uint64_t worldSeed)
{ {
const char *isSpawnBiome = getValidSpawnBiomes(); const char *isSpawnBiome = getValidSpawnBiomes();
Pos spawn; Pos spawn;
@ -1238,7 +1245,7 @@ Pos getSpawn(const int mcversion, const LayerStack *g, int *cache, int64_t world
int i; int i;
const Layer *l = &g->layers[L_RIVER_MIX_4]; const Layer *l = &g->layers[L_RIVER_MIX_4];
int64_t rnd; uint64_t rnd;
setSeed(&rnd, worldSeed); setSeed(&rnd, worldSeed);
spawn = findBiomePosition(mcversion, l, cache, 0, 0, 256, isSpawnBiome, spawn = findBiomePosition(mcversion, l, cache, 0, 0, 256, isSpawnBiome,
@ -1340,14 +1347,14 @@ Pos getSpawn(const int mcversion, const LayerStack *g, int *cache, int64_t world
} }
Pos estimateSpawn(const int mcversion, const LayerStack *g, int *cache, int64_t worldSeed) Pos estimateSpawn(const int mcversion, const LayerStack *g, int *cache, uint64_t worldSeed)
{ {
const char *isSpawnBiome = getValidSpawnBiomes(); const char *isSpawnBiome = getValidSpawnBiomes();
Pos spawn; Pos spawn;
int found; int found;
const Layer *l = &g->layers[L_RIVER_MIX_4]; const Layer *l = &g->layers[L_RIVER_MIX_4];
int64_t rnd; uint64_t rnd;
setSeed(&rnd, worldSeed); setSeed(&rnd, worldSeed);
spawn = findBiomePosition(mcversion, l, cache, 0, 0, 256, isSpawnBiome, spawn = findBiomePosition(mcversion, l, cache, 0, 0, 256, isSpawnBiome,
&rnd, &found); &rnd, &found);
@ -1595,7 +1602,7 @@ static int mapViableShore(const Layer * l, int * out, int x, int z, int w, int h
int isViableStructurePos(int structureType, int mc, LayerStack *g, int isViableStructurePos(int structureType, int mc, LayerStack *g,
int64_t seed, int blockX, int blockZ) uint64_t seed, int blockX, int blockZ)
{ {
int *ids = NULL; int *ids = NULL;
Layer *l; Layer *l;
@ -1671,7 +1678,7 @@ L_feature:
{ {
if (mc < MC_1_14) if (mc < MC_1_14)
goto L_not_viable; goto L_not_viable;
int64_t rnd = seed; uint64_t rnd = seed;
setAttemptSeed(&rnd, chunkX, chunkZ); setAttemptSeed(&rnd, chunkX, chunkZ);
if (nextInt(&rnd, 5) != 0) if (nextInt(&rnd, 5) != 0)
goto L_not_viable; goto L_not_viable;
@ -1787,7 +1794,7 @@ L_not_viable:
} }
int isViableNetherStructurePos(int structureType, int mc, NetherNoise *nn, int isViableNetherStructurePos(int structureType, int mc, NetherNoise *nn,
int64_t seed, int blockX, int blockZ) uint64_t seed, int blockX, int blockZ)
{ {
if (structureType == Fortress) if (structureType == Fortress)
return 1; // fortresses generate in all nether biomes and mc versions return 1; // fortresses generate in all nether biomes and mc versions
@ -1802,7 +1809,7 @@ int isViableNetherStructurePos(int structureType, int mc, NetherNoise *nn,
} }
int isViableEndStructurePos(int structureType, int mc, EndNoise *en, int isViableEndStructurePos(int structureType, int mc, EndNoise *en,
int64_t seed, int blockX, int blockZ) uint64_t seed, int blockX, int blockZ)
{ {
if (structureType != End_City || mc < MC_1_9) if (structureType != End_City || mc < MC_1_9)
return 0; return 0;
@ -1852,8 +1859,8 @@ int isViableEndCityTerrain(const EndNoise *en, const SurfaceNoise *sn,
h00 = getSurfaceHeight(ncol[0][0], ncol[0][1], ncol[1][0], ncol[1][1], h00 = getSurfaceHeight(ncol[0][0], ncol[0][1], ncol[1][0], ncol[1][1],
y0, y1, 4, (blockX & 7) / 8.0, (blockZ & 7) / 8.0); y0, y1, 4, (blockX & 7) / 8.0, (blockZ & 7) / 8.0);
int64_t cs; uint64_t cs;
setSeed(&cs, chunkX + chunkZ * 10387313LL); setSeed(&cs, chunkX + chunkZ * 10387313ULL);
switch (nextInt(&cs, 4)) switch (nextInt(&cs, 4))
{ {
case 0: // (++) 0 case 0: // (++) 0
@ -1917,13 +1924,13 @@ int isViableEndCityTerrain(const EndNoise *en, const SurfaceNoise *sn,
//============================================================================== //==============================================================================
VillageType getVillageType(int mc, int64_t seed, int blockX, int blockZ, int biomeID) VillageType getVillageType(int mc, uint64_t seed, int blockX, int blockZ, int biomeID)
{ {
VillageType r = { 0, 0, 0 }; VillageType r = { 0, 0, 0 };
if (!isViableFeatureBiome(mc, Village, biomeID)) if (!isViableFeatureBiome(mc, Village, biomeID))
return r; return r;
int64_t rnd = chunkGenerateRnd(seed, blockX >> 4, blockZ >> 4); uint64_t rnd = chunkGenerateRnd(seed, blockX >> 4, blockZ >> 4);
r.biome = biomeID; r.biome = biomeID;
@ -1994,10 +2001,10 @@ VillageType getVillageType(int mc, int64_t seed, int blockX, int blockZ, int bio
} }
int64_t getHouseList(const int64_t worldSeed, const int chunkX, const int chunkZ, uint64_t getHouseList(uint64_t worldSeed, int chunkX, int chunkZ,
int *out) int *out)
{ {
int64_t rnd = chunkGenerateRnd(worldSeed, chunkX, chunkZ); uint64_t rnd = chunkGenerateRnd(worldSeed, chunkX, chunkZ);
skipNextN(&rnd, 1); skipNextN(&rnd, 1);
out[HouseSmall] = nextInt(&rnd, 4 - 2 + 1) + 2; out[HouseSmall] = nextInt(&rnd, 4 - 2 + 1) + 2;
@ -2304,8 +2311,8 @@ static int mapFilterSpecial(const Layer * l, int * out, int x, int z, int w, int
int specialcnt = f->bf->specialCnt; int specialcnt = f->bf->specialCnt;
if (specialcnt > 0) if (specialcnt > 0)
{ {
int64_t ss = l->startSeed; uint64_t ss = l->startSeed;
int64_t cs; uint64_t cs;
for (j = 0; j < h; j++) for (j = 0; j < h; j++)
{ {
@ -2353,8 +2360,8 @@ static int mapFilterMushroom(const Layer * l, int * out, int x, int z, int w, in
if (w*h < 100 && (f->bf->majorToFind & (1ULL << mushroom_fields))) if (w*h < 100 && (f->bf->majorToFind & (1ULL << mushroom_fields)))
{ {
int64_t ss = l->startSeed; uint64_t ss = l->startSeed;
int64_t cs; uint64_t cs;
for (j = 0; j < h; j++) for (j = 0; j < h; j++)
{ {
@ -2579,7 +2586,7 @@ int checkForBiomes(
LayerStack * g, LayerStack * g,
int layerID, int layerID,
int * cache, int * cache,
int64_t seed, uint64_t seed,
int x, int x,
int z, int z,
unsigned int w, unsigned int w,
@ -2600,7 +2607,7 @@ int checkForBiomes(
int bw = w * l->scale; int bw = w * l->scale;
int bh = h * l->scale; int bh = h * l->scale;
int x0, z0, x1, z1; int x0, z0, x1, z1;
int64_t ss, cs; uint64_t ss, cs;
uint64_t potential, required; uint64_t potential, required;
int specialcnt = filter.specialCnt; int specialcnt = filter.specialCnt;
@ -2742,10 +2749,10 @@ L_HAS_PROTO_MUSHROOM:
} }
int checkForTemps(LayerStack *g, int64_t seed, int x, int z, int w, int h, const int tc[9]) int checkForTemps(LayerStack *g, uint64_t seed, int x, int z, int w, int h, const int tc[9])
{ {
int64_t ls = getLayerSalt(3); // L_SPECIAL_1024 layer seed uint64_t ls = getLayerSalt(3); // L_SPECIAL_1024 layer seed
int64_t ss = getStartSeed(seed, ls); uint64_t ss = getStartSeed(seed, ls);
int i, j; int i, j;
int scnt = 0; int scnt = 0;
@ -2865,15 +2872,10 @@ int canBiomeGenerate(int layerId, int mc, int id)
if (dofilter || layerId == L_RIVER_MIX_4) if (dofilter || layerId == L_RIVER_MIX_4)
{ {
dofilter = 1; dofilter = 1;
switch (id) if (id == frozen_ocean && mc >= MC_1_7)
{ return 0;
case frozen_ocean: if (isDeepOcean(id) && id != deep_ocean)
if (mc >= MC_1_7)
return 0;
break;
case warm_ocean...deep_frozen_ocean:
return 0; return 0;
}
} }
if (dofilter || (layerId == L_OCEAN_MIX_4 && mc >= MC_1_13)) if (dofilter || (layerId == L_OCEAN_MIX_4 && mc >= MC_1_13))
{ {

197
finders.h
View File

@ -135,7 +135,7 @@ STRUCT(StrongholdIter)
int ringidx; // index within ring int ringidx; // index within ring
double angle; // next angle within ring double angle; // next angle within ring
double dist; // next distance from origin (in chunks) double dist; // next distance from origin (in chunks)
int64_t rnds; // random number seed (48 bit) uint64_t rnds; // random number seed (48 bit)
int mc; // minecraft version int mc; // minecraft version
}; };
@ -201,13 +201,13 @@ STRUCT(VillageType)
// lower 20 bits, only the very best constellations // lower 20 bits, only the very best constellations
// (the structure salt has to be subtracted before use) // (the structure salt has to be subtracted before use)
static const int64_t low20QuadIdeal[] = static const uint64_t low20QuadIdeal[] =
{ {
0x43f18,0xc751a,0xf520a, 0x43f18,0xc751a,0xf520a,
}; };
// lower 20 bits, the classic quad-structure constellations // lower 20 bits, the classic quad-structure constellations
static const int64_t low20QuadClassic[] = static const uint64_t low20QuadClassic[] =
{ {
0x43f18,0x79a0a,0xc751a,0xf520a, 0x43f18,0x79a0a,0xc751a,0xf520a,
}; };
@ -215,7 +215,7 @@ static const int64_t low20QuadClassic[] =
// for any valid quad-structure constellation with a structure size: // for any valid quad-structure constellation with a structure size:
// (7+1,7+43+1,9+1) which corresponds to a fall-damage based quad-witch-farm, // (7+1,7+43+1,9+1) which corresponds to a fall-damage based quad-witch-farm,
// but may require a perfect player position // but may require a perfect player position
static const int64_t low20QuadHutNormal[] = static const uint64_t low20QuadHutNormal[] =
{ {
0x43f18,0x65118,0x75618,0x79a0a, 0x89718,0x9371a,0xa5a08,0xb5e18, 0x43f18,0x65118,0x75618,0x79a0a, 0x89718,0x9371a,0xa5a08,0xb5e18,
0xc751a,0xf520a, 0xc751a,0xf520a,
@ -223,7 +223,7 @@ static const int64_t low20QuadHutNormal[] =
// for any valid quad-structure constellation with a structure size: // for any valid quad-structure constellation with a structure size:
// (7+1,7+1,9+1) which corresponds to quad-witch-farms without drop chute // (7+1,7+1,9+1) which corresponds to quad-witch-farms without drop chute
static const int64_t low20QuadHutBarely[] = static const uint64_t low20QuadHutBarely[] =
{ {
0x1272d,0x17908,0x367b9,0x43f18, 0x487c9,0x487ce,0x50aa7,0x647b5, 0x1272d,0x17908,0x367b9,0x43f18, 0x487c9,0x487ce,0x50aa7,0x647b5,
0x65118,0x75618,0x79a0a,0x89718, 0x9371a,0x967ec,0xa3d0a,0xa5918, 0x65118,0x75618,0x79a0a,0x89718, 0x9371a,0x967ec,0xa3d0a,0xa5918,
@ -238,8 +238,7 @@ static const int64_t low20QuadHutBarely[] =
/* Transposes a base seed such that structures are moved by the specified region /* Transposes a base seed such that structures are moved by the specified region
* vector, (regX, regZ). * vector, (regX, regZ).
*/ */
static inline int64_t moveStructure(const int64_t baseSeed, static inline uint64_t moveStructure(uint64_t baseSeed, int regX, int regZ)
const int regX, const int regZ)
{ {
return (baseSeed - regX*341873128712 - regZ*132897987541) & 0xffffffffffff; return (baseSeed - regX*341873128712 - regZ*132897987541) & 0xffffffffffff;
} }
@ -258,7 +257,7 @@ static inline int64_t moveStructure(const int64_t baseSeed,
* *
* Return a pointer to a dynamically allocated seed list. * Return a pointer to a dynamically allocated seed list.
*/ */
int64_t *loadSavedSeeds(const char *fnam, int64_t *scnt); uint64_t *loadSavedSeeds(const char *fnam, uint64_t *scnt);
@ -296,7 +295,7 @@ int getStructureConfig_override(int stype, int mc, StructureConfig *sconf);
* *
* Returns zero if the position is invalid, or non-zero otherwise. * Returns zero if the position is invalid, or non-zero otherwise.
*/ */
int getStructurePos(int structureType, int mc, int64_t seed, int regX, int regZ, Pos *pos); int getStructurePos(int structureType, int mc, uint64_t seed, int regX, int regZ, Pos *pos);
/* The inline functions below get the generation attempt position given a /* The inline functions below get the generation attempt position given a
* structure configuration. Most small structures use the getFeature.. * structure configuration. Most small structures use the getFeature..
@ -304,33 +303,33 @@ int getStructurePos(int structureType, int mc, int64_t seed, int regX, int regZ,
* (monuments and mansions) have a triangular distribution. * (monuments and mansions) have a triangular distribution.
*/ */
static inline __attribute__((const)) static inline __attribute__((const))
Pos getFeaturePos(StructureConfig config, int64_t seed, int regX, int regZ); Pos getFeaturePos(StructureConfig config, uint64_t seed, int regX, int regZ);
static inline __attribute__((const)) static inline __attribute__((const))
Pos getFeatureChunkInRegion(StructureConfig config, int64_t seed, int regX, int regZ); Pos getFeatureChunkInRegion(StructureConfig config, uint64_t seed, int regX, int regZ);
static inline __attribute__((const)) static inline __attribute__((const))
Pos getLargeStructurePos(StructureConfig config, int64_t seed, int regX, int regZ); Pos getLargeStructurePos(StructureConfig config, uint64_t seed, int regX, int regZ);
static inline __attribute__((const)) static inline __attribute__((const))
Pos getLargeStructureChunkInRegion(StructureConfig config, int64_t seed, int regX, int regZ); Pos getLargeStructureChunkInRegion(StructureConfig config, uint64_t seed, int regX, int regZ);
/* Some structures check each chunk individually for viability. /* Some structures check each chunk individually for viability.
* The placement and biome check within a valid chunk is at block position (9,9) * The placement and biome check within a valid chunk is at block position (9,9)
* or at (2,2) with layer scale=4 from 1.16 onwards. * or at (2,2) with layer scale=4 from 1.16 onwards.
*/ */
int isMineshaftChunk(int64_t seed, int chunkX, int chunkZ); int isMineshaftChunk(uint64_t seed, int chunkX, int chunkZ);
// not exacly a structure // not exacly a structure
static inline __attribute__((const)) static inline __attribute__((const))
int isSlimeChunk(int64_t seed, int chunkX, int chunkZ) int isSlimeChunk(uint64_t seed, int chunkX, int chunkZ)
{ {
int64_t rnd = seed; uint64_t rnd = seed;
rnd += (int)(chunkX * 0x5ac0db); rnd += (int)(chunkX * 0x5ac0db);
rnd += (int)(chunkX * chunkX * 0x4c1906); rnd += (int)(chunkX * chunkX * 0x4c1906);
rnd += (int)(chunkZ * 0x5f24f); rnd += (int)(chunkZ * 0x5f24f);
rnd += (int)(chunkZ * chunkZ) * 0x4307a7LL; rnd += (int)(chunkZ * chunkZ) * 0x4307a7ULL;
rnd ^= 0x3ad8025fLL; rnd ^= 0x3ad8025fULL;
setSeed(&rnd, rnd); setSeed(&rnd, rnd);
return nextInt(&rnd, 10) == 0; return nextInt(&rnd, 10) == 0;
} }
@ -358,7 +357,7 @@ int isSlimeChunk(int64_t seed, int chunkX, int chunkZ)
* radius of the enclosing sphere if it is, and can be used as a measure of * radius of the enclosing sphere if it is, and can be used as a measure of
* quality for the quad-base (smaller is better). * quality for the quad-base (smaller is better).
*/ */
static inline float isQuadBase(const StructureConfig sconf, int64_t seed, int radius); static inline float isQuadBase(const StructureConfig sconf, uint64_t seed, int radius);
/* Determines if the specified seed qualifies as a quad-base, given a required /* Determines if the specified seed qualifies as a quad-base, given a required
* structure size. The structure size should include the actual dimensions of * structure size. The structure size should include the actual dimensions of
@ -389,18 +388,18 @@ static inline float isQuadBase(const StructureConfig sconf, int64_t seed, int ra
* so quickly that the function call is a major contributor to the overall time. * so quickly that the function call is a major contributor to the overall time.
*/ */
static inline __attribute__((always_inline, const)) static inline __attribute__((always_inline, const))
float isQuadBaseFeature24Classic (const StructureConfig sconf, int64_t seed); float isQuadBaseFeature24Classic (const StructureConfig sconf, uint64_t seed);
static inline __attribute__((always_inline, const)) static inline __attribute__((always_inline, const))
float isQuadBaseFeature24 (const StructureConfig sconf, int64_t seed, float isQuadBaseFeature24 (const StructureConfig sconf, uint64_t seed,
int ax, int ay, int az); int ax, int ay, int az);
static inline __attribute__((always_inline, const)) static inline __attribute__((always_inline, const))
float isQuadBaseFeature (const StructureConfig sconf, int64_t seed, float isQuadBaseFeature (const StructureConfig sconf, uint64_t seed,
int ax, int ay, int az, int radius); int ax, int ay, int az, int radius);
static inline __attribute__((always_inline, const)) static inline __attribute__((always_inline, const))
float isQuadBaseLarge (const StructureConfig sconf, int64_t seed, float isQuadBaseLarge (const StructureConfig sconf, uint64_t seed,
int ax, int ay, int az, int radius); int ax, int ay, int az, int radius);
@ -425,14 +424,14 @@ float isQuadBaseLarge (const StructureConfig sconf, int64_t seed,
* Returns zero upon success. * Returns zero upon success.
*/ */
int searchAll48( int searchAll48(
int64_t ** seedbuf, uint64_t ** seedbuf,
int64_t * buflen, uint64_t * buflen,
const char * path, const char * path,
int threads, int threads,
const int64_t * lowBits, const uint64_t * lowBits,
int lowBitCnt, int lowBitCnt,
int lowBitN, int lowBitN,
int (*check)(int64_t s48, void *data), int (*check)(uint64_t s48, void *data),
void * data void * data
); );
@ -472,8 +471,8 @@ Pos getOptimalAfk(Pos p[4], int ax, int ay, int az, int *spcnt);
* Returns the number of quad-structures found (up to 'n'). * Returns the number of quad-structures found (up to 'n').
*/ */
int scanForQuads( int scanForQuads(
const StructureConfig sconf, int radius, int64_t s48, const StructureConfig sconf, int radius, uint64_t s48,
const int64_t *lowBits, int lowBitCnt, int lowBitN, int64_t salt, const uint64_t *lowBits, int lowBitCnt, int lowBitN, uint64_t salt,
int x, int z, int w, int h, Pos *qplist, int n); int x, int z, int w, int h, Pos *qplist, int n);
//============================================================================== //==============================================================================
@ -487,7 +486,7 @@ int getBiomeAtPos(const LayerStack *g, const Pos pos);
/* Get the shadow seed. /* Get the shadow seed.
*/ */
static inline int64_t getShadow(int64_t seed) static inline uint64_t getShadow(uint64_t seed)
{ {
return -7379792620528906219LL - seed; return -7379792620528906219LL - seed;
} }
@ -514,7 +513,7 @@ Pos findBiomePosition(
const int centerZ, const int centerZ,
const int range, const int range,
const char * isValid, const char * isValid,
int64_t * seed, uint64_t * seed,
int * passes int * passes
); );
@ -555,7 +554,7 @@ int areBiomesViable(
* *
* Returns the approximate block position of the first stronghold. * Returns the approximate block position of the first stronghold.
*/ */
Pos initFirstStronghold(StrongholdIter *sh, int mc, int64_t s48); Pos initFirstStronghold(StrongholdIter *sh, int mc, uint64_t s48);
/* Performs the biome checks for the stronghold iterator and finds its accurate /* Performs the biome checks for the stronghold iterator and finds its accurate
* location, as well as the approximate location of the next stronghold. * location, as well as the approximate location of the next stronghold.
@ -590,7 +589,7 @@ int findStrongholds(
const LayerStack * g, const LayerStack * g,
int * cache, int * cache,
Pos * locations, Pos * locations,
int64_t worldSeed, uint64_t worldSeed,
int maxSH, int maxSH,
int maxRing int maxRing
); );
@ -604,7 +603,7 @@ int findStrongholds(
* @cache : biome buffer, set to NULL for temporary allocation * @cache : biome buffer, set to NULL for temporary allocation
* @worldSeed : world seed used for the generator * @worldSeed : world seed used for the generator
*/ */
Pos getSpawn(const int mc, const LayerStack *g, int *cache, int64_t worldSeed); Pos getSpawn(const int mc, const LayerStack *g, int *cache, uint64_t worldSeed);
/* Finds the approximate spawn point in the world. /* Finds the approximate spawn point in the world.
* *
@ -613,7 +612,7 @@ Pos getSpawn(const int mc, const LayerStack *g, int *cache, int64_t worldSeed);
* @cache : biome buffer, set to NULL for temporary allocation * @cache : biome buffer, set to NULL for temporary allocation
* @worldSeed : world seed used for the generator * @worldSeed : world seed used for the generator
*/ */
Pos estimateSpawn(const int mc, const LayerStack *g, int *cache, int64_t worldSeed); Pos estimateSpawn(const int mc, const LayerStack *g, int *cache, uint64_t worldSeed);
//============================================================================== //==============================================================================
@ -634,11 +633,11 @@ Pos estimateSpawn(const int mc, const LayerStack *g, int *cache, int64_t worldSe
* The return value is non-zero if the position is valid. * The return value is non-zero if the position is valid.
*/ */
int isViableStructurePos(int structureType, int mc, LayerStack *g, int isViableStructurePos(int structureType, int mc, LayerStack *g,
int64_t seed, int blockX, int blockZ); uint64_t seed, int blockX, int blockZ);
int isViableNetherStructurePos(int structureType, int mc, NetherNoise *nn, int isViableNetherStructurePos(int structureType, int mc, NetherNoise *nn,
int64_t seed, int blockX, int blockZ); uint64_t seed, int blockX, int blockZ);
int isViableEndStructurePos(int structureType, int mc, EndNoise *en, int isViableEndStructurePos(int structureType, int mc, EndNoise *en,
int64_t seed, int blockX, int blockZ); uint64_t seed, int blockX, int blockZ);
/* Checks if the specified structure type could generate in the given biome. /* Checks if the specified structure type could generate in the given biome.
*/ */
@ -659,17 +658,17 @@ int isViableEndCityTerrain(const EndNoise *en, const SurfaceNoise *sn,
* This random object is used for recursiveGenerate() which is responsible for * This random object is used for recursiveGenerate() which is responsible for
* generating caves, ravines, mineshafts, and virtually all other structures. * generating caves, ravines, mineshafts, and virtually all other structures.
*/ */
inline static int64_t chunkGenerateRnd(const int64_t worldSeed, inline static int64_t chunkGenerateRnd(const uint64_t worldSeed,
const int chunkX, const int chunkZ) const int chunkX, const int chunkZ)
{ {
int64_t rnd; uint64_t rnd;
setSeed(&rnd, worldSeed); setSeed(&rnd, worldSeed);
rnd = (nextLong(&rnd) * chunkX) ^ (nextLong(&rnd) * chunkZ) ^ worldSeed; rnd = (nextLong(&rnd) * chunkX) ^ (nextLong(&rnd) * chunkZ) ^ worldSeed;
setSeed(&rnd, rnd); setSeed(&rnd, rnd);
return rnd; return rnd;
} }
VillageType getVillageType(int mc, int64_t seed, int blockX, int blockZ, int biomeID); VillageType getVillageType(int mc, uint64_t seed, int blockX, int blockZ, int biomeID);
/* Finds the number of each type of house that generate in a village /* Finds the number of each type of house that generate in a village
@ -681,8 +680,7 @@ VillageType getVillageType(int mc, int64_t seed, int blockX, int blockZ, int bio
* *
* Returns the random object seed after finding these numbers. * Returns the random object seed after finding these numbers.
*/ */
int64_t getHouseList(const int64_t worldSeed, const int chunkX, const int chunkZ, uint64_t getHouseList(uint64_t worldSeed, int chunkX, int chunkZ, int *housesOut);
int *housesOut);
//============================================================================== //==============================================================================
@ -713,7 +711,7 @@ int checkForBiomes(
LayerStack * g, LayerStack * g,
int layerID, int layerID,
int * cache, int * cache,
int64_t seed, uint64_t seed,
int x, int x,
int z, int z,
unsigned int w, unsigned int w,
@ -730,7 +728,7 @@ int checkForBiomes(
* Oceanic, Warm, Lush, Cold, Freeing, Special+Warm, Special+Lush, Special+Cold * Oceanic, Warm, Lush, Cold, Freeing, Special+Warm, Special+Lush, Special+Cold
* For 1.7+ only. * For 1.7+ only.
*/ */
int checkForTemps(LayerStack *g, int64_t seed, int x, int z, int w, int h, const int tc[9]); int checkForTemps(LayerStack *g, uint64_t seed, int x, int z, int w, int h, const int tc[9]);
/* Checks if a biome may generate given a version and layer ID as entry point. /* Checks if a biome may generate given a version and layer ID as entry point.
* The supported layers are: * The supported layers are:
@ -753,7 +751,7 @@ void genPotential(uint64_t *mL, uint64_t *mM, int layer, int mc, int id);
static inline __attribute__((const)) static inline __attribute__((const))
Pos getFeatureChunkInRegion(StructureConfig config, int64_t seed, int regX, int regZ) Pos getFeatureChunkInRegion(StructureConfig config, uint64_t seed, int regX, int regZ)
{ {
/* /*
// Vanilla like implementation. // Vanilla like implementation.
@ -764,54 +762,55 @@ Pos getFeatureChunkInRegion(StructureConfig config, int64_t seed, int regX, int
pos.z = nextInt(&seed, 24); pos.z = nextInt(&seed, 24);
*/ */
Pos pos; Pos pos;
const int64_t K = 0x5deece66dLL; const uint64_t K = 0x5deece66dULL;
const int64_t M = (1ULL << 48) - 1; const uint64_t M = (1ULL << 48) - 1;
const int64_t b = 0xb; const uint64_t b = 0xb;
// set seed // set seed
seed = seed + regX*341873128712 + regZ*132897987541 + config.salt; seed = seed + regX*341873128712ULL + regZ*132897987541ULL + config.salt;
seed = (seed ^ K); seed = (seed ^ K);
seed = (seed * K + b) & M; seed = (seed * K + b) & M;
if (config.chunkRange & (config.chunkRange-1)) uint64_t r = config.chunkRange;
if (r & (r-1))
{ {
pos.x = (int)(seed >> 17) % config.chunkRange; pos.x = (int)(seed >> 17) % r;
seed = (seed * K + b) & M; seed = (seed * K + b) & M;
pos.z = (int)(seed >> 17) % config.chunkRange; pos.z = (int)(seed >> 17) % r;
} }
else else
{ {
// Java RNG treats powers of 2 as a special case. // Java RNG treats powers of 2 as a special case.
pos.x = (config.chunkRange * (seed >> 17)) >> 31; pos.x = (int)((r * (seed >> 17)) >> 31);
seed = (seed * K + b) & M; seed = (seed * K + b) & M;
pos.z = (config.chunkRange * (seed >> 17)) >> 31; pos.z = (int)((r * (seed >> 17)) >> 31);
} }
return pos; return pos;
} }
static inline __attribute__((const)) static inline __attribute__((const))
Pos getFeaturePos(StructureConfig config, int64_t seed, int regX, int regZ) Pos getFeaturePos(StructureConfig config, uint64_t seed, int regX, int regZ)
{ {
Pos pos = getFeatureChunkInRegion(config, seed, regX, regZ); Pos pos = getFeatureChunkInRegion(config, seed, regX, regZ);
pos.x = ((regX*config.regionSize + pos.x) << 4); pos.x = (int)(((uint64_t)regX*config.regionSize + pos.x) << 4);
pos.z = ((regZ*config.regionSize + pos.z) << 4); pos.z = (int)(((uint64_t)regZ*config.regionSize + pos.z) << 4);
return pos; return pos;
} }
static inline __attribute__((const)) static inline __attribute__((const))
Pos getLargeStructureChunkInRegion(StructureConfig config, int64_t seed, int regX, int regZ) Pos getLargeStructureChunkInRegion(StructureConfig config, uint64_t seed, int regX, int regZ)
{ {
Pos pos; Pos pos;
const int64_t K = 0x5deece66dLL; const uint64_t K = 0x5deece66dULL;
const int64_t M = (1ULL << 48) - 1; const uint64_t M = (1ULL << 48) - 1;
const int64_t b = 0xb; const uint64_t b = 0xb;
//TODO: power of two chunk ranges... //TODO: power of two chunk ranges...
// set seed // set seed
seed = seed + regX*341873128712 + regZ*132897987541 + config.salt; seed = seed + regX*341873128712ULL + regZ*132897987541ULL + config.salt;
seed = (seed ^ K); seed = (seed ^ K);
seed = (seed * K + b) & M; seed = (seed * K + b) & M;
@ -831,14 +830,12 @@ Pos getLargeStructureChunkInRegion(StructureConfig config, int64_t seed, int reg
} }
static inline __attribute__((const)) static inline __attribute__((const))
Pos getLargeStructurePos(StructureConfig config, int64_t seed, int regX, int regZ) Pos getLargeStructurePos(StructureConfig config, uint64_t seed, int regX, int regZ)
{ {
Pos pos = getLargeStructureChunkInRegion(config, seed, regX, regZ); Pos pos = getLargeStructureChunkInRegion(config, seed, regX, regZ);
pos.x = regX*config.regionSize + pos.x; pos.x = (int)(((uint64_t)regX*config.regionSize + pos.x) << 4);
pos.z = regZ*config.regionSize + pos.z; pos.z = (int)(((uint64_t)regZ*config.regionSize + pos.z) << 4);
pos.x = pos.x*16;
pos.z = pos.z*16;
return pos; return pos;
} }
@ -888,7 +885,7 @@ float getEnclosingRadius(
} }
static inline float isQuadBase(const StructureConfig sconf, int64_t seed, int radius) static inline float isQuadBase(const StructureConfig sconf, uint64_t seed, int radius)
{ {
switch(sconf.structType) switch(sconf.structType)
{ {
@ -934,13 +931,13 @@ static inline float isQuadBase(const StructureConfig sconf, int64_t seed, int ra
// optimised version for regionSize=32,chunkRange=24,radius=128 // optimised version for regionSize=32,chunkRange=24,radius=128
static inline __attribute__((always_inline, const)) static inline __attribute__((always_inline, const))
float isQuadBaseFeature24(const StructureConfig sconf, int64_t seed, float isQuadBaseFeature24(const StructureConfig sconf, uint64_t seed,
int ax, int ay, int az) int ax, int ay, int az)
{ {
seed += sconf.salt; seed += sconf.salt;
int64_t s00 = seed; uint64_t s00 = seed;
int64_t s11 = 341873128712 + 132897987541 + seed; uint64_t s11 = 341873128712ULL + 132897987541ULL + seed;
const int64_t K = 0x5deece66dLL; const uint64_t K = 0x5deece66dULL;
int x0, z0, x1, z1, x2, z2, x3, z3; int x0, z0, x1, z1, x2, z2, x3, z3;
int x, z; int x, z;
@ -960,8 +957,8 @@ float isQuadBaseFeature24(const StructureConfig sconf, int64_t seed,
if (x*x + z*z > 255) if (x*x + z*z > 255)
return 0; return 0;
int64_t s01 = 341873128712 + seed; uint64_t s01 = 341873128712ULL + seed;
int64_t s10 = 132897987541 + seed; uint64_t s10 = 132897987541ULL + seed;
s01 ^= K; s01 ^= K;
JAVA_NEXT_INT24(s01, x2); if L(x2 >= 4) return 0; JAVA_NEXT_INT24(s01, x2); if L(x2 >= 4) return 0;
@ -986,12 +983,12 @@ float isQuadBaseFeature24(const StructureConfig sconf, int64_t seed,
// variant of isQuadBaseFeature24 which finds only the classic constellations // variant of isQuadBaseFeature24 which finds only the classic constellations
static inline __attribute__((always_inline, const)) static inline __attribute__((always_inline, const))
float isQuadBaseFeature24Classic(const StructureConfig sconf, int64_t seed) float isQuadBaseFeature24Classic(const StructureConfig sconf, uint64_t seed)
{ {
seed += sconf.salt; seed += sconf.salt;
int64_t s00 = seed; uint64_t s00 = seed;
int64_t s11 = 341873128712 + 132897987541 + seed; uint64_t s11 = 341873128712ULL + 132897987541ULL + seed;
const int64_t K = 0x5deece66dLL; const uint64_t K = 0x5deece66dULL;
int p; int p;
// check that the two structures in the opposing diagonal quadrants are // check that the two structures in the opposing diagonal quadrants are
@ -1004,8 +1001,8 @@ float isQuadBaseFeature24Classic(const StructureConfig sconf, int64_t seed)
JAVA_NEXT_INT24(s11, p); if L(p > 1) return 0; JAVA_NEXT_INT24(s11, p); if L(p > 1) return 0;
JAVA_NEXT_INT24(s11, p); if L(p > 1) return 0; JAVA_NEXT_INT24(s11, p); if L(p > 1) return 0;
int64_t s01 = 341873128712 + seed; uint64_t s01 = 341873128712ULL + seed;
int64_t s10 = 132897987541 + seed; uint64_t s10 = 132897987541ULL + seed;
s01 ^= K; s01 ^= K;
JAVA_NEXT_INT24(s01, p); if L(p > 1) return 0; JAVA_NEXT_INT24(s01, p); if L(p > 1) return 0;
@ -1019,15 +1016,15 @@ float isQuadBaseFeature24Classic(const StructureConfig sconf, int64_t seed)
} }
static inline __attribute__((always_inline, const)) static inline __attribute__((always_inline, const))
float isQuadBaseFeature(const StructureConfig sconf, int64_t seed, float isQuadBaseFeature(const StructureConfig sconf, uint64_t seed,
int ax, int ay, int az, int radius) int ax, int ay, int az, int radius)
{ {
seed += sconf.salt; seed += sconf.salt;
int64_t s00 = seed; uint64_t s00 = seed;
int64_t s11 = 341873128712 + 132897987541 + seed; uint64_t s11 = 341873128712ULL + 132897987541ULL + seed;
const int64_t M = (1ULL << 48) - 1; const uint64_t M = (1ULL << 48) - 1;
const int64_t K = 0x5deece66dLL; const uint64_t K = 0x5deece66dULL;
const int64_t b = 0xbLL; const uint64_t b = 0xb;
int x0, z0, x1, z1, x2, z2, x3, z3; int x0, z0, x1, z1, x2, z2, x3, z3;
int x, z; int x, z;
@ -1037,7 +1034,7 @@ float isQuadBaseFeature(const StructureConfig sconf, int64_t seed,
int cd = radius/8; int cd = radius/8;
int rm = R - (int)sqrtf(cd*cd - (R-C+1)*(R-C+1)); int rm = R - (int)sqrtf(cd*cd - (R-C+1)*(R-C+1));
int64_t s; uint64_t s;
s = s00 ^ K; s = s00 ^ K;
s = (s * K + b) & M; x0 = (int)(s >> 17) % C; if L(x0 <= rm) return 0; s = (s * K + b) & M; x0 = (int)(s >> 17) % C; if L(x0 <= rm) return 0;
@ -1055,8 +1052,8 @@ float isQuadBaseFeature(const StructureConfig sconf, int64_t seed,
if L(x*x + z*z > cd*cd) if L(x*x + z*z > cd*cd)
return 0; return 0;
int64_t s01 = 341873128712 + seed; uint64_t s01 = 341873128712ULL + seed;
int64_t s10 = 132897987541 + seed; uint64_t s10 = 132897987541ULL + seed;
s = s01 ^ K; s = s01 ^ K;
s = (s * K + b) & M; x2 = (int)(s >> 17) % C; if L(x2 >= C-rm) return 0; s = (s * K + b) & M; x2 = (int)(s >> 17) % C; if L(x2 >= C-rm) return 0;
@ -1078,29 +1075,29 @@ float isQuadBaseFeature(const StructureConfig sconf, int64_t seed,
static inline __attribute__((always_inline, const)) static inline __attribute__((always_inline, const))
float isQuadBaseLarge(const StructureConfig sconf, int64_t seed, float isQuadBaseLarge(const StructureConfig sconf, uint64_t seed,
int ax, int ay, int az, int radius) int ax, int ay, int az, int radius)
{ {
// Good quad-monument bases are very rare indeed and the search takes much // Good quad-monument bases are very rare indeed and the search takes much
// longer since it cannot be abbreviated by the low-20-bit method. For a // longer since it cannot be abbreviated by the low-20-bit method. For a
// complete list of bases see the implementation of cubiomes-viewer. // complete list of bases see the implementation of cubiomes-viewer.
const int64_t M = (1ULL << 48) - 1; const uint64_t M = (1ULL << 48) - 1;
const int64_t K = 0x5deece66dLL; const uint64_t K = 0x5deece66dULL;
const int64_t b = 0xbLL; const uint64_t b = 0xb;
seed += sconf.salt; seed += sconf.salt;
int64_t s00 = seed; uint64_t s00 = seed;
int64_t s01 = 341873128712 + seed; uint64_t s01 = 341873128712ULL + seed;
int64_t s10 = 132897987541 + seed; uint64_t s10 = 132897987541ULL + seed;
int64_t s11 = 341873128712 + 132897987541 + seed; uint64_t s11 = 341873128712ULL + 132897987541ULL + seed;
// p1 = nextInt(range); p2 = nextInt(range); pos = (p1+p2)>>1 // p1 = nextInt(range); p2 = nextInt(range); pos = (p1+p2)>>1
const int R = sconf.regionSize; const int R = sconf.regionSize;
const int C = sconf.chunkRange; const int C = sconf.chunkRange;
int rm = (int)(2 * R + ((ax<az?ax:az) - 2*radius + 7) / 8); int rm = (int)(2 * R + ((ax<az?ax:az) - 2*radius + 7) / 8);
int64_t s; uint64_t s;
int p; int p;
int x0,z0,x1,z1,x2,z2,x3,z3; int x0,z0,x1,z1,x2,z2,x3,z3;
@ -1121,7 +1118,7 @@ float isQuadBaseLarge(const StructureConfig sconf, int64_t seed,
z1 = p; z1 = p;
s = ((x1-x0)>>1)*((x1-x0)>>1) + ((z1-z0)>>1)*((z1-z0)>>1); s = ((x1-x0)>>1)*((x1-x0)>>1) + ((z1-z0)>>1)*((z1-z0)>>1);
if (s > 4*radius*radius) if (s > (uint64_t)4*radius*radius)
return 0; return 0;
s = s01 ^ K; s = s01 ^ K;

View File

@ -7,7 +7,7 @@
Layer *setupLayer(LayerStack *g, int layerId, mapfunc_t *map, int mc, Layer *setupLayer(LayerStack *g, int layerId, mapfunc_t *map, int mc,
int8_t zoom, int8_t edge, int saltbase, Layer *p, Layer *p2) int8_t zoom, int8_t edge, uint64_t saltbase, Layer *p, Layer *p2)
{ {
Layer *l = g->layers + layerId; Layer *l = g->layers + layerId;
l->getMap = map; l->getMap = map;
@ -15,7 +15,10 @@ Layer *setupLayer(LayerStack *g, int layerId, mapfunc_t *map, int mc,
l->zoom = zoom; l->zoom = zoom;
l->edge = edge; l->edge = edge;
l->scale = 0; l->scale = 0;
l->layerSalt = saltbase > 0 ? getLayerSalt(saltbase) : saltbase; if (saltbase == 0 || saltbase == LAYER_INIT_SHA)
l->layerSalt = saltbase;
else
l->layerSalt = getLayerSalt(saltbase);
l->startSalt = 0; l->startSalt = 0;
l->startSeed = 0; l->startSeed = 0;
l->noise = NULL; l->noise = NULL;
@ -184,7 +187,7 @@ static void setupGeneratorImpl(LayerStack *g, int mc, int largeBiomes)
if (mc <= MC_1_14) if (mc <= MC_1_14)
p = setupLayer(g, L_VORONOI_1, mapVoronoi114, mc, 4, 7, 10, p, 0); p = setupLayer(g, L_VORONOI_1, mapVoronoi114, mc, 4, 7, 10, p, 0);
else else
p = setupLayer(g, L_VORONOI_1, mapVoronoi, mc, 4, 7, -1, p, 0); p = setupLayer(g, L_VORONOI_1, mapVoronoi, mc, 4, 7, LAYER_INIT_SHA, p, 0);
} }
g->entry_1 = p; g->entry_1 = p;
@ -254,7 +257,7 @@ int *allocCache(const Layer *layer, int sizeX, int sizeZ)
} }
void applySeed(LayerStack *g, int64_t seed) void applySeed(LayerStack *g, uint64_t seed)
{ {
// the seed has to be applied recursively // the seed has to be applied recursively
setLayerSeed(g->entry_1, seed); setLayerSeed(g->entry_1, seed);
@ -268,7 +271,7 @@ int genArea(const Layer *layer, int *out, int areaX, int areaZ, int areaWidth, i
int genNetherScaled(int mc, int64_t seed, int scale, int *out, int genNetherScaled(int mc, uint64_t seed, int scale, int *out,
int x, int z, int w, int h, int y0, int y1) int x, int z, int w, int h, int y0, int y1)
{ {
if (scale != 1 && scale != 4 && scale != 16 && scale != 64) if (scale != 1 && scale != 4 && scale != 16 && scale != 64)
@ -303,7 +306,8 @@ int genNetherScaled(int mc, int64_t seed, int scale, int *out,
int err = mapNether2D(&nn, out, pX, pZ, pW, pH); int err = mapNether2D(&nn, out, pX, pZ, pW, pH);
if (err) if (err)
return err; return err;
Layer lvoronoi = {0}; Layer lvoronoi;
memset(&lvoronoi, 0, sizeof(Layer));
lvoronoi.startSalt = getVoronoiSHA(seed); lvoronoi.startSalt = getVoronoiSHA(seed);
return mapVoronoi(&lvoronoi, out, x, z, w, h); return mapVoronoi(&lvoronoi, out, x, z, w, h);
} }
@ -314,7 +318,7 @@ int genNetherScaled(int mc, int64_t seed, int scale, int *out,
} }
int genEndScaled(int mc, int64_t seed, int scale, int *out, int genEndScaled(int mc, uint64_t seed, int scale, int *out,
int x, int z, int w, int h) int x, int z, int w, int h)
{ {
if (scale != 1 && scale != 4 && scale != 16 && scale != 64) if (scale != 1 && scale != 4 && scale != 16 && scale != 64)
@ -343,7 +347,8 @@ int genEndScaled(int mc, int64_t seed, int scale, int *out,
int err = mapEnd(&en, out, pX, pZ, pW, pH); int err = mapEnd(&en, out, pX, pZ, pW, pH);
if (err) if (err)
return err; return err;
Layer lvoronoi = {0}; Layer lvoronoi;
memset(&lvoronoi, 0, sizeof(Layer));
if (mc >= MC_1_15) if (mc >= MC_1_15)
{ {
lvoronoi.startSalt = getVoronoiSHA(seed); lvoronoi.startSalt = getVoronoiSHA(seed);

View File

@ -3,6 +3,7 @@
#include "layers.h" #include "layers.h"
/* Enumeration of the layer indices in the generator. */ /* Enumeration of the layer indices in the generator. */
enum enum
{ {
@ -110,10 +111,10 @@ int *allocCache(const Layer *layer, int sizeX, int sizeZ);
/* Set up custom layers. */ /* Set up custom layers. */
Layer *setupLayer(LayerStack *g, int layerId, mapfunc_t *map, int mc, Layer *setupLayer(LayerStack *g, int layerId, mapfunc_t *map, int mc,
int8_t zoom, int8_t edge, int saltbase, Layer *p, Layer *p2); int8_t zoom, int8_t edge, uint64_t saltbase, Layer *p, Layer *p2);
/* Sets the world seed for the generator */ /* Sets the world seed for the generator */
void applySeed(LayerStack *g, int64_t seed); void applySeed(LayerStack *g, uint64_t seed);
/* Generates the specified area using the current generator settings and stores /* Generates the specified area using the current generator settings and stores
* the biomeIDs in 'out'. * the biomeIDs in 'out'.
@ -134,9 +135,9 @@ int genArea(const Layer *layer, int *out, int areaX, int areaZ, int areaWidth, i
* @y0,y1 min and max vertical dimensions (inclusive) * @y0,y1 min and max vertical dimensions (inclusive)
* @return zero upon success * @return zero upon success
*/ */
int genNetherScaled(int mc, int64_t seed, int scale, int *out, int genNetherScaled(int mc, uint64_t seed, int scale, int *out,
int x, int z, int w, int h, int y0, int y1); int x, int z, int w, int h, int y0, int y1);
int genEndScaled(int mc, int64_t seed, int scale, int *out, int genEndScaled(int mc, uint64_t seed, int scale, int *out,
int x, int z, int w, int h); int x, int z, int w, int h);

View File

@ -7,23 +7,26 @@
/********************** C copy of the Java Random methods ********************** /********************** C copy of the Java Random methods **********************
*/ */
static inline void setSeed(int64_t *seed, int64_t value) static inline void setSeed(uint64_t *seed, uint64_t value)
{ {
*seed = (value ^ 0x5deece66d) & ((1LL << 48) - 1); *seed = (value ^ 0x5deece66d) & ((1ULL << 48) - 1);
} }
static inline int next(int64_t *seed, const int bits) static inline int next(uint64_t *seed, const int bits)
{ {
*seed = (*seed * 0x5deece66d + 0xb) & ((1LL << 48) - 1); *seed = (*seed * 0x5deece66d + 0xb) & ((1ULL << 48) - 1);
return (int) (*seed >> (48 - bits)); return (int) ((int64_t)*seed >> (48 - bits));
} }
static inline int nextInt(int64_t *seed, const int n) static inline int nextInt(uint64_t *seed, const int n)
{ {
int bits, val; int bits, val;
const int m = n - 1; const int m = n - 1;
if((m & n) == 0) return (int) ((n * (int64_t)next(seed, 31)) >> 31); if ((m & n) == 0) {
uint64_t x = n * (uint64_t)next(seed, 31);
return (int) ((int64_t) x >> 31);
}
do { do {
bits = next(seed, 31); bits = next(seed, 31);
@ -33,19 +36,22 @@ static inline int nextInt(int64_t *seed, const int n)
return val; return val;
} }
static inline int64_t nextLong(int64_t *seed) static inline uint64_t nextLong(uint64_t *seed)
{ {
return ((int64_t) next(seed, 32) << 32) + next(seed, 32); return ((uint64_t) next(seed, 32) << 32) + next(seed, 32);
} }
static inline float nextFloat(int64_t *seed) static inline float nextFloat(uint64_t *seed)
{ {
return next(seed, 24) / (float) (1 << 24); return next(seed, 24) / (float) (1 << 24);
} }
static inline double nextDouble(int64_t *seed) static inline double nextDouble(uint64_t *seed)
{ {
return (((int64_t) next(seed, 26) << 27) + next(seed, 27)) / (double) (1LL << 53); uint64_t x = (uint64_t)next(seed, 26);
x <<= 27;
x += next(seed, 27);
return (int64_t) x / (double) (1ULL << 53);
} }
/* A macro to generate the ideal assembly for X = nextInt(S, 24) /* A macro to generate the ideal assembly for X = nextInt(S, 24)
@ -54,13 +60,13 @@ static inline double nextDouble(int64_t *seed)
*/ */
#define JAVA_NEXT_INT24(S,X) \ #define JAVA_NEXT_INT24(S,X) \
do { \ do { \
int64_t a = (1ULL << 48) - 1; \ uint64_t a = (1ULL << 48) - 1; \
int64_t c = 0x5deece66dLL * (S); \ uint64_t c = 0x5deece66dULL * (S); \
c += 11; a &= c; \ c += 11; a &= c; \
(S) = a; \ (S) = a; \
a >>= 17; \ a = (uint64_t) ((int64_t)a >> 17); \
c = 0xaaaaaaab * a; \ c = 0xaaaaaaab * a; \
c >>= 36; \ c = (uint64_t) ((int64_t)c >> 36); \
(X) = (int)a - (int)(c << 3) * 3; \ (X) = (int)a - (int)(c << 3) * 3; \
} while (0) } while (0)
@ -69,12 +75,12 @@ static inline double nextDouble(int64_t *seed)
* --------- * ---------
* Jumps forwards in the random number sequence by simulating 'n' calls to next. * Jumps forwards in the random number sequence by simulating 'n' calls to next.
*/ */
static inline void skipNextN(int64_t *seed, uint64_t n) static inline void skipNextN(uint64_t *seed, uint64_t n)
{ {
int64_t m = 1; uint64_t m = 1;
int64_t a = 0; uint64_t a = 0;
int64_t im = 0x5deece66dLL; uint64_t im = 0x5deece66dULL;
int64_t ia = 0xbLL; uint64_t ia = 0xb;
uint64_t k; uint64_t k;
for (k = n; k; k >>= 1) for (k = n; k; k >>= 1)
@ -89,59 +95,24 @@ static inline void skipNextN(int64_t *seed, uint64_t n)
} }
*seed = *seed * m + a; *seed = *seed * m + a;
*seed &= 0xffffffffffffLL; *seed &= 0xffffffffffffULL;
}
/* invSeed48
* ---------
* Returns the previous 48-bit seed which will generate 'nseed'.
* The upper 16 bits are ignored, both here and in the generator.
*/
static inline __attribute__((const))
int64_t invSeed48(int64_t nseed)
{
const int64_t x = 0x5deece66d;
const int64_t xinv = 0xdfe05bcb1365LL;
const int64_t y = 0xbLL;
const int64_t m48 = 0xffffffffffffLL;
int64_t a = nseed >> 32;
int64_t b = nseed & 0xffffffffLL;
if (b & 0x80000000LL) a++;
int64_t q = ((b << 16) - y - (a << 16)*x) & m48;
int64_t k;
for (k = 0; k <= 5; k++)
{
int64_t d = (x - (q + (k << 48))) % x;
d = (d + x) % x; // force the modulo and keep it positive
if (d < 65536)
{
int64_t c = ((q + d) * xinv) & m48;
if (c < 65536)
{
return ((((a << 16) + c) - y) * xinv) & m48;
}
}
}
return -1;
} }
/* Find the modular inverse: (1/x) | mod m. /* Find the modular inverse: (1/x) | mod m.
* Assumes x and m are positive and co-prime. * Assumes x and m are positive (less than 2^63), co-prime.
*/ */
static inline __attribute__((const)) static inline __attribute__((const))
int64_t mulInv(int64_t x, int64_t m) uint64_t mulInv(uint64_t x, uint64_t m)
{ {
int64_t t, q, a, b, n; uint64_t t, q, a, b, n;
if (m <= 1) if ((int64_t)m <= 1)
return 0; // no solution return 0; // no solution
n = m; n = m;
a = 0; b = 1; a = 0; b = 1;
while (x > 1) while ((int64_t)x > 1)
{ {
if (m == 0) if (m == 0)
return 0; // x and m are co-prime return 0; // x and m are co-prime
@ -150,7 +121,7 @@ int64_t mulInv(int64_t x, int64_t m)
t = a; a = b - q * a; b = t; t = a; a = b - q * a; b = t;
} }
if (b < 0) if ((int64_t)b < 0)
b += n; b += n;
return b; return b;
} }

177
layers.c
View File

@ -11,18 +11,14 @@
int biomeExists(int mc, int id) int biomeExists(int mc, int id)
{ {
if (id >= ocean && id <= mountain_edge) return 1;
if (id >= jungle && id <= jungle_hills) return mc >= MC_1_2;
if (id >= jungle_edge && id <= badlands_plateau) return mc >= MC_1_7;
if (id >= small_end_islands && id <= end_barrens) return mc >= MC_1_9;
if (id >= warm_ocean && id <= deep_frozen_ocean) return mc >= MC_1_13;
switch (id) switch (id)
{ {
case ocean...mountain_edge:
return 1;
case jungle...jungle_hills:
return mc >= MC_1_2;
case jungle_edge...badlands_plateau:
return mc >= MC_1_7;
case small_end_islands...end_barrens:
return mc >= MC_1_9;
case warm_ocean...deep_frozen_ocean:
return mc >= MC_1_13;
case the_void: case the_void:
return mc >= MC_1_9; return mc >= MC_1_9;
case sunflower_plains: case sunflower_plains:
@ -50,7 +46,10 @@ int biomeExists(int mc, int id)
case bamboo_jungle: case bamboo_jungle:
case bamboo_jungle_hills: case bamboo_jungle_hills:
return mc >= MC_1_14; return mc >= MC_1_14;
case soul_sand_valley...basalt_deltas: case soul_sand_valley:
case crimson_forest:
case warped_forest:
case basalt_deltas:
return mc >= MC_1_16; return mc >= MC_1_16;
case dripstone_caves: case dripstone_caves:
case lush_caves: case lush_caves:
@ -65,6 +64,9 @@ int isOverworld(int mc, int id)
if (!biomeExists(mc, id)) if (!biomeExists(mc, id))
return 0; return 0;
if (id >= small_end_islands && id <= end_barrens) return 0;
if (id >= soul_sand_valley && id <= basalt_deltas) return 0;
switch (id) switch (id)
{ {
case nether_wastes: case nether_wastes:
@ -74,15 +76,13 @@ int isOverworld(int mc, int id)
return mc <= MC_1_6 || mc >= MC_1_13; return mc <= MC_1_6 || mc >= MC_1_13;
case mountain_edge: case mountain_edge:
return mc <= MC_1_6; return mc <= MC_1_6;
case small_end_islands...end_barrens:
case deep_warm_ocean: case deep_warm_ocean:
case the_void: case the_void:
return 0; return 0;
case tall_birch_hills: case tall_birch_hills:
return mc <= MC_1_8 || mc >= MC_1_11; return mc <= MC_1_8 || mc >= MC_1_11;
case soul_sand_valley...basalt_deltas: case dripstone_caves:
return 0; case lush_caves:
case dripstone_caves...lush_caves:
return 0; return 0;
} }
return 1; return 1;
@ -321,8 +321,7 @@ void initBiomes()
{ {
} }
void setLayerSeed(Layer *layer, uint64_t worldSeed)
void setLayerSeed(Layer *layer, int64_t worldSeed)
{ {
if (layer->p2 != NULL) if (layer->p2 != NULL)
setLayerSeed(layer->p2, worldSeed); setLayerSeed(layer->p2, worldSeed);
@ -332,25 +331,25 @@ void setLayerSeed(Layer *layer, int64_t worldSeed)
if (layer->noise != NULL) if (layer->noise != NULL)
{ {
int64_t s; uint64_t s;
setSeed(&s, worldSeed); setSeed(&s, worldSeed);
perlinInit((PerlinNoise*)layer->noise, &s); perlinInit((PerlinNoise*)layer->noise, &s);
} }
int64_t ls = layer->layerSalt; uint64_t ls = layer->layerSalt;
if (ls == 0) // Pre 1.13 the Hills branch stays zero-initialized if (ls == 0)
{ { // Pre 1.13 the Hills branch stays zero-initialized
layer->startSalt = 0; layer->startSalt = 0;
layer->startSeed = 0; layer->startSeed = 0;
} }
else if (ls == -1) // Post 1.14 VoronoiZoom uses SHA256 for initialization else if (ls == LAYER_INIT_SHA)
{ { // Post 1.14 Voronoi uses SHA256 for initialization
layer->startSalt = getVoronoiSHA(worldSeed); layer->startSalt = getVoronoiSHA(worldSeed);
layer->startSeed = 0; layer->startSeed = 0;
} }
else else
{ {
int64_t st = worldSeed; uint64_t st = worldSeed;
st = mcStepSeed(st, ls); st = mcStepSeed(st, ls);
st = mcStepSeed(st, ls); st = mcStepSeed(st, ls);
st = mcStepSeed(st, ls); st = mcStepSeed(st, ls);
@ -409,7 +408,7 @@ static double indexedLerp(int idx, double d1, double d2, double d3)
} }
void perlinInit(PerlinNoise *rnd, int64_t *seed) void perlinInit(PerlinNoise *rnd, uint64_t *seed)
{ {
int i = 0; int i = 0;
memset(rnd, 0, sizeof(*rnd)); memset(rnd, 0, sizeof(*rnd));
@ -525,7 +524,7 @@ double sampleSimplex2D(const PerlinNoise *rnd, double x, double y)
} }
void octaveInit(OctaveNoise *rnd, int64_t *seed, PerlinNoise *octaves, void octaveInit(OctaveNoise *rnd, uint64_t *seed, PerlinNoise *octaves,
int omin, int len) int omin, int len)
{ {
int end = omin+len-1; int end = omin+len-1;
@ -575,7 +574,7 @@ double sampleOctave(const OctaveNoise *rnd, double x, double y, double z)
} }
void doublePerlinInit(DoublePerlinNoise *rnd, int64_t *seed, void doublePerlinInit(DoublePerlinNoise *rnd, uint64_t *seed,
PerlinNoise *octavesA, PerlinNoise *octavesB, int omin, int len) PerlinNoise *octavesA, PerlinNoise *octavesB, int omin, int len)
{ // require: len >= 1 && omin+len <= 0 { // require: len >= 1 && omin+len <= 0
rnd->amplitude = (10.0 / 6.0) * len / (len + 1); rnd->amplitude = (10.0 / 6.0) * len / (len + 1);
@ -596,7 +595,7 @@ double sampleDoublePerlin(const DoublePerlinNoise *rnd,
} }
void initSurfaceNoise(SurfaceNoise *rnd, int64_t *seed, void initSurfaceNoise(SurfaceNoise *rnd, uint64_t *seed,
double xzScale, double yScale, double xzFactor, double yFactor) double xzScale, double yScale, double xzFactor, double yFactor)
{ {
rnd->xzScale = xzScale; rnd->xzScale = xzScale;
@ -608,9 +607,9 @@ void initSurfaceNoise(SurfaceNoise *rnd, int64_t *seed,
octaveInit(&rnd->octmain, seed, rnd->oct+32, -7, 8); octaveInit(&rnd->octmain, seed, rnd->oct+32, -7, 8);
} }
void initSurfaceNoiseEnd(SurfaceNoise *rnd, int64_t seed) void initSurfaceNoiseEnd(SurfaceNoise *rnd, uint64_t seed)
{ {
int64_t s; uint64_t s;
setSeed(&s, seed); setSeed(&s, seed);
initSurfaceNoise(rnd, &s, 2.0, 1.0, 80.0, 160.0); initSurfaceNoise(rnd, &s, 2.0, 1.0, 80.0, 160.0);
} }
@ -660,9 +659,9 @@ double sampleSurfaceNoise(const SurfaceNoise *rnd, int x, int y, int z)
// Nether (1.16+) and End (1.9+) Biome Generation // Nether (1.16+) and End (1.9+) Biome Generation
//============================================================================== //==============================================================================
void setNetherSeed(NetherNoise *nn, int64_t seed) void setNetherSeed(NetherNoise *nn, uint64_t seed)
{ {
int64_t s; uint64_t s;
setSeed(&s, seed); setSeed(&s, seed);
doublePerlinInit(&nn->temperature, &s, &nn->oct[0], &nn->oct[2], -7, 2); doublePerlinInit(&nn->temperature, &s, &nn->oct[0], &nn->oct[2], -7, 2);
setSeed(&s, seed+1); setSeed(&s, seed+1);
@ -796,9 +795,9 @@ int mapNether2D(const NetherNoise *nn, int *out, int x, int z, int w, int h)
} }
void setEndSeed(EndNoise *en, int64_t seed) void setEndSeed(EndNoise *en, uint64_t seed)
{ {
int64_t s; uint64_t s;
setSeed(&s, seed); setSeed(&s, seed);
skipNextN(&s, 17292); skipNextN(&s, 17292);
perlinInit(en, &s); perlinInit(en, &s);
@ -1010,7 +1009,7 @@ int getSurfaceHeight(
return 0; return 0;
} }
int getSurfaceHeightEnd(int mc, int64_t seed, int x, int z) int getSurfaceHeightEnd(int mc, uint64_t seed, int x, int z)
{ {
(void) mc; (void) mc;
@ -1052,8 +1051,8 @@ static inline int isAny4(int id, int a, int b, int c, int d)
int mapContinent(const Layer * l, int * out, int x, int z, int w, int h) int mapContinent(const Layer * l, int * out, int x, int z, int w, int h)
{ {
int64_t ss = l->startSeed; uint64_t ss = l->startSeed;
int64_t cs; uint64_t cs;
int i, j; int i, j;
for (j = 0; j < h; j++) for (j = 0; j < h; j++)
@ -1090,8 +1089,8 @@ int mapZoomFuzzy(const Layer * l, int * out, int x, int z, int w, int h)
int idx, v00, v01, v10, v11; int idx, v00, v01, v10, v11;
int *buf = (int*) malloc((newW+1)*(newH+1)*sizeof(*buf)); int *buf = (int*) malloc((newW+1)*(newH+1)*sizeof(*buf));
const int st = (int)l->startSalt; const uint32_t st = (uint32_t)l->startSalt;
const int ss = (int)l->startSeed; const uint32_t ss = (uint32_t)l->startSeed;
for (j = 0; j < pH; j++) for (j = 0; j < pH; j++)
{ {
@ -1115,10 +1114,10 @@ int mapZoomFuzzy(const Layer * l, int * out, int x, int z, int w, int h)
continue; continue;
} }
int chunkX = (i + pX) << 1; int chunkX = (int)((uint32_t)(i + pX) << 1);
int chunkZ = (j + pZ) << 1; int chunkZ = (int)((uint32_t)(j + pZ) << 1);
int cs = ss; uint32_t cs = ss;
cs += chunkX; cs += chunkX;
cs *= cs * 1284865837 + 4150755663; cs *= cs * 1284865837 + 4150755663;
cs += chunkZ; cs += chunkZ;
@ -1154,7 +1153,7 @@ int mapZoomFuzzy(const Layer * l, int * out, int x, int z, int w, int h)
} }
static inline int select4(int cs, int st, int v00, int v01, int v10, int v11) static inline int select4(uint32_t cs, uint32_t st, int v00, int v01, int v10, int v11)
{ {
int v; int v;
int cv00 = (v00 == v10) + (v00 == v01) + (v00 == v11); int cv00 = (v00 == v10) + (v00 == v01) + (v00 == v11);
@ -1194,8 +1193,8 @@ int mapZoom(const Layer * l, int * out, int x, int z, int w, int h)
int idx, v00, v01, v10, v11; int idx, v00, v01, v10, v11;
int *buf = (int*) malloc((newW+1)*(newH+1)*sizeof(*buf)); int *buf = (int*) malloc((newW+1)*(newH+1)*sizeof(*buf));
const int st = (int)l->startSalt; const uint32_t st = (uint32_t)l->startSalt;
const int ss = (int)l->startSeed; const uint32_t ss = (uint32_t)l->startSeed;
for (j = 0; j < pH; j++) for (j = 0; j < pH; j++)
{ {
@ -1219,10 +1218,10 @@ int mapZoom(const Layer * l, int * out, int x, int z, int w, int h)
continue; continue;
} }
int chunkX = (i + pX) << 1; int chunkX = (int)((uint32_t)(i + pX) << 1);
int chunkZ = (j + pZ) << 1; int chunkZ = (int)((uint32_t)(j + pZ) << 1);
int cs = ss; uint32_t cs = ss;
cs += chunkX; cs += chunkX;
cs *= cs * 1284865837 + 4150755663; cs *= cs * 1284865837 + 4150755663;
cs += chunkZ; cs += chunkZ;
@ -1268,9 +1267,9 @@ int mapLand(const Layer * l, int * out, int x, int z, int w, int h)
if U(err != 0) if U(err != 0)
return err; return err;
int64_t st = l->startSalt; uint64_t st = l->startSalt;
int64_t ss = l->startSeed; uint64_t ss = l->startSeed;
int64_t cs; uint64_t cs;
for (j = 0; j < h; j++) for (j = 0; j < h; j++)
{ {
@ -1384,9 +1383,9 @@ int mapLand16(const Layer * l, int * out, int x, int z, int w, int h)
if U(err != 0) if U(err != 0)
return err; return err;
int64_t st = l->startSalt; uint64_t st = l->startSalt;
int64_t ss = l->startSeed; uint64_t ss = l->startSeed;
int64_t cs; uint64_t cs;
for (j = 0; j < h; j++) for (j = 0; j < h; j++)
{ {
@ -1480,8 +1479,8 @@ int mapIsland(const Layer * l, int * out, int x, int z, int w, int h)
if U(err != 0) if U(err != 0)
return err; return err;
int64_t ss = l->startSeed; uint64_t ss = l->startSeed;
int64_t cs; uint64_t cs;
for (j = 0; j < h; j++) for (j = 0; j < h; j++)
{ {
@ -1521,8 +1520,8 @@ int mapSnow16(const Layer * l, int * out, int x, int z, int w, int h)
if U(err != 0) if U(err != 0)
return err; return err;
int64_t ss = l->startSeed; uint64_t ss = l->startSeed;
int64_t cs; uint64_t cs;
for (j = 0; j < h; j++) for (j = 0; j < h; j++)
{ {
@ -1554,8 +1553,8 @@ int mapSnow(const Layer * l, int * out, int x, int z, int w, int h)
if U(err != 0) if U(err != 0)
return err; return err;
int64_t ss = l->startSeed; uint64_t ss = l->startSeed;
int64_t cs; uint64_t cs;
for (j = 0; j < h; j++) for (j = 0; j < h; j++)
{ {
@ -1670,9 +1669,9 @@ int mapSpecial(const Layer * l, int * out, int x, int z, int w, int h)
if U(err != 0) if U(err != 0)
return err; return err;
int64_t st = l->startSalt; uint64_t st = l->startSalt;
int64_t ss = l->startSeed; uint64_t ss = l->startSeed;
int64_t cs; uint64_t cs;
int i, j; int i, j;
for (j = 0; j < h; j++) for (j = 0; j < h; j++)
@ -1710,8 +1709,8 @@ int mapMushroom(const Layer * l, int * out, int x, int z, int w, int h)
if U(err != 0) if U(err != 0)
return err; return err;
int64_t ss = l->startSeed; uint64_t ss = l->startSeed;
int64_t cs; uint64_t cs;
for (j = 0; j < h; j++) for (j = 0; j < h; j++)
{ {
@ -1813,8 +1812,8 @@ int mapBiome(const Layer * l, int * out, int x, int z, int w, int h)
return err; return err;
int mc = l->mc; int mc = l->mc;
int64_t ss = l->startSeed; uint64_t ss = l->startSeed;
int64_t cs; uint64_t cs;
int i, j; int i, j;
for (j = 0; j < h; j++) for (j = 0; j < h; j++)
@ -1891,8 +1890,8 @@ int mapNoise(const Layer * l, int * out, int x, int z, int w, int h)
if U(err != 0) if U(err != 0)
return err; return err;
int64_t ss = l->startSeed; uint64_t ss = l->startSeed;
int64_t cs; uint64_t cs;
int mod = (l->mc <= MC_1_6) ? 2 : 299999; int mod = (l->mc <= MC_1_6) ? 2 : 299999;
@ -1923,8 +1922,8 @@ int mapBamboo(const Layer * l, int * out, int x, int z, int w, int h)
if U(err != 0) if U(err != 0)
return err; return err;
int64_t ss = l->startSeed; uint64_t ss = l->startSeed;
int64_t cs; uint64_t cs;
int i, j; int i, j;
for (j = 0; j < h; j++) for (j = 0; j < h; j++)
@ -2061,9 +2060,9 @@ int mapHills(const Layer * l, int * out, int x, int z, int w, int h)
} }
int mc = l->mc; int mc = l->mc;
int64_t st = l->startSalt; uint64_t st = l->startSalt;
int64_t ss = l->startSeed; uint64_t ss = l->startSeed;
int64_t cs; uint64_t cs;
for (j = 0; j < h; j++) for (j = 0; j < h; j++)
{ {
@ -2275,8 +2274,8 @@ int mapSmooth(const Layer * l, int * out, int x, int z, int w, int h)
if U(err != 0) if U(err != 0)
return err; return err;
int64_t ss = l->startSeed; uint64_t ss = l->startSeed;
int64_t cs; uint64_t cs;
for (j = 0; j < h; j++) for (j = 0; j < h; j++)
{ {
@ -2297,7 +2296,7 @@ int mapSmooth(const Layer * l, int * out, int x, int z, int w, int h)
if (v01 == v21 && v10 == v12) if (v01 == v21 && v10 == v12)
{ {
cs = getChunkSeed(ss, i+x, j+z); cs = getChunkSeed(ss, i+x, j+z);
if (cs & ((int64_t)1 << 24)) if (cs & ((uint64_t)1 << 24))
v11 = v10; v11 = v10;
else else
v11 = v01; v11 = v01;
@ -2325,8 +2324,8 @@ int mapSunflower(const Layer * l, int * out, int x, int z, int w, int h)
if U(err != 0) if U(err != 0)
return err; return err;
int64_t ss = l->startSeed; uint64_t ss = l->startSeed;
int64_t cs; uint64_t cs;
for (j = 0; j < h; j++) for (j = 0; j < h; j++)
{ {
@ -2490,8 +2489,8 @@ int mapSwampRiver(const Layer * l, int * out, int x, int z, int w, int h)
if U(err != 0) if U(err != 0)
return err; return err;
int64_t ss = l->startSeed; uint64_t ss = l->startSeed;
int64_t cs; uint64_t cs;
for (j = 0; j < h; j++) for (j = 0; j < h; j++)
{ {
@ -2716,7 +2715,7 @@ int mapOceanMix(const Layer * l, int * out, int x, int z, int w, int h)
static inline void getVoronoiCell(int64_t sha, int a, int b, int c, static inline void getVoronoiCell(int64_t sha, int a, int b, int c,
int *x, int *y, int *z) int *x, int *y, int *z)
{ {
int64_t s = sha; uint64_t s = sha;
s = mcStepSeed(s, a); s = mcStepSeed(s, a);
s = mcStepSeed(s, b); s = mcStepSeed(s, b);
s = mcStepSeed(s, c); s = mcStepSeed(s, c);
@ -2747,7 +2746,7 @@ int mapVoronoi(const Layer * l, int * out, int x, int z, int w, int h)
return err; return err;
} }
int64_t sha = l->startSalt; uint64_t sha = l->startSalt;
int *buf = (int *) malloc(w*h*sizeof(*buf)); int *buf = (int *) malloc(w*h*sizeof(*buf));
int x000, x001, x010, x011, x100, x101, x110, x111; int x000, x001, x010, x011, x100, x101, x110, x111;
@ -2918,9 +2917,9 @@ int mapVoronoi114(const Layer * l, int * out, int x, int z, int w, int h)
int *buf = (int *) malloc((newW+1)*(newH+1)*sizeof(*buf)); int *buf = (int *) malloc((newW+1)*(newH+1)*sizeof(*buf));
int i, j; int i, j;
int64_t st = l->startSalt; uint64_t st = l->startSalt;
int64_t ss = l->startSeed; uint64_t ss = l->startSeed;
int64_t cs; uint64_t cs;
for (j = 0; j < pH-1; j++) for (j = 0; j < pH-1; j++)
{ {
@ -3016,7 +3015,7 @@ int mapVoronoi114(const Layer * l, int * out, int x, int z, int w, int h)
inline static __attribute__((always_inline,const)) inline static __attribute__((always_inline,const))
uint32_t rotr(uint32_t a, int b) { return (a >> b) | (a << (32-b)); } uint32_t rotr(uint32_t a, int b) { return (a >> b) | (a << (32-b)); }
int64_t getVoronoiSHA(int64_t seed) uint64_t getVoronoiSHA(uint64_t seed)
{ {
static const uint32_t K[64] = { static const uint32_t K[64] = {
0x428a2f98,0x71374491, 0xb5c0fbcf,0xe9b5dba5, 0x428a2f98,0x71374491, 0xb5c0fbcf,0xe9b5dba5,
@ -3091,10 +3090,10 @@ int64_t getVoronoiSHA(int64_t seed)
a0 += B[0]; a0 += B[0];
a1 += B[1]; a1 += B[1];
return __builtin_bswap32(a0) | ((int64_t)__builtin_bswap32(a1) << 32); return __builtin_bswap32(a0) | ((uint64_t)__builtin_bswap32(a1) << 32);
} }
void voronoiAccess3D(int64_t sha, int x, int y, int z, int *x4, int *y4, int *z4) void voronoiAccess3D(uint64_t sha, int x, int y, int z, int *x4, int *y4, int *z4)
{ {
x -= 2; x -= 2;
y -= 2; y -= 2;

View File

@ -25,6 +25,9 @@
#define U(COND) (COND) #define U(COND) (COND)
#endif #endif
#define LAYER_INIT_SHA (~0ULL)
/* Minecraft versions */ /* Minecraft versions */
enum MCversion enum MCversion
{ {
@ -172,9 +175,9 @@ STRUCT(Layer)
int8_t edge; // maximum border required from parent layer int8_t edge; // maximum border required from parent layer
int scale; // scale of this layer (cell = scale x scale blocks) int scale; // scale of this layer (cell = scale x scale blocks)
int64_t layerSalt; // processed salt or initialization mode uint64_t layerSalt; // processed salt or initialization mode
int64_t startSalt; // (depends on world seed) used to step PRNG forward uint64_t startSalt; // (depends on world seed) used to step PRNG forward
int64_t startSeed; // (depends on world seed) starting point for chunk seeds uint64_t startSeed; // (depends on world seed) starting point for chunk seeds
void *noise; // (depends on world seed) noise map data void *noise; // (depends on world seed) noise map data
void *data; // generic data for custom layers void *data; // generic data for custom layers
@ -215,30 +218,30 @@ extern "C"
void initBiomes(); void initBiomes();
/* Applies the given world seed to the layer and all dependent layers. */ /* Applies the given world seed to the layer and all dependent layers. */
void setLayerSeed(Layer *layer, int64_t worldSeed); void setLayerSeed(Layer *layer, uint64_t worldSeed);
//============================================================================== //==============================================================================
// Noise // Noise
//============================================================================== //==============================================================================
void perlinInit(PerlinNoise *rnd, int64_t *seed); void perlinInit(PerlinNoise *rnd, uint64_t *seed);
double samplePerlin(const PerlinNoise *rnd, double x, double y, double z, double samplePerlin(const PerlinNoise *rnd, double x, double y, double z,
double yamp, double ymin); double yamp, double ymin);
double sampleSimplex2D(const PerlinNoise *rnd, double x, double y); double sampleSimplex2D(const PerlinNoise *rnd, double x, double y);
void octaveInit(OctaveNoise *rnd, int64_t *seed, PerlinNoise *octaves, void octaveInit(OctaveNoise *rnd, uint64_t *seed, PerlinNoise *octaves,
int omin, int len); int omin, int len);
double sampleOctave(const OctaveNoise *rnd, double x, double y, double z); double sampleOctave(const OctaveNoise *rnd, double x, double y, double z);
void doublePerlinInit(DoublePerlinNoise *rnd, int64_t *seed, void doublePerlinInit(DoublePerlinNoise *rnd, uint64_t *seed,
PerlinNoise *octavesA, PerlinNoise *octavesB, int omin, int len); PerlinNoise *octavesA, PerlinNoise *octavesB, int omin, int len);
double sampleDoublePerlin(const DoublePerlinNoise *rnd, double sampleDoublePerlin(const DoublePerlinNoise *rnd,
double x, double y, double z); double x, double y, double z);
void initSurfaceNoise(SurfaceNoise *rnd, int64_t *seed, void initSurfaceNoise(SurfaceNoise *rnd, uint64_t *seed,
double xzScale, double yScale, double xzFactor, double yFactor); double xzScale, double yScale, double xzFactor, double yFactor);
void initSurfaceNoiseEnd(SurfaceNoise *rnd, int64_t seed); void initSurfaceNoiseEnd(SurfaceNoise *rnd, uint64_t seed);
double sampleSurfaceNoise(const SurfaceNoise *rnd, int x, int y, int z); double sampleSurfaceNoise(const SurfaceNoise *rnd, int x, int y, int z);
@ -266,7 +269,7 @@ double sampleSurfaceNoise(const SurfaceNoise *rnd, int x, int y, int z);
* The output buffer for the map-functions need only be of sufficient size to * The output buffer for the map-functions need only be of sufficient size to
* hold the generated area (i.e. w*h or w*h*yh). * hold the generated area (i.e. w*h or w*h*yh).
*/ */
void setNetherSeed(NetherNoise *nn, int64_t seed); void setNetherSeed(NetherNoise *nn, uint64_t seed);
int getNetherBiome(const NetherNoise *nn, int x, int y, int z, float *ndel); int getNetherBiome(const NetherNoise *nn, int x, int y, int z, float *ndel);
int mapNether2D(const NetherNoise *nn, int *out, int x, int z, int w, int h); int mapNether2D(const NetherNoise *nn, int *out, int x, int z, int w, int h);
int mapNether3D(const NetherNoise *nn, int *out, int x, int z, int w, int h, int mapNether3D(const NetherNoise *nn, int *out, int x, int z, int w, int h,
@ -278,10 +281,10 @@ int mapNether3D(const NetherNoise *nn, int *out, int x, int z, int w, int h,
* is a variation which also scales this up on a regular grid to 1:4. The final * is a variation which also scales this up on a regular grid to 1:4. The final
* access at a 1:1 scale is the standard voronoi layer. * access at a 1:1 scale is the standard voronoi layer.
*/ */
void setEndSeed(EndNoise *en, int64_t seed); void setEndSeed(EndNoise *en, uint64_t seed);
int mapEndBiome(const EndNoise *en, int *out, int x, int z, int w, int h); int mapEndBiome(const EndNoise *en, int *out, int x, int z, int w, int h);
int mapEnd(const EndNoise *en, int *out, int x, int z, int w, int h); int mapEnd(const EndNoise *en, int *out, int x, int z, int w, int h);
int getSurfaceHeightEnd(int mc, int64_t seed, int x, int z); int getSurfaceHeightEnd(int mc, uint64_t seed, int x, int z);
//============================================================================== //==============================================================================
@ -302,53 +305,53 @@ int getSurfaceHeightEnd(int mc, int64_t seed, int x, int z);
* cs_next = mcStepSeed(cs, st) * cs_next = mcStepSeed(cs, st)
*/ */
static inline int64_t mcStepSeed(int64_t s, int64_t salt) static inline uint64_t mcStepSeed(uint64_t s, uint64_t salt)
{ {
return s * (s * 6364136223846793005LL + 1442695040888963407LL) + salt; return s * (s * 6364136223846793005ULL + 1442695040888963407ULL) + salt;
} }
static inline int mcFirstInt(int64_t s, int mod) static inline int mcFirstInt(uint64_t s, int mod)
{ {
int ret = (int)((s >> 24) % mod); int ret = (int)(((int64_t)s >> 24) % mod);
if (ret < 0) if (ret < 0)
ret += mod; ret += mod;
return ret; return ret;
} }
static inline int mcFirstIsZero(int64_t s, int mod) static inline int mcFirstIsZero(uint64_t s, int mod)
{ {
return (int)((s >> 24) % mod) == 0; return (int)(((int64_t)s >> 24) % mod) == 0;
} }
static inline int64_t getChunkSeed(int64_t ss, int x, int z) static inline uint64_t getChunkSeed(uint64_t ss, int x, int z)
{ {
int64_t cs = ss + x; uint64_t cs = ss + x;
cs = mcStepSeed(cs, z); cs = mcStepSeed(cs, z);
cs = mcStepSeed(cs, x); cs = mcStepSeed(cs, x);
cs = mcStepSeed(cs, z); cs = mcStepSeed(cs, z);
return cs; return cs;
} }
static inline int64_t getLayerSalt(int64_t salt) static inline uint64_t getLayerSalt(uint64_t salt)
{ {
int64_t ls = mcStepSeed(salt, salt); uint64_t ls = mcStepSeed(salt, salt);
ls = mcStepSeed(ls, salt); ls = mcStepSeed(ls, salt);
ls = mcStepSeed(ls, salt); ls = mcStepSeed(ls, salt);
return ls; return ls;
} }
static inline int64_t getStartSalt(int64_t ws, int64_t ls) static inline uint64_t getStartSalt(uint64_t ws, uint64_t ls)
{ {
int64_t st = ws; uint64_t st = ws;
st = mcStepSeed(st, ls); st = mcStepSeed(st, ls);
st = mcStepSeed(st, ls); st = mcStepSeed(st, ls);
st = mcStepSeed(st, ls); st = mcStepSeed(st, ls);
return st; return st;
} }
static inline int64_t getStartSeed(int64_t ws, int64_t ls) static inline uint64_t getStartSeed(uint64_t ws, uint64_t ls)
{ {
int64_t ss = ws; uint64_t ss = ws;
ss = getStartSalt(ss, ls); ss = getStartSalt(ss, ls);
ss = mcStepSeed(ss, 0); ss = mcStepSeed(ss, 0);
return ss; return ss;
@ -411,8 +414,8 @@ mapfunc_t mapVoronoi114;
// Biome generation now stops at scale 1:4 OceanMix and voronoi is just an // Biome generation now stops at scale 1:4 OceanMix and voronoi is just an
// access algorithm, mapping the 1:1 scale onto its 1:4 correspondent. // access algorithm, mapping the 1:1 scale onto its 1:4 correspondent.
// It is seeded by the first 8-bytes of the SHA-256 hash of the world seed. // It is seeded by the first 8-bytes of the SHA-256 hash of the world seed.
int64_t getVoronoiSHA(int64_t worldSeed) __attribute__((const)); uint64_t getVoronoiSHA(uint64_t worldSeed) __attribute__((const));
void voronoiAccess3D(int64_t sha, int x, int y, int z, int *x4, int *y4, int *z4); void voronoiAccess3D(uint64_t sha, int x, int y, int z, int *x4, int *y4, int *z4);
#ifdef __cplusplus #ifdef __cplusplus