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
//==============================================================================
// 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");
int64_t seed, i;
int64_t *baseSeeds;
uint64_t seed, i;
uint64_t *baseSeeds;
if (fp == NULL)
return NULL;
@ -39,20 +40,20 @@ int64_t *loadSavedSeeds(const char *fnam, int64_t *scnt)
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');
}
if (*scnt == 0)
return NULL;
baseSeeds = (int64_t*) calloc(*scnt, sizeof(*baseSeeds));
baseSeeds = (uint64_t*) calloc(*scnt, sizeof(*baseSeeds));
rewind(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');
}
@ -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);
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;
#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;
case Treasure:
pos->x = (regX << 4) + 9;
pos->z = (regZ << 4) + 9;
seed = regX*341873128712 + regZ*132897987541 + seed + sconf.salt;
pos->x = (int)( ((uint32_t)regX << 4) + 9 );
pos->z = (int)( ((uint32_t)regZ << 4) + 9 );
seed = regX*341873128712ULL + regZ*132897987541ULL + seed + sconf.salt;
setSeed(&seed, seed);
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) {
setAttemptSeed(&seed, regX << 4, regZ << 4);
int valid = nextInt(&seed, 3) == 0;
pos->x = ((regX << 4) + nextInt(&seed, 8) + 4) << 4;
pos->z = ((regZ << 4) + nextInt(&seed, 8) + 4) << 4;
pos->x = (int)((((uint64_t)regX << 4) + nextInt(&seed,8) + 4) << 4);
pos->z = (int)((((uint64_t)regZ << 4) + nextInt(&seed,8) + 4) << 4);
return valid;
} else {
setSeed(&seed, regX*341873128712 + regZ*132897987541 + seed + sconf.salt);
pos->x = (regX * sconf.regionSize + nextInt(&seed, sconf.chunkRange)) << 4;
pos->z = (regZ * sconf.regionSize + nextInt(&seed, sconf.chunkRange)) << 4;
getRegPos(pos, &seed, regX, regZ, sconf);
return nextInt(&seed, 5) < 2;
}
case Bastion:
setSeed(&seed, regX*341873128712 + regZ*132897987541 + seed + sconf.salt);
pos->x = (regX * sconf.regionSize + nextInt(&seed, sconf.chunkRange)) << 4;
pos->z = (regZ * sconf.regionSize + nextInt(&seed, sconf.chunkRange)) << 4;
getRegPos(pos, &seed, regX, regZ, sconf);
return nextInt(&seed, 5) >= 2;
default:
@ -209,12 +216,12 @@ int getStructurePos(int structureType, int mc, int64_t seed, int regX, int regZ,
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);
int64_t i = nextLong(&s);
int64_t j = nextLong(&s);
uint64_t i = nextLong(&s);
uint64_t j = nextLong(&s);
s = chunkX * i ^ chunkZ * j ^ seed;
setSeed(&s, s);
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)
{
int64_t seeds[100];
uint64_t seeds[100];
size_t len;
linked_seeds_t *next;
};
@ -402,13 +409,13 @@ STRUCT(linked_seeds_t)
STRUCT(threadinfo_t)
{
// seed range
int64_t start, end;
const int64_t *lowBits;
uint64_t start, end;
const uint64_t *lowBits;
int lowBitCnt;
int lowBitN;
// testing function
int (*check)(int64_t, void*);
int (*check)(uint64_t, void*);
void *data;
// output
@ -440,7 +447,7 @@ static int mkdirp(char *path)
struct stat st;
if (stat(path, &st) == -1)
err = mkdir(path, 0773);
else if (!(st.st_mode & S_IFDIR))
else if (!S_ISDIR(st.st_mode))
err = 1;
p = q+1;
@ -461,17 +468,17 @@ static DWORD WINAPI searchAll48Thread(LPVOID data)
threadinfo_t *info = (threadinfo_t*)data;
int64_t seed = info->start;
int64_t end = info->end;
uint64_t seed = info->start;
uint64_t end = info->end;
linked_seeds_t *lp = &info->ls;
lp->len = 0;
lp->next = NULL;
if (info->lowBits)
{
int64_t hstep = 1LL << info->lowBitN;
int64_t hmask = ~(hstep - 1);
int64_t mid;
uint64_t hstep = 1ULL << info->lowBitN;
uint64_t hmask = ~(hstep - 1);
uint64_t mid;
int idx;
mid = info->start & hmask;
@ -483,14 +490,14 @@ static DWORD WINAPI searchAll48Thread(LPVOID data)
{
if (info->fp)
{
fprintf(info->fp, "%" PRId64"\n", seed);
fprintf(info->fp, "%" PRId64"\n", (int64_t)seed);
fflush(info->fp);
}
else
{
lp->seeds[lp->len] = seed;
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*) malloc(sizeof(linked_seeds_t));
@ -522,14 +529,14 @@ static DWORD WINAPI searchAll48Thread(LPVOID data)
{
if (info->fp)
{
fprintf(info->fp, "%" PRId64"\n", seed);
fprintf(info->fp, "%" PRId64"\n", (int64_t)seed);
fflush(info->fp);
}
else
{
lp->seeds[lp->len] = seed;
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*) malloc(sizeof(linked_seeds_t));
@ -554,14 +561,14 @@ static DWORD WINAPI searchAll48Thread(LPVOID data)
int searchAll48(
int64_t ** seedbuf,
int64_t * buflen,
uint64_t ** seedbuf,
uint64_t * buflen,
const char * path,
int threads,
const int64_t * lowBits,
const uint64_t * lowBits,
int lowBitCnt,
int lowBitN,
int (*check)(int64_t s48, void *data),
int (*check)(uint64_t s48, void *data),
void * data
)
{
@ -725,7 +732,7 @@ int searchAll48(
while (lp);
}
*seedbuf = (int64_t*) malloc((*buflen) * sizeof(int64_t));
*seedbuf = (uint64_t*) malloc((*buflen) * sizeof(uint64_t));
if (*seedbuf == NULL)
exit(1);
@ -735,7 +742,7 @@ int searchAll48(
linked_seeds_t *lp = &info[t].ls;
do
{
memcpy(*seedbuf + i, lp->seeds, lp->len * sizeof(int64_t));
memcpy(*seedbuf + i, lp->seeds, lp->len * sizeof(uint64_t));
i += lp->len;
linked_seeds_t *tmp = lp;
lp = lp->next;
@ -757,12 +764,12 @@ L_err:
}
static inline
int scanForQuadBits(const StructureConfig sconf, int radius, int64_t s48,
int64_t lbit, int lbitn, int64_t invB, int64_t x, int64_t z,
int scanForQuadBits(const StructureConfig sconf, int radius, uint64_t s48,
uint64_t lbit, int lbitn, uint64_t invB, int64_t x, int64_t z,
int64_t w, int64_t h, Pos *qplist, int n)
{
const int64_t m = (1LL << lbitn);
const int64_t A = 341873128712LL;
const uint64_t m = (1ULL << lbitn);
const uint64_t A = 341873128712ULL;
// for lbitn=20: invB = 132477LL;
if (n < 1)
@ -773,13 +780,13 @@ int scanForQuadBits(const StructureConfig sconf, int radius, int64_t s48,
int cnt = 0;
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));
if (j < z)
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)
continue;
@ -798,18 +805,18 @@ int scanForQuadBits(const StructureConfig sconf, int radius, int64_t s48,
}
int scanForQuads(
const StructureConfig sconf, int radius, int64_t s48,
const int64_t *lowBits, int lowBitCnt, int lowBitN, int64_t salt,
const StructureConfig sconf, int radius, uint64_t s48,
const uint64_t *lowBits, int lowBitCnt, int lowBitN, uint64_t salt,
int x, int z, int w, int h, Pos *qplist, int n)
{
int i, cnt = 0;
int64_t invB;
uint64_t invB;
if (lowBitN == 20)
invB = 132477LL;
invB = 132477ULL;
else if (lowBitN == 48)
invB = 211541297333629LL;
invB = 211541297333629ULL;
else
invB = mulInv(132897987541LL, (1LL << lowBitN));
invB = mulInv(132897987541ULL, (1ULL << lowBitN));
for (i = 0; i < lowBitCnt; i++)
{
@ -846,7 +853,7 @@ Pos findBiomePosition(
const int centerZ,
const int range,
const char *isValid,
int64_t *seed,
uint64_t *seed,
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;
int64_t rnds;
uint64_t rnds;
Pos p;
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,
Pos *locations, int64_t worldSeed, int maxSH, int maxRing)
Pos *locations, uint64_t worldSeed, int maxSH, int maxRing)
{
const char *validStrongholdBiomes = getValidStrongholdBiomes(mc);
int i, x, z;
@ -1089,7 +1096,7 @@ int findStrongholds(const int mc, const LayerStack *g, int *cache,
int currentRing = 0;
int currentCount = 0;
int perRing = 3;
int64_t rnd;
uint64_t rnd;
setSeed(&rnd, worldSeed);
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;
// 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();
Pos spawn;
@ -1238,7 +1245,7 @@ Pos getSpawn(const int mcversion, const LayerStack *g, int *cache, int64_t world
int i;
const Layer *l = &g->layers[L_RIVER_MIX_4];
int64_t rnd;
uint64_t rnd;
setSeed(&rnd, worldSeed);
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();
Pos spawn;
int found;
const Layer *l = &g->layers[L_RIVER_MIX_4];
int64_t rnd;
uint64_t rnd;
setSeed(&rnd, worldSeed);
spawn = findBiomePosition(mcversion, l, cache, 0, 0, 256, isSpawnBiome,
&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,
int64_t seed, int blockX, int blockZ)
uint64_t seed, int blockX, int blockZ)
{
int *ids = NULL;
Layer *l;
@ -1671,7 +1678,7 @@ L_feature:
{
if (mc < MC_1_14)
goto L_not_viable;
int64_t rnd = seed;
uint64_t rnd = seed;
setAttemptSeed(&rnd, chunkX, chunkZ);
if (nextInt(&rnd, 5) != 0)
goto L_not_viable;
@ -1787,7 +1794,7 @@ L_not_viable:
}
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)
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,
int64_t seed, int blockX, int blockZ)
uint64_t seed, int blockX, int blockZ)
{
if (structureType != End_City || mc < MC_1_9)
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],
y0, y1, 4, (blockX & 7) / 8.0, (blockZ & 7) / 8.0);
int64_t cs;
setSeed(&cs, chunkX + chunkZ * 10387313LL);
uint64_t cs;
setSeed(&cs, chunkX + chunkZ * 10387313ULL);
switch (nextInt(&cs, 4))
{
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 };
if (!isViableFeatureBiome(mc, Village, biomeID))
return r;
int64_t rnd = chunkGenerateRnd(seed, blockX >> 4, blockZ >> 4);
uint64_t rnd = chunkGenerateRnd(seed, blockX >> 4, blockZ >> 4);
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)
{
int64_t rnd = chunkGenerateRnd(worldSeed, chunkX, chunkZ);
uint64_t rnd = chunkGenerateRnd(worldSeed, chunkX, chunkZ);
skipNextN(&rnd, 1);
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;
if (specialcnt > 0)
{
int64_t ss = l->startSeed;
int64_t cs;
uint64_t ss = l->startSeed;
uint64_t cs;
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)))
{
int64_t ss = l->startSeed;
int64_t cs;
uint64_t ss = l->startSeed;
uint64_t cs;
for (j = 0; j < h; j++)
{
@ -2579,7 +2586,7 @@ int checkForBiomes(
LayerStack * g,
int layerID,
int * cache,
int64_t seed,
uint64_t seed,
int x,
int z,
unsigned int w,
@ -2600,7 +2607,7 @@ int checkForBiomes(
int bw = w * l->scale;
int bh = h * l->scale;
int x0, z0, x1, z1;
int64_t ss, cs;
uint64_t ss, cs;
uint64_t potential, required;
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
int64_t ss = getStartSeed(seed, ls);
uint64_t ls = getLayerSalt(3); // L_SPECIAL_1024 layer seed
uint64_t ss = getStartSeed(seed, ls);
int i, j;
int scnt = 0;
@ -2865,15 +2872,10 @@ int canBiomeGenerate(int layerId, int mc, int id)
if (dofilter || layerId == L_RIVER_MIX_4)
{
dofilter = 1;
switch (id)
{
case frozen_ocean:
if (mc >= MC_1_7)
return 0;
break;
case warm_ocean...deep_frozen_ocean:
if (id == frozen_ocean && mc >= MC_1_7)
return 0;
if (isDeepOcean(id) && id != deep_ocean)
return 0;
}
}
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
double angle; // next angle within ring
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
};
@ -201,13 +201,13 @@ STRUCT(VillageType)
// lower 20 bits, only the very best constellations
// (the structure salt has to be subtracted before use)
static const int64_t low20QuadIdeal[] =
static const uint64_t low20QuadIdeal[] =
{
0x43f18,0xc751a,0xf520a,
};
// lower 20 bits, the classic quad-structure constellations
static const int64_t low20QuadClassic[] =
static const uint64_t low20QuadClassic[] =
{
0x43f18,0x79a0a,0xc751a,0xf520a,
};
@ -215,7 +215,7 @@ static const int64_t low20QuadClassic[] =
// 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,
// 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,
0xc751a,0xf520a,
@ -223,7 +223,7 @@ static const int64_t low20QuadHutNormal[] =
// 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
static const int64_t low20QuadHutBarely[] =
static const uint64_t low20QuadHutBarely[] =
{
0x1272d,0x17908,0x367b9,0x43f18, 0x487c9,0x487ce,0x50aa7,0x647b5,
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
* vector, (regX, regZ).
*/
static inline int64_t moveStructure(const int64_t baseSeed,
const int regX, const int regZ)
static inline uint64_t moveStructure(uint64_t baseSeed, int regX, int regZ)
{
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.
*/
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.
*/
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
* 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.
*/
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))
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))
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))
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.
* 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.
*/
int isMineshaftChunk(int64_t seed, int chunkX, int chunkZ);
int isMineshaftChunk(uint64_t seed, int chunkX, int chunkZ);
// not exacly a structure
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 * chunkX * 0x4c1906);
rnd += (int)(chunkZ * 0x5f24f);
rnd += (int)(chunkZ * chunkZ) * 0x4307a7LL;
rnd ^= 0x3ad8025fLL;
rnd += (int)(chunkZ * chunkZ) * 0x4307a7ULL;
rnd ^= 0x3ad8025fULL;
setSeed(&rnd, rnd);
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
* 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
* 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.
*/
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))
float isQuadBaseFeature24 (const StructureConfig sconf, int64_t seed,
float isQuadBaseFeature24 (const StructureConfig sconf, uint64_t seed,
int ax, int ay, int az);
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);
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);
@ -425,14 +424,14 @@ float isQuadBaseLarge (const StructureConfig sconf, int64_t seed,
* Returns zero upon success.
*/
int searchAll48(
int64_t ** seedbuf,
int64_t * buflen,
uint64_t ** seedbuf,
uint64_t * buflen,
const char * path,
int threads,
const int64_t * lowBits,
const uint64_t * lowBits,
int lowBitCnt,
int lowBitN,
int (*check)(int64_t s48, void *data),
int (*check)(uint64_t s48, 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').
*/
int scanForQuads(
const StructureConfig sconf, int radius, int64_t s48,
const int64_t *lowBits, int lowBitCnt, int lowBitN, int64_t salt,
const StructureConfig sconf, int radius, uint64_t s48,
const uint64_t *lowBits, int lowBitCnt, int lowBitN, uint64_t salt,
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.
*/
static inline int64_t getShadow(int64_t seed)
static inline uint64_t getShadow(uint64_t seed)
{
return -7379792620528906219LL - seed;
}
@ -514,7 +513,7 @@ Pos findBiomePosition(
const int centerZ,
const int range,
const char * isValid,
int64_t * seed,
uint64_t * seed,
int * passes
);
@ -555,7 +554,7 @@ int areBiomesViable(
*
* 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
* location, as well as the approximate location of the next stronghold.
@ -590,7 +589,7 @@ int findStrongholds(
const LayerStack * g,
int * cache,
Pos * locations,
int64_t worldSeed,
uint64_t worldSeed,
int maxSH,
int maxRing
);
@ -604,7 +603,7 @@ int findStrongholds(
* @cache : biome buffer, set to NULL for temporary allocation
* @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.
*
@ -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
* @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.
*/
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,
int64_t seed, int blockX, int blockZ);
uint64_t seed, int blockX, int blockZ);
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.
*/
@ -659,17 +658,17 @@ int isViableEndCityTerrain(const EndNoise *en, const SurfaceNoise *sn,
* This random object is used for recursiveGenerate() which is responsible for
* 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)
{
int64_t rnd;
uint64_t rnd;
setSeed(&rnd, worldSeed);
rnd = (nextLong(&rnd) * chunkX) ^ (nextLong(&rnd) * chunkZ) ^ worldSeed;
setSeed(&rnd, 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
@ -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.
*/
int64_t getHouseList(const int64_t worldSeed, const int chunkX, const int chunkZ,
int *housesOut);
uint64_t getHouseList(uint64_t worldSeed, int chunkX, int chunkZ, int *housesOut);
//==============================================================================
@ -713,7 +711,7 @@ int checkForBiomes(
LayerStack * g,
int layerID,
int * cache,
int64_t seed,
uint64_t seed,
int x,
int z,
unsigned int w,
@ -730,7 +728,7 @@ int checkForBiomes(
* Oceanic, Warm, Lush, Cold, Freeing, Special+Warm, Special+Lush, Special+Cold
* 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.
* 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))
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.
@ -764,54 +762,55 @@ Pos getFeatureChunkInRegion(StructureConfig config, int64_t seed, int regX, int
pos.z = nextInt(&seed, 24);
*/
Pos pos;
const int64_t K = 0x5deece66dLL;
const int64_t M = (1ULL << 48) - 1;
const int64_t b = 0xb;
const uint64_t K = 0x5deece66dULL;
const uint64_t M = (1ULL << 48) - 1;
const uint64_t b = 0xb;
// set seed
seed = seed + regX*341873128712 + regZ*132897987541 + config.salt;
seed = seed + regX*341873128712ULL + regZ*132897987541ULL + config.salt;
seed = (seed ^ K);
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;
pos.z = (int)(seed >> 17) % config.chunkRange;
pos.z = (int)(seed >> 17) % r;
}
else
{
// 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;
pos.z = (config.chunkRange * (seed >> 17)) >> 31;
pos.z = (int)((r * (seed >> 17)) >> 31);
}
return pos;
}
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.x = ((regX*config.regionSize + pos.x) << 4);
pos.z = ((regZ*config.regionSize + pos.z) << 4);
pos.x = (int)(((uint64_t)regX*config.regionSize + pos.x) << 4);
pos.z = (int)(((uint64_t)regZ*config.regionSize + pos.z) << 4);
return pos;
}
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;
const int64_t K = 0x5deece66dLL;
const int64_t M = (1ULL << 48) - 1;
const int64_t b = 0xb;
const uint64_t K = 0x5deece66dULL;
const uint64_t M = (1ULL << 48) - 1;
const uint64_t b = 0xb;
//TODO: power of two chunk ranges...
// set seed
seed = seed + regX*341873128712 + regZ*132897987541 + config.salt;
seed = seed + regX*341873128712ULL + regZ*132897987541ULL + config.salt;
seed = (seed ^ K);
seed = (seed * K + b) & M;
@ -831,14 +830,12 @@ Pos getLargeStructureChunkInRegion(StructureConfig config, int64_t seed, int reg
}
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.x = regX*config.regionSize + pos.x;
pos.z = regZ*config.regionSize + pos.z;
pos.x = pos.x*16;
pos.z = pos.z*16;
pos.x = (int)(((uint64_t)regX*config.regionSize + pos.x) << 4);
pos.z = (int)(((uint64_t)regZ*config.regionSize + pos.z) << 4);
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)
{
@ -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
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)
{
seed += sconf.salt;
int64_t s00 = seed;
int64_t s11 = 341873128712 + 132897987541 + seed;
const int64_t K = 0x5deece66dLL;
uint64_t s00 = seed;
uint64_t s11 = 341873128712ULL + 132897987541ULL + seed;
const uint64_t K = 0x5deece66dULL;
int x0, z0, x1, z1, x2, z2, x3, z3;
int x, z;
@ -960,8 +957,8 @@ float isQuadBaseFeature24(const StructureConfig sconf, int64_t seed,
if (x*x + z*z > 255)
return 0;
int64_t s01 = 341873128712 + seed;
int64_t s10 = 132897987541 + seed;
uint64_t s01 = 341873128712ULL + seed;
uint64_t s10 = 132897987541ULL + seed;
s01 ^= K;
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
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;
int64_t s00 = seed;
int64_t s11 = 341873128712 + 132897987541 + seed;
const int64_t K = 0x5deece66dLL;
uint64_t s00 = seed;
uint64_t s11 = 341873128712ULL + 132897987541ULL + seed;
const uint64_t K = 0x5deece66dULL;
int p;
// 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;
int64_t s01 = 341873128712 + seed;
int64_t s10 = 132897987541 + seed;
uint64_t s01 = 341873128712ULL + seed;
uint64_t s10 = 132897987541ULL + seed;
s01 ^= K;
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))
float isQuadBaseFeature(const StructureConfig sconf, int64_t seed,
float isQuadBaseFeature(const StructureConfig sconf, uint64_t seed,
int ax, int ay, int az, int radius)
{
seed += sconf.salt;
int64_t s00 = seed;
int64_t s11 = 341873128712 + 132897987541 + seed;
const int64_t M = (1ULL << 48) - 1;
const int64_t K = 0x5deece66dLL;
const int64_t b = 0xbLL;
uint64_t s00 = seed;
uint64_t s11 = 341873128712ULL + 132897987541ULL + seed;
const uint64_t M = (1ULL << 48) - 1;
const uint64_t K = 0x5deece66dULL;
const uint64_t b = 0xb;
int x0, z0, x1, z1, x2, z2, x3, z3;
int x, z;
@ -1037,7 +1034,7 @@ float isQuadBaseFeature(const StructureConfig sconf, int64_t seed,
int cd = radius/8;
int rm = R - (int)sqrtf(cd*cd - (R-C+1)*(R-C+1));
int64_t s;
uint64_t s;
s = s00 ^ K;
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)
return 0;
int64_t s01 = 341873128712 + seed;
int64_t s10 = 132897987541 + seed;
uint64_t s01 = 341873128712ULL + seed;
uint64_t s10 = 132897987541ULL + seed;
s = s01 ^ K;
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))
float isQuadBaseLarge(const StructureConfig sconf, int64_t seed,
float isQuadBaseLarge(const StructureConfig sconf, uint64_t seed,
int ax, int ay, int az, int radius)
{
// 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
// complete list of bases see the implementation of cubiomes-viewer.
const int64_t M = (1ULL << 48) - 1;
const int64_t K = 0x5deece66dLL;
const int64_t b = 0xbLL;
const uint64_t M = (1ULL << 48) - 1;
const uint64_t K = 0x5deece66dULL;
const uint64_t b = 0xb;
seed += sconf.salt;
int64_t s00 = seed;
int64_t s01 = 341873128712 + seed;
int64_t s10 = 132897987541 + seed;
int64_t s11 = 341873128712 + 132897987541 + seed;
uint64_t s00 = seed;
uint64_t s01 = 341873128712ULL + seed;
uint64_t s10 = 132897987541ULL + seed;
uint64_t s11 = 341873128712ULL + 132897987541ULL + seed;
// p1 = nextInt(range); p2 = nextInt(range); pos = (p1+p2)>>1
const int R = sconf.regionSize;
const int C = sconf.chunkRange;
int rm = (int)(2 * R + ((ax<az?ax:az) - 2*radius + 7) / 8);
int64_t s;
uint64_t s;
int p;
int x0,z0,x1,z1,x2,z2,x3,z3;
@ -1121,7 +1118,7 @@ float isQuadBaseLarge(const StructureConfig sconf, int64_t seed,
z1 = p;
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;
s = s01 ^ K;

View File

@ -7,7 +7,7 @@
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;
l->getMap = map;
@ -15,7 +15,10 @@ Layer *setupLayer(LayerStack *g, int layerId, mapfunc_t *map, int mc,
l->zoom = zoom;
l->edge = edge;
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->startSeed = 0;
l->noise = NULL;
@ -184,7 +187,7 @@ static void setupGeneratorImpl(LayerStack *g, int mc, int largeBiomes)
if (mc <= MC_1_14)
p = setupLayer(g, L_VORONOI_1, mapVoronoi114, mc, 4, 7, 10, p, 0);
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;
@ -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
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)
{
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);
if (err)
return err;
Layer lvoronoi = {0};
Layer lvoronoi;
memset(&lvoronoi, 0, sizeof(Layer));
lvoronoi.startSalt = getVoronoiSHA(seed);
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)
{
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);
if (err)
return err;
Layer lvoronoi = {0};
Layer lvoronoi;
memset(&lvoronoi, 0, sizeof(Layer));
if (mc >= MC_1_15)
{
lvoronoi.startSalt = getVoronoiSHA(seed);

View File

@ -3,6 +3,7 @@
#include "layers.h"
/* Enumeration of the layer indices in the generator. */
enum
{
@ -110,10 +111,10 @@ int *allocCache(const Layer *layer, int sizeX, int sizeZ);
/* Set up custom layers. */
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 */
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
* 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)
* @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 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);

View File

@ -7,23 +7,26 @@
/********************** 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);
return (int) (*seed >> (48 - bits));
*seed = (*seed * 0x5deece66d + 0xb) & ((1ULL << 48) - 1);
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;
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 {
bits = next(seed, 31);
@ -33,19 +36,22 @@ static inline int nextInt(int64_t *seed, const int n)
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);
}
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)
@ -54,13 +60,13 @@ static inline double nextDouble(int64_t *seed)
*/
#define JAVA_NEXT_INT24(S,X) \
do { \
int64_t a = (1ULL << 48) - 1; \
int64_t c = 0x5deece66dLL * (S); \
uint64_t a = (1ULL << 48) - 1; \
uint64_t c = 0x5deece66dULL * (S); \
c += 11; a &= c; \
(S) = a; \
a >>= 17; \
a = (uint64_t) ((int64_t)a >> 17); \
c = 0xaaaaaaab * a; \
c >>= 36; \
c = (uint64_t) ((int64_t)c >> 36); \
(X) = (int)a - (int)(c << 3) * 3; \
} 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.
*/
static inline void skipNextN(int64_t *seed, uint64_t n)
static inline void skipNextN(uint64_t *seed, uint64_t n)
{
int64_t m = 1;
int64_t a = 0;
int64_t im = 0x5deece66dLL;
int64_t ia = 0xbLL;
uint64_t m = 1;
uint64_t a = 0;
uint64_t im = 0x5deece66dULL;
uint64_t ia = 0xb;
uint64_t k;
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 &= 0xffffffffffffLL;
}
/* 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;
*seed &= 0xffffffffffffULL;
}
/* 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))
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;
if (m <= 1)
uint64_t t, q, a, b, n;
if ((int64_t)m <= 1)
return 0; // no solution
n = m;
a = 0; b = 1;
while (x > 1)
while ((int64_t)x > 1)
{
if (m == 0)
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;
}
if (b < 0)
if ((int64_t)b < 0)
b += n;
return b;
}

177
layers.c
View File

@ -11,18 +11,14 @@
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)
{
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:
return mc >= MC_1_9;
case sunflower_plains:
@ -50,7 +46,10 @@ int biomeExists(int mc, int id)
case bamboo_jungle:
case bamboo_jungle_hills:
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;
case dripstone_caves:
case lush_caves:
@ -65,6 +64,9 @@ int isOverworld(int mc, int id)
if (!biomeExists(mc, id))
return 0;
if (id >= small_end_islands && id <= end_barrens) return 0;
if (id >= soul_sand_valley && id <= basalt_deltas) return 0;
switch (id)
{
case nether_wastes:
@ -74,15 +76,13 @@ int isOverworld(int mc, int id)
return mc <= MC_1_6 || mc >= MC_1_13;
case mountain_edge:
return mc <= MC_1_6;
case small_end_islands...end_barrens:
case deep_warm_ocean:
case the_void:
return 0;
case tall_birch_hills:
return mc <= MC_1_8 || mc >= MC_1_11;
case soul_sand_valley...basalt_deltas:
return 0;
case dripstone_caves...lush_caves:
case dripstone_caves:
case lush_caves:
return 0;
}
return 1;
@ -321,8 +321,7 @@ void initBiomes()
{
}
void setLayerSeed(Layer *layer, int64_t worldSeed)
void setLayerSeed(Layer *layer, uint64_t worldSeed)
{
if (layer->p2 != NULL)
setLayerSeed(layer->p2, worldSeed);
@ -332,25 +331,25 @@ void setLayerSeed(Layer *layer, int64_t worldSeed)
if (layer->noise != NULL)
{
int64_t s;
uint64_t s;
setSeed(&s, worldSeed);
perlinInit((PerlinNoise*)layer->noise, &s);
}
int64_t ls = layer->layerSalt;
if (ls == 0) // Pre 1.13 the Hills branch stays zero-initialized
{
uint64_t ls = layer->layerSalt;
if (ls == 0)
{ // Pre 1.13 the Hills branch stays zero-initialized
layer->startSalt = 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->startSeed = 0;
}
else
{
int64_t st = worldSeed;
uint64_t st = worldSeed;
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;
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 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)
{ // require: len >= 1 && omin+len <= 0
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)
{
rnd->xzScale = xzScale;
@ -608,9 +607,9 @@ void initSurfaceNoise(SurfaceNoise *rnd, int64_t *seed,
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);
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
//==============================================================================
void setNetherSeed(NetherNoise *nn, int64_t seed)
void setNetherSeed(NetherNoise *nn, uint64_t seed)
{
int64_t s;
uint64_t s;
setSeed(&s, seed);
doublePerlinInit(&nn->temperature, &s, &nn->oct[0], &nn->oct[2], -7, 2);
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);
skipNextN(&s, 17292);
perlinInit(en, &s);
@ -1010,7 +1009,7 @@ int getSurfaceHeight(
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;
@ -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)
{
int64_t ss = l->startSeed;
int64_t cs;
uint64_t ss = l->startSeed;
uint64_t cs;
int i, 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 *buf = (int*) malloc((newW+1)*(newH+1)*sizeof(*buf));
const int st = (int)l->startSalt;
const int ss = (int)l->startSeed;
const uint32_t st = (uint32_t)l->startSalt;
const uint32_t ss = (uint32_t)l->startSeed;
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;
}
int chunkX = (i + pX) << 1;
int chunkZ = (j + pZ) << 1;
int chunkX = (int)((uint32_t)(i + pX) << 1);
int chunkZ = (int)((uint32_t)(j + pZ) << 1);
int cs = ss;
uint32_t cs = ss;
cs += chunkX;
cs *= cs * 1284865837 + 4150755663;
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 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 *buf = (int*) malloc((newW+1)*(newH+1)*sizeof(*buf));
const int st = (int)l->startSalt;
const int ss = (int)l->startSeed;
const uint32_t st = (uint32_t)l->startSalt;
const uint32_t ss = (uint32_t)l->startSeed;
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;
}
int chunkX = (i + pX) << 1;
int chunkZ = (j + pZ) << 1;
int chunkX = (int)((uint32_t)(i + pX) << 1);
int chunkZ = (int)((uint32_t)(j + pZ) << 1);
int cs = ss;
uint32_t cs = ss;
cs += chunkX;
cs *= cs * 1284865837 + 4150755663;
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)
return err;
int64_t st = l->startSalt;
int64_t ss = l->startSeed;
int64_t cs;
uint64_t st = l->startSalt;
uint64_t ss = l->startSeed;
uint64_t cs;
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)
return err;
int64_t st = l->startSalt;
int64_t ss = l->startSeed;
int64_t cs;
uint64_t st = l->startSalt;
uint64_t ss = l->startSeed;
uint64_t cs;
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)
return err;
int64_t ss = l->startSeed;
int64_t cs;
uint64_t ss = l->startSeed;
uint64_t cs;
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)
return err;
int64_t ss = l->startSeed;
int64_t cs;
uint64_t ss = l->startSeed;
uint64_t cs;
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)
return err;
int64_t ss = l->startSeed;
int64_t cs;
uint64_t ss = l->startSeed;
uint64_t cs;
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)
return err;
int64_t st = l->startSalt;
int64_t ss = l->startSeed;
int64_t cs;
uint64_t st = l->startSalt;
uint64_t ss = l->startSeed;
uint64_t cs;
int i, 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)
return err;
int64_t ss = l->startSeed;
int64_t cs;
uint64_t ss = l->startSeed;
uint64_t cs;
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;
int mc = l->mc;
int64_t ss = l->startSeed;
int64_t cs;
uint64_t ss = l->startSeed;
uint64_t cs;
int i, 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)
return err;
int64_t ss = l->startSeed;
int64_t cs;
uint64_t ss = l->startSeed;
uint64_t cs;
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)
return err;
int64_t ss = l->startSeed;
int64_t cs;
uint64_t ss = l->startSeed;
uint64_t cs;
int i, 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;
int64_t st = l->startSalt;
int64_t ss = l->startSeed;
int64_t cs;
uint64_t st = l->startSalt;
uint64_t ss = l->startSeed;
uint64_t cs;
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)
return err;
int64_t ss = l->startSeed;
int64_t cs;
uint64_t ss = l->startSeed;
uint64_t cs;
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)
{
cs = getChunkSeed(ss, i+x, j+z);
if (cs & ((int64_t)1 << 24))
if (cs & ((uint64_t)1 << 24))
v11 = v10;
else
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)
return err;
int64_t ss = l->startSeed;
int64_t cs;
uint64_t ss = l->startSeed;
uint64_t cs;
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)
return err;
int64_t ss = l->startSeed;
int64_t cs;
uint64_t ss = l->startSeed;
uint64_t cs;
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,
int *x, int *y, int *z)
{
int64_t s = sha;
uint64_t s = sha;
s = mcStepSeed(s, a);
s = mcStepSeed(s, b);
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;
}
int64_t sha = l->startSalt;
uint64_t sha = l->startSalt;
int *buf = (int *) malloc(w*h*sizeof(*buf));
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 i, j;
int64_t st = l->startSalt;
int64_t ss = l->startSeed;
int64_t cs;
uint64_t st = l->startSalt;
uint64_t ss = l->startSeed;
uint64_t cs;
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))
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] = {
0x428a2f98,0x71374491, 0xb5c0fbcf,0xe9b5dba5,
@ -3091,10 +3090,10 @@ int64_t getVoronoiSHA(int64_t seed)
a0 += B[0];
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;
y -= 2;

View File

@ -25,6 +25,9 @@
#define U(COND) (COND)
#endif
#define LAYER_INIT_SHA (~0ULL)
/* Minecraft versions */
enum MCversion
{
@ -172,9 +175,9 @@ STRUCT(Layer)
int8_t edge; // maximum border required from parent layer
int scale; // scale of this layer (cell = scale x scale blocks)
int64_t layerSalt; // processed salt or initialization mode
int64_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 layerSalt; // processed salt or initialization mode
uint64_t startSalt; // (depends on world seed) used to step PRNG forward
uint64_t startSeed; // (depends on world seed) starting point for chunk seeds
void *noise; // (depends on world seed) noise map data
void *data; // generic data for custom layers
@ -215,30 +218,30 @@ extern "C"
void initBiomes();
/* 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
//==============================================================================
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 yamp, double ymin);
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);
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);
double sampleDoublePerlin(const DoublePerlinNoise *rnd,
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);
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);
@ -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
* 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 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,
@ -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
* 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 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)
*/
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)
ret += mod;
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, x);
cs = mcStepSeed(cs, z);
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);
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);
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 = mcStepSeed(ss, 0);
return ss;
@ -411,8 +414,8 @@ mapfunc_t mapVoronoi114;
// 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.
// 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));
void voronoiAccess3D(int64_t sha, int x, int y, int z, int *x4, int *y4, int *z4);
uint64_t getVoronoiSHA(uint64_t worldSeed) __attribute__((const));
void voronoiAccess3D(uint64_t sha, int x, int y, int z, int *x4, int *y4, int *z4);
#ifdef __cplusplus