diff --git a/finders.c b/finders.c index b0ea6e6..c10a58d 100644 --- a/finders.c +++ b/finders.c @@ -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)) { diff --git a/finders.h b/finders.h index eaf7dd3..2f44d78 100644 --- a/finders.h +++ b/finders.h @@ -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>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; diff --git a/generator.c b/generator.c index da89f78..c56b32e 100644 --- a/generator.c +++ b/generator.c @@ -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); diff --git a/generator.h b/generator.h index f14f81b..22538dc 100644 --- a/generator.h +++ b/generator.h @@ -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); diff --git a/javarnd.h b/javarnd.h index bc9964f..9141210 100644 --- a/javarnd.h +++ b/javarnd.h @@ -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; } diff --git a/layers.c b/layers.c index 9edabac..134c5ec 100644 --- a/layers.c +++ b/layers.c @@ -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; diff --git a/layers.h b/layers.h index 873c73f..c8c5c7f 100644 --- a/layers.h +++ b/layers.h @@ -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