mirror of
https://github.com/Cubitect/cubiomes.git
synced 2025-09-23 11:45:27 -04:00
Nether generation + 1.15 voronoi + setWorldSeed -> setLayerSeed
1) added noise generators 2) added initial support for nether biome generation 3) added sha256 from Brad Conte for 1.15 voronoi zoom 4) ranamed setWorldSeed to setLayerSeed
This commit is contained in:
parent
b2d122cf7f
commit
c0b6005909
122
finders.c
122
finders.c
@ -77,7 +77,7 @@ int64_t *loadSavedSeeds(const char *fnam, int64_t *scnt)
|
||||
static int testOutpostPos(int64_t s, int cx, int cz)
|
||||
{
|
||||
s ^= (cx >> 4) ^ ( (cz >> 4) << 4 );
|
||||
setSeed(&s);
|
||||
setSeed(&s, s);
|
||||
next(&s, 32);
|
||||
return nextInt(&s, 5) == 0;
|
||||
}
|
||||
@ -129,19 +129,19 @@ Pos getStructurePos(StructureConfig config, int64_t seed, int regX, int regZ, in
|
||||
|
||||
int isMineshaftChunk(int64_t seed, int chunkX, int chunkZ)
|
||||
{
|
||||
int64_t s = seed;
|
||||
setSeed(&s);
|
||||
int64_t s;
|
||||
setSeed(&s, seed);
|
||||
int64_t i = nextLong(&s);
|
||||
int64_t j = nextLong(&s);
|
||||
s = chunkX * i ^ chunkZ * j ^ seed;
|
||||
setSeed(&s);
|
||||
setSeed(&s, s);
|
||||
return nextDouble(&s) < 0.004;
|
||||
}
|
||||
|
||||
int isTreasureChunk(int64_t seed, int chunkX, int chunkZ)
|
||||
{
|
||||
seed = chunkX*341873128712 + chunkZ*132897987541 + seed + TREASURE_CONFIG.salt;
|
||||
setSeed(&seed);
|
||||
setSeed(&seed, seed);
|
||||
return nextFloat(&seed) < 0.01;
|
||||
}
|
||||
|
||||
@ -959,8 +959,7 @@ Pos initFirstStronghold(StrongholdIter *sh, int mc, int64_t s48)
|
||||
int64_t rnds;
|
||||
Pos p;
|
||||
|
||||
rnds = s48;
|
||||
setSeed(&rnds);
|
||||
setSeed(&rnds, s48);
|
||||
|
||||
angle = 2.0 * PI * nextDouble(&rnds);
|
||||
if (mc >= MC_1_9)
|
||||
@ -1034,9 +1033,10 @@ int findStrongholds(const int mcversion, const LayerStack *g, int *cache,
|
||||
int currentRing = 0;
|
||||
int currentCount = 0;
|
||||
int perRing = 3;
|
||||
int64_t rnd;
|
||||
|
||||
setSeed(&worldSeed); // PRNG
|
||||
double angle = nextDouble(&worldSeed) * PI * 2.0;
|
||||
setSeed(&rnd, worldSeed);
|
||||
double angle = nextDouble(&rnd) * PI * 2.0;
|
||||
|
||||
const Layer *l = &g->layers[L_RIVER_MIX_4];
|
||||
|
||||
@ -1047,14 +1047,14 @@ int findStrongholds(const int mcversion, const LayerStack *g, int *cache,
|
||||
for (i = 0; i < maxSH; i++)
|
||||
{
|
||||
distance = (4.0 * 32.0) + (6.0 * currentRing * 32.0) +
|
||||
(nextDouble(&worldSeed) - 0.5) * 32 * 2.5;
|
||||
(nextDouble(&rnd) - 0.5) * 32 * 2.5;
|
||||
|
||||
x = (int)round(cos(angle) * distance);
|
||||
z = (int)round(sin(angle) * distance);
|
||||
|
||||
locations[i] = findBiomePosition(mcversion, l, cache,
|
||||
(x << 4) + 8, (z << 4) + 8, 112, validStrongholdBiomes,
|
||||
&worldSeed, NULL);
|
||||
&rnd, NULL);
|
||||
|
||||
angle += 2 * PI / perRing;
|
||||
|
||||
@ -1073,7 +1073,7 @@ int findStrongholds(const int mcversion, const LayerStack *g, int *cache,
|
||||
perRing = perRing + 2*perRing/(currentRing+1);
|
||||
if (perRing > 128-i)
|
||||
perRing = 128-i;
|
||||
angle = angle + nextDouble(&worldSeed) * PI * 2.0;
|
||||
angle = angle + nextDouble(&rnd) * PI * 2.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1083,14 +1083,14 @@ int findStrongholds(const int mcversion, const LayerStack *g, int *cache,
|
||||
|
||||
for (i = 0; i < maxSH; i++)
|
||||
{
|
||||
distance = (1.25 + nextDouble(&worldSeed)) * 32.0;
|
||||
distance = (1.25 + nextDouble(&rnd)) * 32.0;
|
||||
|
||||
x = (int)round(cos(angle) * distance);
|
||||
z = (int)round(sin(angle) * distance);
|
||||
|
||||
locations[i] = findBiomePosition(mcversion, l, cache,
|
||||
(x << 4) + 8, (z << 4) + 8, 112, validStrongholdBiomes,
|
||||
&worldSeed, NULL);
|
||||
&rnd, NULL);
|
||||
|
||||
angle += 2 * PI / 3.0;
|
||||
}
|
||||
@ -1182,10 +1182,11 @@ 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;
|
||||
|
||||
setSeed(&worldSeed);
|
||||
setSeed(&rnd, worldSeed);
|
||||
spawn = findBiomePosition(mcversion, l, cache, 0, 0, 256, isSpawnBiome,
|
||||
&worldSeed, &found);
|
||||
&rnd, &found);
|
||||
|
||||
if (!found)
|
||||
{
|
||||
@ -1274,8 +1275,8 @@ Pos getSpawn(const int mcversion, const LayerStack *g, int *cache, int64_t world
|
||||
break;
|
||||
}
|
||||
|
||||
spawn.x += nextInt(&worldSeed, 64) - nextInt(&worldSeed, 64);
|
||||
spawn.z += nextInt(&worldSeed, 64) - nextInt(&worldSeed, 64);
|
||||
spawn.x += nextInt(&rnd, 64) - nextInt(&rnd, 64);
|
||||
spawn.z += nextInt(&rnd, 64) - nextInt(&rnd, 64);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1290,10 +1291,10 @@ Pos estimateSpawn(const int mcversion, const LayerStack *g, int *cache, int64_t
|
||||
int found;
|
||||
|
||||
const Layer *l = &g->layers[L_RIVER_MIX_4];
|
||||
|
||||
setSeed(&worldSeed);
|
||||
int64_t rnd;
|
||||
setSeed(&rnd, worldSeed);
|
||||
spawn = findBiomePosition(mcversion, l, cache, 0, 0, 256, isSpawnBiome,
|
||||
&worldSeed, &found);
|
||||
&rnd, &found);
|
||||
|
||||
if (!found)
|
||||
{
|
||||
@ -1575,7 +1576,7 @@ L_feature:
|
||||
biomeX = (chunkX << 2) + 2;
|
||||
biomeZ = (chunkZ << 2) + 2;
|
||||
}
|
||||
setWorldSeed(l, seed);
|
||||
setLayerSeed(l, seed);
|
||||
map = allocCache(l, 1, 1);
|
||||
if (genArea(l, map, biomeX, biomeZ, 1, 1))
|
||||
goto L_not_viable;
|
||||
@ -1587,7 +1588,7 @@ L_feature:
|
||||
l = &g->layers[L_RIVER_MIX_4];
|
||||
biomeX = (chunkX << 2) + 2;
|
||||
biomeZ = (chunkZ << 2) + 2;
|
||||
setWorldSeed(l, seed);
|
||||
setLayerSeed(l, seed);
|
||||
map = allocCache(l, 1, 1);
|
||||
if (genArea(l, map, biomeX, biomeZ, 1, 1))
|
||||
goto L_not_viable;
|
||||
@ -1612,7 +1613,7 @@ L_feature:
|
||||
biomeX = (chunkX << 2) + 2;
|
||||
biomeZ = (chunkZ << 2) + 2;
|
||||
}
|
||||
setWorldSeed(l, seed);
|
||||
setLayerSeed(l, seed);
|
||||
map = allocCache(l, 1, 1);
|
||||
if (genArea(l, map, biomeX, biomeZ, 1, 1))
|
||||
goto L_not_viable;
|
||||
@ -1647,7 +1648,7 @@ L_feature:
|
||||
else if (mc == MC_1_8)
|
||||
{ // In 1.8 monuments require only a single deep ocean block.
|
||||
l = g->entry_1;
|
||||
setWorldSeed(l, seed);
|
||||
setLayerSeed(l, seed);
|
||||
map = allocCache(l, 1, 1);
|
||||
if (genArea(l, map, (chunkX << 4) + 8, (chunkZ << 4) + 8, 1, 1))
|
||||
goto L_not_viable;
|
||||
@ -1656,7 +1657,7 @@ L_feature:
|
||||
{ // Monuments require two viability checks with the ocean layer
|
||||
// branch => worth checking for potential deep ocean beforehand.
|
||||
l = &g->layers[L_SHORE_16];
|
||||
setWorldSeed(l, seed);
|
||||
setLayerSeed(l, seed);
|
||||
map = allocCache(l, 1, 1);
|
||||
if (genArea(l, map, chunkX, chunkZ, 1, 1))
|
||||
goto L_not_viable;
|
||||
@ -1669,7 +1670,7 @@ L_feature:
|
||||
l = &g->layers[L_RIVER_MIX_4];
|
||||
biomeX = (chunkX << 4) + 8; // areBiomesViable expects block positions
|
||||
biomeZ = (chunkZ << 4) + 8;
|
||||
setWorldSeed(l, seed);
|
||||
setLayerSeed(l, seed);
|
||||
if (mc < MC_1_9 || areBiomesViable(l, NULL, biomeX, biomeZ, 16, getValidMonumentBiomes2()))
|
||||
if (areBiomesViable(l, NULL, biomeX, biomeZ, 29, getValidMonumentBiomes1()))
|
||||
goto L_viable;
|
||||
@ -1681,7 +1682,7 @@ L_feature:
|
||||
l = &g->layers[L_RIVER_MIX_4];
|
||||
biomeX = (chunkX << 4) + 8;
|
||||
biomeZ = (chunkZ << 4) + 8;
|
||||
setWorldSeed(l, seed);
|
||||
setLayerSeed(l, seed);
|
||||
if (areBiomesViable(l, NULL, biomeX, biomeZ, 32, getValidMansionBiomes()))
|
||||
goto L_viable;
|
||||
goto L_not_viable;
|
||||
@ -1719,7 +1720,7 @@ L_not_viable:
|
||||
|
||||
VillageType getVillageType(int mc, int64_t seed, int blockX, int blockZ, int biomeID)
|
||||
{
|
||||
VillageType r = {};
|
||||
VillageType r = { 0, 0, 0 };
|
||||
if (!isViableFeatureBiome(mc, Village, biomeID))
|
||||
return r;
|
||||
|
||||
@ -2411,7 +2412,7 @@ int checkForBiomes(
|
||||
z0 = (bz) / l->scale; if (z < 0) z0--;
|
||||
x1 = (bx + bw) / l->scale; if (x+(int)w >= 0) x1++;
|
||||
z1 = (bz + bh) / l->scale; if (z+(int)h >= 0) z1++;
|
||||
ss = getStartSeed(seed, l->layerSeed);
|
||||
ss = getStartSeed(seed, l->layerSalt);
|
||||
|
||||
for (j = z0; j <= z1; j++)
|
||||
{
|
||||
@ -2434,7 +2435,7 @@ int checkForBiomes(
|
||||
|
||||
if (filter.majorToFind & (1ULL << mushroom_fields))
|
||||
{
|
||||
ss = getStartSeed(seed, g->layers[L_ADD_MUSHROOM_256].layerSeed);
|
||||
ss = getStartSeed(seed, g->layers[L_ADD_MUSHROOM_256].layerSalt);
|
||||
|
||||
for (j = z0; j <= z1; j++)
|
||||
{
|
||||
@ -2456,7 +2457,7 @@ L_HAS_PROTO_MUSHROOM:
|
||||
(1ULL << forest) | (1ULL << dark_forest) | (1ULL << mountains) |
|
||||
(1ULL << birch_forest) | (1ULL << swamp));
|
||||
|
||||
ss = getStartSeed(seed, l->layerSeed);
|
||||
ss = getStartSeed(seed, l->layerSalt);
|
||||
|
||||
for (j = z0; j <= z1; j++)
|
||||
{
|
||||
@ -2503,7 +2504,7 @@ L_HAS_PROTO_MUSHROOM:
|
||||
swapMap(fd+7, &filter, l+L_ADD_MUSHROOM_256, mapFilterMushroom);
|
||||
swapMap(fd+8, &filter, l+L_SPECIAL_1024, mapFilterSpecial);
|
||||
|
||||
setWorldSeed(&l[layerID], seed);
|
||||
setLayerSeed(&l[layerID], seed);
|
||||
int ret = !l[layerID].getMap(&l[layerID], map, x, z, w, h);
|
||||
if (ret)
|
||||
{
|
||||
@ -2542,60 +2543,9 @@ L_HAS_PROTO_MUSHROOM:
|
||||
}
|
||||
|
||||
|
||||
int hasAllTemps(LayerStack *g, int64_t seed, int x1024, int z1024)
|
||||
{
|
||||
int64_t ls = getLayerSeed(3); // L_SPECIAL_1024 layer seed
|
||||
int64_t ss = getStartSeed(seed, ls);
|
||||
int spbits = 0, spcnt = 0;
|
||||
|
||||
if (mcFirstIsZero(getChunkSeed(ss, x1024-1, z1024-1), 13))
|
||||
{ spbits |= (1<<0); spcnt++; }
|
||||
if (mcFirstIsZero(getChunkSeed(ss, x1024 , z1024-1), 13))
|
||||
{ spbits |= (1<<1); spcnt++; }
|
||||
if (mcFirstIsZero(getChunkSeed(ss, x1024+1, z1024-1), 13))
|
||||
{ spbits |= (1<<2); spcnt++; }
|
||||
if (mcFirstIsZero(getChunkSeed(ss, x1024-1, z1024 ), 13))
|
||||
{ spbits |= (1<<3); spcnt++; }
|
||||
if (mcFirstIsZero(getChunkSeed(ss, x1024 , z1024 ), 13))
|
||||
{ spbits |= (1<<4); spcnt++; }
|
||||
if (mcFirstIsZero(getChunkSeed(ss, x1024+1, z1024 ), 13))
|
||||
{ spbits |= (1<<5); spcnt++; }
|
||||
if (mcFirstIsZero(getChunkSeed(ss, x1024-1, z1024+1), 13))
|
||||
{ spbits |= (1<<6); spcnt++; }
|
||||
if (mcFirstIsZero(getChunkSeed(ss, x1024 , z1024+1), 13))
|
||||
{ spbits |= (1<<7); spcnt++; }
|
||||
if (mcFirstIsZero(getChunkSeed(ss, x1024+1, z1024+1), 13))
|
||||
{ spbits |= (1<<8); spcnt++; }
|
||||
|
||||
if (spcnt < 3)
|
||||
return 0;
|
||||
|
||||
// approx. ~2.7% of seeds make it to here
|
||||
|
||||
int buf[20*20];
|
||||
int i;
|
||||
|
||||
setWorldSeed(&g->layers[L_HEAT_ICE_1024], seed);
|
||||
genArea(&g->layers[L_HEAT_ICE_1024], buf, x1024-1, z1024-1, 3, 3);
|
||||
|
||||
uint64_t bm = 0;
|
||||
for (i = 0; i < 9; i++)
|
||||
{
|
||||
int id = buf[i];
|
||||
if (id != 0 && id != Freezing && (spbits & (1<<i)))
|
||||
bm |= (1ULL << (id+Special));
|
||||
else
|
||||
bm |= (1ULL << id);
|
||||
}
|
||||
|
||||
// approx. 1 in 100000 seeds satisfy such an all-temperatures cluster
|
||||
return ((bm & 0x1df) ^ 0x1df) == 0;
|
||||
}
|
||||
|
||||
|
||||
int checkForTemps(LayerStack *g, int64_t seed, int x, int z, int w, int h, const int tc[9])
|
||||
{
|
||||
int64_t ls = getLayerSeed(3); // L_SPECIAL_1024 layer seed
|
||||
int64_t ls = getLayerSalt(3); // L_SPECIAL_1024 layer seed
|
||||
int64_t ss = getStartSeed(seed, ls);
|
||||
|
||||
int i, j;
|
||||
@ -2624,7 +2574,7 @@ int checkForTemps(LayerStack *g, int64_t seed, int x, int z, int w, int h, const
|
||||
int *area = allocCache(l, w, h);
|
||||
int ret = 1;
|
||||
|
||||
setWorldSeed(l, seed);
|
||||
setLayerSeed(l, seed);
|
||||
genArea(l, area, x, z, w, h);
|
||||
|
||||
for (i = 0; i < w*h; i++)
|
||||
|
@ -640,10 +640,10 @@ int isViableFeatureBiome(int mc, int structureType, int biomeID);
|
||||
inline static int64_t chunkGenerateRnd(const int64_t worldSeed,
|
||||
const int chunkX, const int chunkZ)
|
||||
{
|
||||
int64_t rnd = worldSeed;
|
||||
setSeed(&rnd);
|
||||
int64_t rnd;
|
||||
setSeed(&rnd, worldSeed);
|
||||
rnd = (nextLong(&rnd) * chunkX) ^ (nextLong(&rnd) * chunkZ) ^ worldSeed;
|
||||
setSeed(&rnd);
|
||||
setSeed(&rnd, rnd);
|
||||
return rnd;
|
||||
}
|
||||
|
||||
|
24
generator.c
24
generator.c
@ -9,7 +9,7 @@
|
||||
|
||||
void setupLayer(Layer *l, Layer *p, int s, mapfunc_t getMap)
|
||||
{
|
||||
l->layerSeed = s ? getLayerSeed(s) : 0;
|
||||
l->layerSalt = s > 0 ? getLayerSalt(s) : s;
|
||||
l->startSalt = 0;
|
||||
l->startSeed = 0;
|
||||
l->p = p;
|
||||
@ -40,7 +40,7 @@ static void setupScale(Layer *l, int scale)
|
||||
m = 2;
|
||||
e = 3;
|
||||
}
|
||||
else if (map == mapVoronoiZoom)
|
||||
else if (map == mapVoronoiZoom || map == mapVoronoiZoom114)
|
||||
{
|
||||
m = 4;
|
||||
e = 7;
|
||||
@ -113,8 +113,7 @@ static void setupGeneratorImpl(LayerStack *g, int mcversion, int largeBiomes)
|
||||
setupLayer(&l[L_ADD_MUSHROOM_256], &l[L_ADD_ISLAND_256], 5, mapAddMushroomIsland);
|
||||
setupLayer(&l[L_DEEP_OCEAN_256], &l[L_ADD_MUSHROOM_256], 4, mapDeepOcean);
|
||||
// biome layer chain
|
||||
setupLayer(&l[L_BIOME_256], &l[L_DEEP_OCEAN_256], 200,
|
||||
mcversion != MC_BE ? mapBiome : mapBiomeBE);
|
||||
setupLayer(&l[L_BIOME_256], &l[L_DEEP_OCEAN_256], 200, mapBiome);
|
||||
|
||||
if (mcversion <= MC_1_13)
|
||||
setupLayer(&l[L_ZOOM_128], &l[L_BIOME_256], 1000, mapZoom);
|
||||
@ -144,11 +143,11 @@ static void setupGeneratorImpl(LayerStack *g, int mcversion, int largeBiomes)
|
||||
setupLayer(&l[L_ZOOM_4], &l[L_ZOOM_8], 1003, mapZoom);
|
||||
|
||||
if (largeBiomes != 0) {
|
||||
setupLayer(&l[L_ZOOM_LARGE_BIOME_A], &l[L_ZOOM_4], 1004, mapZoom);
|
||||
setupLayer(&l[L_ZOOM_LARGE_BIOME_B], &l[L_ZOOM_LARGE_BIOME_A], 1005, mapZoom);
|
||||
setupLayer(&l[L_SMOOTH_4], &l[L_ZOOM_LARGE_BIOME_B], 1000, mapSmooth);
|
||||
setupLayer(&l[L_ZOOM_LARGE_BIOME_A], &l[L_ZOOM_4], 1004, mapZoom);
|
||||
setupLayer(&l[L_ZOOM_LARGE_BIOME_B], &l[L_ZOOM_LARGE_BIOME_A], 1005, mapZoom);
|
||||
setupLayer(&l[L_SMOOTH_4], &l[L_ZOOM_LARGE_BIOME_B], 1000, mapSmooth);
|
||||
} else {
|
||||
setupLayer(&l[L_SMOOTH_4], &l[L_ZOOM_4], 1000, mapSmooth);
|
||||
setupLayer(&l[L_SMOOTH_4], &l[L_ZOOM_4], 1000, mapSmooth);
|
||||
}
|
||||
|
||||
// river layer chain
|
||||
@ -181,9 +180,12 @@ static void setupGeneratorImpl(LayerStack *g, int mcversion, int largeBiomes)
|
||||
setupLayer(&l[L13_ZOOM_4], &l[L13_ZOOM_8], 2006, mapZoom);
|
||||
|
||||
setupMultiLayer(&l[L13_OCEAN_MIX_4], &l[L_RIVER_MIX_4], &l[L13_ZOOM_4], 100, mapOceanMix);
|
||||
|
||||
setupLayer(&l[L_VORONOI_ZOOM_1], &l[L13_OCEAN_MIX_4], 10, mapVoronoiZoom);
|
||||
g->entry_4 = &l[L13_OCEAN_MIX_4];
|
||||
|
||||
if (mcversion <= MC_1_14)
|
||||
setupLayer(&l[L_VORONOI_ZOOM_1], &l[L13_OCEAN_MIX_4], 10, mapVoronoiZoom114);
|
||||
else
|
||||
setupLayer(&l[L_VORONOI_ZOOM_1], &l[L13_OCEAN_MIX_4], -1, mapVoronoiZoom);
|
||||
}
|
||||
|
||||
setupScale(&l[L_VORONOI_ZOOM_1], 1);
|
||||
@ -252,7 +254,7 @@ int *allocCache(const Layer *layer, int sizeX, int sizeZ)
|
||||
void applySeed(LayerStack *g, int64_t seed)
|
||||
{
|
||||
// the seed has to be applied recursively
|
||||
setWorldSeed(&g->layers[L_VORONOI_ZOOM_1], seed);
|
||||
setLayerSeed(g->entry_1, seed);
|
||||
}
|
||||
|
||||
int genArea(const Layer *layer, int *out, int areaX, int areaZ, int areaWidth, int areaHeight)
|
||||
|
@ -8,7 +8,6 @@ enum MCversion
|
||||
{
|
||||
MC_1_7, MC_1_8, MC_1_9, MC_1_10, MC_1_11, MC_1_12, MC_1_13, MC_1_14,
|
||||
MC_1_15, MC_1_16,
|
||||
MC_BE = 128
|
||||
};
|
||||
|
||||
/* Enumeration of the layer indices in the generator. */
|
||||
|
28
javarnd.h
28
javarnd.h
@ -7,9 +7,9 @@
|
||||
/********************** C copy of the Java Random methods **********************
|
||||
*/
|
||||
|
||||
static inline void setSeed(int64_t *seed)
|
||||
static inline void setSeed(int64_t *seed, int64_t value)
|
||||
{
|
||||
*seed = (*seed ^ 0x5deece66d) & ((1LL << 48) - 1);
|
||||
*seed = (value ^ 0x5deece66d) & ((1LL << 48) - 1);
|
||||
}
|
||||
|
||||
static inline int next(int64_t *seed, const int bits)
|
||||
@ -69,11 +69,27 @@ 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, const int n)
|
||||
static inline void skipNextN(int64_t *seed, uint64_t n)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < n; i++) *seed = (*seed * 0x5deece66d + 0xb);
|
||||
*seed &= 0xffffffffffff;
|
||||
int64_t m = 1;
|
||||
int64_t a = 0;
|
||||
int64_t im = 0x5deece66dLL;
|
||||
int64_t ia = 0xbLL;
|
||||
uint64_t k;
|
||||
|
||||
for (k = n; k; k >>= 1)
|
||||
{
|
||||
if (k & 1)
|
||||
{
|
||||
m *= im;
|
||||
a = im * a + ia;
|
||||
}
|
||||
ia = (im + 1) * ia;
|
||||
im *= im;
|
||||
}
|
||||
|
||||
*seed = *seed * m + a;
|
||||
*seed &= 0xffffffffffffLL;
|
||||
}
|
||||
|
||||
/* invSeed48
|
||||
|
508
layers.c
508
layers.c
@ -2,8 +2,12 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include <float.h>
|
||||
|
||||
|
||||
//==============================================================================
|
||||
// Essentials
|
||||
//==============================================================================
|
||||
|
||||
void initAddBiome(int id, int tempCat, int biometype, float temp, float height)
|
||||
{
|
||||
@ -127,19 +131,33 @@ void initBiomes()
|
||||
}
|
||||
|
||||
|
||||
void setWorldSeed(Layer *layer, int64_t worldSeed)
|
||||
void setLayerSeed(Layer *layer, int64_t worldSeed)
|
||||
{
|
||||
if (layer->p2 != NULL)
|
||||
setWorldSeed(layer->p2, worldSeed);
|
||||
setLayerSeed(layer->p2, worldSeed);
|
||||
|
||||
if (layer->p != NULL)
|
||||
setWorldSeed(layer->p, worldSeed);
|
||||
setLayerSeed(layer->p, worldSeed);
|
||||
|
||||
if (layer->noise != NULL)
|
||||
perlinInit((PerlinNoise*)layer->noise, worldSeed);
|
||||
{
|
||||
int64_t s;
|
||||
setSeed(&s, worldSeed);
|
||||
perlinInit((PerlinNoise*)layer->noise, &s);
|
||||
}
|
||||
|
||||
int64_t ls = layer->layerSeed;
|
||||
if (ls != 0) // Pre 1.13 the Hills branch stays zero-initialized
|
||||
int64_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
|
||||
{
|
||||
layer->startSalt = getVoroniSHA(worldSeed);
|
||||
layer->startSeed = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
int64_t st = worldSeed;
|
||||
st = mcStepSeed(st, ls);
|
||||
@ -149,14 +167,233 @@ void setWorldSeed(Layer *layer, int64_t worldSeed)
|
||||
layer->startSalt = st;
|
||||
layer->startSeed = mcStepSeed(st, 0);
|
||||
}
|
||||
else
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
// Noise
|
||||
//==============================================================================
|
||||
|
||||
|
||||
static double lerp(double part, double from, double to)
|
||||
{
|
||||
return from + part * (to - from);
|
||||
}
|
||||
|
||||
/* Table of vectors to cube edge centres (12 + 4 extra), used for ocean PRNG */
|
||||
const double cEdgeX[] = {1.0,-1.0, 1.0,-1.0, 1.0,-1.0, 1.0,-1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0,-1.0, 0.0};
|
||||
const double cEdgeY[] = {1.0, 1.0,-1.0,-1.0, 0.0, 0.0, 0.0, 0.0, 1.0,-1.0, 1.0,-1.0, 1.0,-1.0, 1.0,-1.0};
|
||||
const double cEdgeZ[] = {0.0, 0.0, 0.0, 0.0, 1.0, 1.0,-1.0,-1.0, 1.0, 1.0,-1.0,-1.0, 0.0, 1.0, 0.0,-1.0};
|
||||
|
||||
// grad()
|
||||
static double indexedLerp(int idx, double d1, double d2, double d3)
|
||||
{
|
||||
idx &= 0xf;
|
||||
return cEdgeX[idx] * d1 + cEdgeY[idx] * d2 + cEdgeZ[idx] * d3;
|
||||
}
|
||||
|
||||
void perlinInit(PerlinNoise *rnd, int64_t *seed)
|
||||
{
|
||||
int i = 0;
|
||||
memset(rnd, 0, sizeof(*rnd));
|
||||
rnd->a = nextDouble(seed) * 256.0;
|
||||
rnd->b = nextDouble(seed) * 256.0;
|
||||
rnd->c = nextDouble(seed) * 256.0;
|
||||
|
||||
for (i = 0; i < 256; i++)
|
||||
{
|
||||
layer->startSalt = 0;
|
||||
layer->startSeed = 0;
|
||||
rnd->d[i] = i;
|
||||
}
|
||||
for (i = 0; i < 256; i++)
|
||||
{
|
||||
int n3 = nextInt(seed, 256 - i) + i;
|
||||
int n4 = rnd->d[i];
|
||||
rnd->d[i] = rnd->d[n3];
|
||||
rnd->d[n3] = n4;
|
||||
rnd->d[i + 256] = rnd->d[i];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
double samplePerlin(const PerlinNoise *rnd, double d1, double d2, double d3)
|
||||
{
|
||||
d1 += rnd->a;
|
||||
d2 += rnd->b;
|
||||
d3 += rnd->c;
|
||||
int i1 = (int)d1 - (int)(d1 < 0);
|
||||
int i2 = (int)d2 - (int)(d2 < 0);
|
||||
int i3 = (int)d3 - (int)(d3 < 0);
|
||||
d1 -= i1;
|
||||
d2 -= i2;
|
||||
d3 -= i3;
|
||||
double t1 = d1*d1*d1 * (d1 * (d1*6.0-15.0) + 10.0);
|
||||
double t2 = d2*d2*d2 * (d2 * (d2*6.0-15.0) + 10.0);
|
||||
double t3 = d3*d3*d3 * (d3 * (d3*6.0-15.0) + 10.0);
|
||||
|
||||
i1 &= 0xff;
|
||||
i2 &= 0xff;
|
||||
i3 &= 0xff;
|
||||
|
||||
int a1 = rnd->d[i1] + i2;
|
||||
int a2 = rnd->d[a1] + i3;
|
||||
int a3 = rnd->d[a1+1] + i3;
|
||||
int b1 = rnd->d[i1+1] + i2;
|
||||
int b2 = rnd->d[b1] + i3;
|
||||
int b3 = rnd->d[b1+1] + i3;
|
||||
|
||||
double l1 = indexedLerp(rnd->d[a2], d1, d2, d3);
|
||||
double l2 = indexedLerp(rnd->d[b2], d1-1, d2, d3);
|
||||
double l3 = indexedLerp(rnd->d[a3], d1, d2-1, d3);
|
||||
double l4 = indexedLerp(rnd->d[b3], d1-1, d2-1, d3);
|
||||
double l5 = indexedLerp(rnd->d[a2+1], d1, d2, d3-1);
|
||||
double l6 = indexedLerp(rnd->d[b2+1], d1-1, d2, d3-1);
|
||||
double l7 = indexedLerp(rnd->d[a3+1], d1, d2-1, d3-1);
|
||||
double l8 = indexedLerp(rnd->d[b3+1], d1-1, d2-1, d3-1);
|
||||
|
||||
l1 = lerp(t1, l1, l2);
|
||||
l3 = lerp(t1, l3, l4);
|
||||
l5 = lerp(t1, l5, l6);
|
||||
l7 = lerp(t1, l7, l8);
|
||||
|
||||
l1 = lerp(t2, l1, l3);
|
||||
l5 = lerp(t2, l5, l7);
|
||||
|
||||
return lerp(t3, l1, l5);
|
||||
}
|
||||
|
||||
|
||||
void doublePerlinInit(DoublePerlinNoise *rnd, int64_t *seed,
|
||||
PerlinNoise *octavesA, PerlinNoise *octavesB, int omin, int len)
|
||||
{
|
||||
if (len < 1 || omin+len > 0)
|
||||
{
|
||||
printf("doublePerlinInit(): unsupported octave range\n");
|
||||
return;
|
||||
}
|
||||
rnd->octaves[0] = octavesA;
|
||||
rnd->octaves[1] = octavesB;
|
||||
rnd->octcnt = len;
|
||||
|
||||
rnd->amplitude = (10.0 / 6.0) * len / (len + 1);
|
||||
|
||||
int ab, i;
|
||||
for (ab = 0; ab < 2; ab++)
|
||||
{
|
||||
// octave zero is initialized first
|
||||
if (omin <= 0 && omin+len > 0)
|
||||
perlinInit(&rnd->octaves[ab][-omin], seed);
|
||||
else
|
||||
skipNextN(seed, 262);
|
||||
|
||||
if (omin+len < 0)
|
||||
skipNextN(seed, -(omin+len) * 262);
|
||||
for (i = 0; i < len; i++)
|
||||
if (i+omin < 0)
|
||||
perlinInit(&rnd->octaves[ab][i], seed);
|
||||
|
||||
rnd->persist[ab] = pow(2.0, omin+len - 1);
|
||||
rnd->lacuna[ab] = 1.0 / ((1LL << len) - 1.0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static double sampleOctave(const PerlinNoise *octaves, int len,
|
||||
double x, double y, double z, double persist, double lacuna)
|
||||
{
|
||||
double v = 0;
|
||||
int i;
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
double ax = x * persist;
|
||||
double ay = y * persist;
|
||||
double az = z * persist;
|
||||
ax -= floor(ax / 33554432.0 + 0.5) * 33554432.0;
|
||||
ay -= floor(ay / 33554432.0 + 0.5) * 33554432.0;
|
||||
az -= floor(az / 33554432.0 + 0.5) * 33554432.0;
|
||||
v += lacuna * samplePerlin(octaves+i, ax, ay, az);
|
||||
persist *= 0.5;
|
||||
lacuna *= 2.0;
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
double sampleDoublePerlin(const DoublePerlinNoise *rnd,
|
||||
double x, double y, double z)
|
||||
{
|
||||
const double f = 337.0 / 331.0;
|
||||
double v = 0;
|
||||
|
||||
v += sampleOctave(rnd->octaves[0], rnd->octcnt, x, y, z,
|
||||
rnd->persist[0], rnd->lacuna[0]);
|
||||
|
||||
v += sampleOctave(rnd->octaves[1], rnd->octcnt, x*f, y*f, z*f,
|
||||
rnd->persist[1], rnd->lacuna[1]);
|
||||
|
||||
return v * rnd->amplitude;
|
||||
}
|
||||
|
||||
|
||||
void setNetherSeed(NetherNoise *nn, int64_t seed)
|
||||
{
|
||||
int64_t s;
|
||||
setSeed(&s, seed);
|
||||
doublePerlinInit(&nn->temperature, &s, &nn->oct[0], &nn->oct[2], -7, 2);
|
||||
setSeed(&s, seed+1);
|
||||
doublePerlinInit(&nn->humidity, &s, &nn->oct[4], &nn->oct[6], -7, 2);
|
||||
}
|
||||
|
||||
|
||||
static float distsq(const float *a, const float *b, int n)
|
||||
{
|
||||
float dsq = 0;
|
||||
int i;
|
||||
for (i = 0; i < n; i++)
|
||||
{
|
||||
float d = a[i] - b[i];
|
||||
dsq += d*d;
|
||||
}
|
||||
return dsq;
|
||||
}
|
||||
|
||||
int getNetherBiome(const NetherNoise *nn, int x, int y, int z)
|
||||
{
|
||||
const float mixpoints[5][6] = {
|
||||
{ nether_wastes, 0, 0, 0, 0, 0 },
|
||||
{ soul_sand_valley, 0, -0.5, 0, 0, 0 },
|
||||
{ crimson_forest, 0.4, 0, 0, 0, 0 },
|
||||
{ warped_forest, 0, 0.5, 0, 0, 0.375 },
|
||||
{ basalt_deltas, -0.5, 0, 0, 0, 0.175 },
|
||||
};
|
||||
|
||||
float point[] = {
|
||||
(float) sampleDoublePerlin(&nn->temperature, x, y, z),
|
||||
(float) sampleDoublePerlin(&nn->humidity, x, y, z),
|
||||
0,//(float) sampleDoublePerlin(&nn->altitude, x, y, z),
|
||||
0,//(float) sampleDoublePerlin(&nn->wierdness, x, y, z),
|
||||
0,
|
||||
};
|
||||
|
||||
int i, id = 0;
|
||||
float dmin = FLT_MAX;
|
||||
for (i = 0; i < 5; i++)
|
||||
{
|
||||
float dsq = distsq(point, &mixpoints[i][1], 5);
|
||||
if (dsq < dmin)
|
||||
{
|
||||
dmin = dsq;
|
||||
id = i;
|
||||
}
|
||||
}
|
||||
|
||||
id = (int) mixpoints[id][0];
|
||||
return id;
|
||||
}
|
||||
|
||||
|
||||
//==============================================================================
|
||||
// Layers
|
||||
//==============================================================================
|
||||
|
||||
|
||||
int mapIsland(const Layer * l, int * out, int x, int z, int w, int h)
|
||||
{
|
||||
int64_t ss = l->startSeed;
|
||||
@ -1041,7 +1278,7 @@ int mapHills112(const Layer * l, int * out, int x, int z, int w, int h)
|
||||
int i, j;
|
||||
int *buf = NULL;
|
||||
|
||||
if (l->p2 == NULL)
|
||||
if U(l->p2 == NULL)
|
||||
{
|
||||
printf("mapHills() requires two parents! Use setupMultiLayer()\n");
|
||||
exit(1);
|
||||
@ -1179,7 +1416,7 @@ int mapHills(const Layer * l, int * out, int x, int z, int w, int h)
|
||||
int i, j;
|
||||
int *buf = NULL;
|
||||
|
||||
if (l->p2 == NULL)
|
||||
if U(l->p2 == NULL)
|
||||
{
|
||||
printf("mapHills() requires two parents! Use setupMultiLayer()\n");
|
||||
exit(1);
|
||||
@ -1563,7 +1800,7 @@ int mapRiverMix(const Layer * l, int * out, int x, int z, int w, int h)
|
||||
int len;
|
||||
int *buf;
|
||||
|
||||
if (l->p2 == NULL)
|
||||
if U(l->p2 == NULL)
|
||||
{
|
||||
printf("mapRiverMix() requires two parents! Use setupMultiLayer()\n");
|
||||
exit(1);
|
||||
@ -1614,92 +1851,6 @@ int mapRiverMix(const Layer * l, int * out, int x, int z, int w, int h)
|
||||
}
|
||||
|
||||
|
||||
void perlinInit(PerlinNoise *rnd, int64_t seed)
|
||||
{
|
||||
int i = 0;
|
||||
memset(rnd, 0, sizeof(*rnd));
|
||||
setSeed(&seed);
|
||||
rnd->a = nextDouble(&seed) * 256.0;
|
||||
rnd->b = nextDouble(&seed) * 256.0;
|
||||
rnd->c = nextDouble(&seed) * 256.0;
|
||||
|
||||
for (i = 0; i < 256; i++)
|
||||
{
|
||||
rnd->d[i] = i;
|
||||
}
|
||||
for (i = 0; i < 256; i++)
|
||||
{
|
||||
int n3 = nextInt(&seed, 256 - i) + i;
|
||||
int n4 = rnd->d[i];
|
||||
rnd->d[i] = rnd->d[n3];
|
||||
rnd->d[n3] = n4;
|
||||
rnd->d[i + 256] = rnd->d[i];
|
||||
}
|
||||
}
|
||||
|
||||
static double lerp(double part, double from, double to)
|
||||
{
|
||||
return from + part * (to - from);
|
||||
}
|
||||
|
||||
/* Table of vectors to cube edge centres (12 + 4 extra), used for ocean PRNG */
|
||||
const double cEdgeX[] = {1.0,-1.0, 1.0,-1.0, 1.0,-1.0, 1.0,-1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0,-1.0, 0.0};
|
||||
const double cEdgeY[] = {1.0, 1.0,-1.0,-1.0, 0.0, 0.0, 0.0, 0.0, 1.0,-1.0, 1.0,-1.0, 1.0,-1.0, 1.0,-1.0};
|
||||
const double cEdgeZ[] = {0.0, 0.0, 0.0, 0.0, 1.0, 1.0,-1.0,-1.0, 1.0, 1.0,-1.0,-1.0, 0.0, 1.0, 0.0,-1.0};
|
||||
|
||||
static double indexedLerp(int idx, double d1, double d2, double d3)
|
||||
{
|
||||
idx &= 0xf;
|
||||
return cEdgeX[idx] * d1 + cEdgeY[idx] * d2 + cEdgeZ[idx] * d3;
|
||||
}
|
||||
|
||||
|
||||
double samplePerlin(const PerlinNoise *rnd, double d1, double d2, double d3)
|
||||
{
|
||||
d1 += rnd->a;
|
||||
d2 += rnd->b;
|
||||
d3 += rnd->c;
|
||||
int i1 = (int)d1 - (int)(d1 < 0);
|
||||
int i2 = (int)d2 - (int)(d2 < 0);
|
||||
int i3 = (int)d3 - (int)(d3 < 0);
|
||||
d1 -= i1;
|
||||
d2 -= i2;
|
||||
d3 -= i3;
|
||||
double t1 = d1*d1*d1 * (d1 * (d1*6.0-15.0) + 10.0);
|
||||
double t2 = d2*d2*d2 * (d2 * (d2*6.0-15.0) + 10.0);
|
||||
double t3 = d3*d3*d3 * (d3 * (d3*6.0-15.0) + 10.0);
|
||||
|
||||
i1 &= 0xff;
|
||||
i2 &= 0xff;
|
||||
i3 &= 0xff;
|
||||
|
||||
int a1 = rnd->d[i1] + i2;
|
||||
int a2 = rnd->d[a1] + i3;
|
||||
int a3 = rnd->d[a1+1] + i3;
|
||||
int b1 = rnd->d[i1+1] + i2;
|
||||
int b2 = rnd->d[b1] + i3;
|
||||
int b3 = rnd->d[b1+1] + i3;
|
||||
|
||||
double l1 = indexedLerp(rnd->d[a2], d1, d2, d3);
|
||||
double l2 = indexedLerp(rnd->d[b2], d1-1, d2, d3);
|
||||
double l3 = indexedLerp(rnd->d[a3], d1, d2-1, d3);
|
||||
double l4 = indexedLerp(rnd->d[b3], d1-1, d2-1, d3);
|
||||
double l5 = indexedLerp(rnd->d[a2+1], d1, d2, d3-1);
|
||||
double l6 = indexedLerp(rnd->d[b2+1], d1-1, d2, d3-1);
|
||||
double l7 = indexedLerp(rnd->d[a3+1], d1, d2-1, d3-1);
|
||||
double l8 = indexedLerp(rnd->d[b3+1], d1-1, d2-1, d3-1);
|
||||
|
||||
l1 = lerp(t1, l1, l2);
|
||||
l3 = lerp(t1, l3, l4);
|
||||
l5 = lerp(t1, l5, l6);
|
||||
l7 = lerp(t1, l7, l8);
|
||||
|
||||
l1 = lerp(t2, l1, l3);
|
||||
l5 = lerp(t2, l5, l7);
|
||||
|
||||
return lerp(t3, l1, l5);
|
||||
}
|
||||
|
||||
int mapOceanTemp(const Layer * l, int * out, int x, int z, int w, int h)
|
||||
{
|
||||
int i, j;
|
||||
@ -1734,7 +1885,7 @@ int mapOceanMix(const Layer * l, int * out, int x, int z, int w, int h)
|
||||
int i, j;
|
||||
int lx0, lx1, lz0, lz1, lw, lh;
|
||||
|
||||
if (l->p2 == NULL)
|
||||
if U(l->p2 == NULL)
|
||||
{
|
||||
printf("mapOceanMix() requires two parents! Use setupMultiLayer()\n");
|
||||
exit(1);
|
||||
@ -1858,14 +2009,96 @@ int mapVoronoiZoom(const Layer * l, int * out, int x, int z, int w, int h)
|
||||
int pW = ((x + w) >> 2) - pX + 2;
|
||||
int pH = ((z + h) >> 2) - pZ + 2;
|
||||
|
||||
int err = l->p->getMap(l->p, out, pX, pZ, pW, pH);
|
||||
if U(err != 0)
|
||||
return err;
|
||||
|
||||
int64_t sha = l->startSalt;
|
||||
int *buf = (int *) malloc(w*h*sizeof(*buf));
|
||||
|
||||
int i, j;
|
||||
for (j = 0; j < h; j++)
|
||||
{
|
||||
for (i = 0; i < w; i++)
|
||||
{
|
||||
// TODO: this can be optimized further!
|
||||
// rx,ry,rz only need to be calculated for the parent grid
|
||||
// the dependency on the inner grid comes with dx,dz
|
||||
|
||||
int pi = x+i;
|
||||
int pj = z+j;
|
||||
int px = pi >> 2;
|
||||
int pz = pj >> 2;
|
||||
int dx = (pi & 3) * 10240;
|
||||
int dz = (pj & 3) * 10240;
|
||||
uint64_t dmin = (uint64_t)-1;
|
||||
int k;
|
||||
|
||||
for (k = 0; k < 8; k++)
|
||||
{
|
||||
int bx = (k & 4) != 0;
|
||||
int by = (k & 2) != 0;
|
||||
int bz = (k & 1) != 0;
|
||||
int ax = px + bx;
|
||||
int ay = -1 + by;
|
||||
int az = pz + bz;
|
||||
|
||||
int64_t s = sha;
|
||||
s = mcStepSeed(s, ax);
|
||||
s = mcStepSeed(s, ay);
|
||||
s = mcStepSeed(s, az);
|
||||
s = mcStepSeed(s, ax);
|
||||
s = mcStepSeed(s, ay);
|
||||
s = mcStepSeed(s, az);
|
||||
|
||||
int rx = (((s >> 24) & 1023) - 512) * 36;
|
||||
s = mcStepSeed(s, sha);
|
||||
int ry = (((s >> 24) & 1023) - 512) * 36;
|
||||
s = mcStepSeed(s, sha);
|
||||
int rz = (((s >> 24) & 1023) - 512) * 36;
|
||||
|
||||
int64_t sx = rx - 40*1024*bx + dx;
|
||||
int64_t sy = ry - 40*1024*by + 20*1024;
|
||||
int64_t sz = rz - 40*1024*bz + dz;
|
||||
|
||||
uint64_t d = sx*sx + sy*sy + sz*sz;
|
||||
if (d < dmin)
|
||||
{
|
||||
dmin = d;
|
||||
pi = ax;
|
||||
pj = az;
|
||||
}
|
||||
}
|
||||
|
||||
pi -= pX;
|
||||
pj -= pZ;
|
||||
int v = out[pj*pW + pi];
|
||||
buf[j*w + i] = v;
|
||||
}
|
||||
}
|
||||
|
||||
memcpy(out, buf, w*h*sizeof(*buf));
|
||||
free(buf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mapVoronoiZoom114(const Layer * l, int * out, int x, int z, int w, int h)
|
||||
{
|
||||
x -= 2;
|
||||
z -= 2;
|
||||
int pX = x >> 2;
|
||||
int pZ = z >> 2;
|
||||
int pW = ((x + w) >> 2) - pX + 2;
|
||||
int pH = ((z + h) >> 2) - pZ + 2;
|
||||
|
||||
int err = l->p->getMap(l->p, out, pX, pZ, pW, pH);
|
||||
if U(err != 0)
|
||||
return err;
|
||||
|
||||
int newW = pW << 2;
|
||||
int newH = pH << 2;
|
||||
int i, j;
|
||||
int *buf = (int *) malloc((newW+1)*(newH+1)*sizeof(*buf));
|
||||
int i, j;
|
||||
|
||||
int64_t st = l->startSalt;
|
||||
int64_t ss = l->startSeed;
|
||||
@ -1962,3 +2195,76 @@ int mapVoronoiZoom(const Layer * l, int * out, int x, int z, int w, int h)
|
||||
}
|
||||
|
||||
|
||||
int64_t getVoroniSHA(int64_t worldSeed)
|
||||
{
|
||||
int i;
|
||||
BYTE data[8];
|
||||
for (i = 0; i < 8; i++)
|
||||
data[i] = (BYTE) (worldSeed >> i*8);
|
||||
SHA256_CTX ctx;
|
||||
BYTE hash[SHA256_BLOCK_SIZE];
|
||||
|
||||
sha256_init(&ctx);
|
||||
sha256_update(&ctx, data, 8);
|
||||
sha256_final(&ctx, hash);
|
||||
|
||||
int64_t sha = 0;
|
||||
for (i = 0; i < 8; i++)
|
||||
sha |= ((uint64_t)hash[i] << i*8);
|
||||
return sha;
|
||||
}
|
||||
|
||||
void voronoiAccess3D(int64_t sha, int x, int y, int z, int *x4, int *y4, int *z4)
|
||||
{
|
||||
x -= 2;
|
||||
y -= 2;
|
||||
z -= 2;
|
||||
int pX = x >> 2;
|
||||
int pY = y >> 2;
|
||||
int pZ = z >> 2;
|
||||
int dx = (x & 3) * 10240;
|
||||
int dy = (y & 3) * 10240;
|
||||
int dz = (z & 3) * 10240;
|
||||
uint64_t dmin = (uint64_t)-1;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 8; i++)
|
||||
{
|
||||
int bx = (i & 4) != 0;
|
||||
int by = (i & 2) != 0;
|
||||
int bz = (i & 1) != 0;
|
||||
int ax = pX + bx;
|
||||
int ay = pY + by;
|
||||
int az = pZ + bz;
|
||||
|
||||
int64_t s = sha;
|
||||
s = mcStepSeed(s, ax);
|
||||
s = mcStepSeed(s, ay);
|
||||
s = mcStepSeed(s, az);
|
||||
s = mcStepSeed(s, ax);
|
||||
s = mcStepSeed(s, ay);
|
||||
s = mcStepSeed(s, az);
|
||||
|
||||
int rx = (((s >> 24) & 1023) - 512) * 36;
|
||||
s = mcStepSeed(s, sha);
|
||||
int ry = (((s >> 24) & 1023) - 512) * 36;
|
||||
s = mcStepSeed(s, sha);
|
||||
int rz = (((s >> 24) & 1023) - 512) * 36;
|
||||
|
||||
rx += dx - 40*1024*bx;
|
||||
ry += dy - 40*1024*by;
|
||||
rz += dz - 40*1024*bz;
|
||||
|
||||
uint64_t d = rx*(uint64_t)rx + ry*(uint64_t)ry + rz*(uint64_t)rz;
|
||||
if (d < dmin)
|
||||
{
|
||||
dmin = d;
|
||||
*x4 = ax;
|
||||
*y4 = ay;
|
||||
*z4 = az;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
200
layers.h
200
layers.h
@ -2,6 +2,7 @@
|
||||
#define LAYER_H_
|
||||
|
||||
#include "javarnd.h"
|
||||
#include "sha256.h"
|
||||
|
||||
#define __STDC_FORMAT_MACROS 1
|
||||
|
||||
@ -152,10 +153,18 @@ STRUCT(PerlinNoise)
|
||||
double a, b, c;
|
||||
};
|
||||
|
||||
STRUCT(DoublePerlinNoise)
|
||||
{
|
||||
double amplitude;
|
||||
double lacuna[2];
|
||||
double persist[2];
|
||||
PerlinNoise *octaves[2];
|
||||
int octcnt;
|
||||
};
|
||||
|
||||
STRUCT(Layer)
|
||||
{
|
||||
int64_t layerSeed; // (depends only on layer salt)
|
||||
int64_t layerSalt; // (depends only on layer salt)
|
||||
int64_t startSalt; // (world seed dependent) = worldGenSeed, used for RND beyond the first
|
||||
int64_t startSeed; // (world seed dependent) starting point for chunk seeds
|
||||
|
||||
@ -170,6 +179,15 @@ STRUCT(Layer)
|
||||
Layer *p, *p2; // parent layers
|
||||
};
|
||||
|
||||
STRUCT(NetherNoise)
|
||||
{
|
||||
// altitude, wierdness and weight don't affect nether biomes
|
||||
DoublePerlinNoise temperature;
|
||||
DoublePerlinNoise humidity;
|
||||
PerlinNoise oct[8]; // buffer for octaves in double perlin noise
|
||||
};
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
@ -186,14 +204,99 @@ extern Biome biomes[256];
|
||||
void initBiomes();
|
||||
|
||||
/* Applies the given world seed to the layer and all dependent layers. */
|
||||
void setWorldSeed(Layer *layer, int64_t worldSeed);
|
||||
void setLayerSeed(Layer *layer, int64_t worldSeed);
|
||||
|
||||
|
||||
void perlinInit(PerlinNoise *rnd, int64_t seed);
|
||||
double samplePerlin(const PerlinNoise *rnd, double d1, double d2, double d3);
|
||||
|
||||
//==============================================================================
|
||||
// Static Helpers
|
||||
// Noise
|
||||
//==============================================================================
|
||||
|
||||
void perlinInit(PerlinNoise *rnd, int64_t *seed);
|
||||
double samplePerlin(const PerlinNoise *rnd, double x, double y, double z);
|
||||
|
||||
void doublePerlinInit(DoublePerlinNoise *rnd, int64_t *seed,
|
||||
PerlinNoise *octavesA, PerlinNoise *octavesB, int omin, int len);
|
||||
double sampleDoublePerlin(const DoublePerlinNoise *rnd,
|
||||
double x, double y, double z);
|
||||
|
||||
// nether noise is scale 1:4
|
||||
void setNetherSeed(NetherNoise *nn, int64_t seed);
|
||||
int getNetherBiome(const NetherNoise *nn, int x, int y, int z);
|
||||
|
||||
|
||||
//==============================================================================
|
||||
// Seed Helpers
|
||||
//==============================================================================
|
||||
|
||||
/**
|
||||
* The seed pipeline:
|
||||
*
|
||||
* getLayerSalt(n) -> layerSalt (ls)
|
||||
* layerSalt (ls) & worldSeed (ws) -> startSalt (st) & startSeed (ss)
|
||||
* startSeed (ss) & coords (x,z) -> chunkSeed (cs)
|
||||
*
|
||||
* The chunkSeed alone is enough to generate the first RND integer with:
|
||||
* mcFirstInt(cs, mod)
|
||||
* subsequent RND integers are generated by stepping the chunkSeed forwards,
|
||||
* salted with startSalt:
|
||||
* cs_next = mcStepSeed(cs, st)
|
||||
*/
|
||||
|
||||
static inline int64_t mcStepSeed(int64_t s, int64_t salt)
|
||||
{
|
||||
return s * (s * 6364136223846793005LL + 1442695040888963407LL) + salt;
|
||||
}
|
||||
|
||||
static inline int mcFirstInt(int64_t s, int mod)
|
||||
{
|
||||
int ret = (int)((s >> 24) % mod);
|
||||
if (ret < 0)
|
||||
ret += mod;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline int mcFirstIsZero(int64_t s, int mod)
|
||||
{
|
||||
return (int)((s >> 24) % mod) == 0;
|
||||
}
|
||||
|
||||
static inline int64_t getChunkSeed(int64_t ss, int x, int z)
|
||||
{
|
||||
int64_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)
|
||||
{
|
||||
int64_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)
|
||||
{
|
||||
int64_t st = ws;
|
||||
st = mcStepSeed(st, ls);
|
||||
st = mcStepSeed(st, ls);
|
||||
st = mcStepSeed(st, ls);
|
||||
return st;
|
||||
}
|
||||
|
||||
static inline int64_t getStartSeed(int64_t ws, int64_t ls)
|
||||
{
|
||||
int64_t ss = ws;
|
||||
ss = getStartSalt(ss, ls);
|
||||
ss = mcStepSeed(ss, 0);
|
||||
return ss;
|
||||
}
|
||||
|
||||
|
||||
//==============================================================================
|
||||
// BiomeID Helpers
|
||||
//==============================================================================
|
||||
|
||||
|
||||
@ -219,11 +322,9 @@ static inline int areSimilar112(int id1, int id2)
|
||||
return id2 == wooded_badlands_plateau || id2 == badlands_plateau;
|
||||
if (!biomeExists(id1) || !biomeExists(id2)) return 0;
|
||||
// adjust for asymmetric equality (workaround to simulate a bug in the MC java code)
|
||||
if (id1 >= 128 || id2 >= 128) {
|
||||
// skip biomes that did not overload the isEqualTo() method
|
||||
if (id2 == 130 || id2 == 133 || id2 == 134 || id2 == 149 || id2 == 151 || id2 == 155 ||
|
||||
id2 == 156 || id2 == 157 || id2 == 158 || id2 == 163 || id2 == 164) return 0;
|
||||
}
|
||||
// for biomes that did not overload the isEqualTo() method up to 1.12
|
||||
if (id2 == 130 || id2 == 133 || id2 == 134 || id2 == 149 || id2 == 151 || id2 == 155 ||
|
||||
id2 == 156 || id2 == 157 || id2 == 158 || id2 == 163 || id2 == 164) return 0;
|
||||
return getBiomeType(id1) == getBiomeType(id2);
|
||||
}
|
||||
|
||||
@ -274,81 +375,12 @@ static inline int isOceanic(int id)
|
||||
return id < 64 && ((1ULL << id) & ocean_bits);
|
||||
}
|
||||
|
||||
|
||||
static inline int isBiomeSnowy(int id)
|
||||
{
|
||||
return biomeExists(id) && biomes[id].temp < 0.1;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* The seed pipeline:
|
||||
*
|
||||
* Salt of Layer -> layerSeed (ls)
|
||||
* layerSeed (ls) & worldSeed (ws) -> startSalt (st) & startSeed (ss)
|
||||
* startSeed (ls) & coords (x,z) -> chunkSeed (cs)
|
||||
*
|
||||
* The chunkSeed alone is enough to generate the first RND integer with:
|
||||
* mcFirstInt(cs, mod)
|
||||
* subsequent RND integers are generated by stepping the chunkSeed forwards,
|
||||
* salted with startSalt:
|
||||
* cs_next = mcStepSeed(cs, st)
|
||||
*/
|
||||
|
||||
static inline int64_t mcStepSeed(int64_t s, int64_t salt)
|
||||
{
|
||||
return s * (s * 6364136223846793005LL + 1442695040888963407LL) + salt;
|
||||
}
|
||||
|
||||
static inline int mcFirstInt(int64_t s, int mod)
|
||||
{
|
||||
int ret = (int)((s >> 24) % mod);
|
||||
if (ret < 0)
|
||||
ret += mod;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline int mcFirstIsZero(int64_t s, int mod)
|
||||
{
|
||||
return (int)((s >> 24) % mod) == 0;
|
||||
}
|
||||
|
||||
static inline int64_t getChunkSeed(int64_t ss, int x, int z)
|
||||
{
|
||||
int64_t cs = ss + x;
|
||||
cs = mcStepSeed(cs, z);
|
||||
cs = mcStepSeed(cs, x);
|
||||
cs = mcStepSeed(cs, z);
|
||||
return cs;
|
||||
}
|
||||
|
||||
static inline int64_t getLayerSeed(int64_t salt)
|
||||
{
|
||||
int64_t ls = mcStepSeed(salt, salt);
|
||||
ls = mcStepSeed(ls, salt);
|
||||
ls = mcStepSeed(ls, salt);
|
||||
return ls;
|
||||
}
|
||||
|
||||
static inline int64_t getStartSalt(int64_t ws, int64_t ls)
|
||||
{
|
||||
int64_t st = ws;
|
||||
st = mcStepSeed(st, ls);
|
||||
st = mcStepSeed(st, ls);
|
||||
st = mcStepSeed(st, ls);
|
||||
return st;
|
||||
}
|
||||
|
||||
static inline int64_t getStartSeed(int64_t ws, int64_t ls)
|
||||
{
|
||||
int64_t ss = ws;
|
||||
ss = getStartSalt(ss, ls);
|
||||
ss = mcStepSeed(ss, 0);
|
||||
return ss;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//==============================================================================
|
||||
// Layers
|
||||
//==============================================================================
|
||||
@ -369,20 +401,22 @@ int mapBiomeBE (const Layer *, int *, int, int, int, int);
|
||||
int mapAddBamboo (const Layer *, int *, int, int, int, int);
|
||||
int mapRiverInit (const Layer *, int *, int, int, int, int);
|
||||
int mapBiomeEdge (const Layer *, int *, int, int, int, int);
|
||||
int mapHills (const Layer *, int *, int, int, int, int);
|
||||
int mapHills112 (const Layer *, int *, int, int, int, int);
|
||||
int mapRiver (const Layer *, int *, int, int, int, int);
|
||||
int mapSmooth (const Layer *, int *, int, int, int, int);
|
||||
int mapRareBiome (const Layer *, int *, int, int, int, int);
|
||||
int mapShore (const Layer *, int *, int, int, int, int);
|
||||
int mapRiverMix (const Layer *, int *, int, int, int, int);
|
||||
|
||||
// 1.13 layers
|
||||
int mapHills (const Layer *, int *, int, int, int, int);
|
||||
int mapOceanTemp (const Layer *, int *, int, int, int, int);
|
||||
int mapOceanMix (const Layer *, int *, int, int, int, int);
|
||||
|
||||
// final layer 1:1
|
||||
int mapVoronoiZoom (const Layer *, int *, int, int, int, int);
|
||||
int mapVoronoiZoom114 (const Layer *, int *, int, int, int, int);
|
||||
|
||||
int64_t getVoroniSHA(int64_t worldSeed);
|
||||
void voronoiAccess3D(int64_t sha, int x, int y, int z, int *x4, int *y4, int *z4);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
7
makefile
7
makefile
@ -1,4 +1,4 @@
|
||||
CC = gcc
|
||||
CC = g++
|
||||
AR = ar
|
||||
ARFLAGS = cr
|
||||
override LDFLAGS = -lm
|
||||
@ -27,7 +27,7 @@ ifeq ($(OS),Windows_NT)
|
||||
else
|
||||
libcubiomes: CFLAGS += -fPIC
|
||||
endif
|
||||
libcubiomes: layers.o generator.o finders.o util.o
|
||||
libcubiomes: sha256.o layers.o generator.o finders.o util.o
|
||||
$(AR) $(ARFLAGS) libcubiomes.a $^
|
||||
|
||||
|
||||
@ -40,6 +40,9 @@ generator.o: generator.c generator.h
|
||||
layers.o: layers.c layers.h
|
||||
$(CC) -c $(CFLAGS) $<
|
||||
|
||||
sha256.o: sha256.c sha256.h
|
||||
$(CC) -c $(CFLAGS) $<
|
||||
|
||||
util.o: util.c util.h
|
||||
$(CC) -c $(CFLAGS) $<
|
||||
|
||||
|
158
sha256.c
Normal file
158
sha256.c
Normal file
@ -0,0 +1,158 @@
|
||||
/*********************************************************************
|
||||
* Filename: sha256.c
|
||||
* Author: Brad Conte (brad AT bradconte.com)
|
||||
* Copyright:
|
||||
* Disclaimer: This code is presented "as is" without any guarantees.
|
||||
* Details: Implementation of the SHA-256 hashing algorithm.
|
||||
SHA-256 is one of the three algorithms in the SHA2
|
||||
specification. The others, SHA-384 and SHA-512, are not
|
||||
offered in this implementation.
|
||||
Algorithm specification can be found here:
|
||||
* http://csrc.nist.gov/publications/fips/fips180-2/fips180-2withchangenotice.pdf
|
||||
This implementation uses little endian byte order.
|
||||
*********************************************************************/
|
||||
|
||||
/*************************** HEADER FILES ***************************/
|
||||
#include <stdlib.h>
|
||||
#include <memory.h>
|
||||
#include "sha256.h"
|
||||
|
||||
/****************************** MACROS ******************************/
|
||||
#define ROTLEFT(a,b) (((a) << (b)) | ((a) >> (32-(b))))
|
||||
#define ROTRIGHT(a,b) (((a) >> (b)) | ((a) << (32-(b))))
|
||||
|
||||
#define CH(x,y,z) (((x) & (y)) ^ (~(x) & (z)))
|
||||
#define MAJ(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
|
||||
#define EP0(x) (ROTRIGHT(x,2) ^ ROTRIGHT(x,13) ^ ROTRIGHT(x,22))
|
||||
#define EP1(x) (ROTRIGHT(x,6) ^ ROTRIGHT(x,11) ^ ROTRIGHT(x,25))
|
||||
#define SIG0(x) (ROTRIGHT(x,7) ^ ROTRIGHT(x,18) ^ ((x) >> 3))
|
||||
#define SIG1(x) (ROTRIGHT(x,17) ^ ROTRIGHT(x,19) ^ ((x) >> 10))
|
||||
|
||||
/**************************** VARIABLES *****************************/
|
||||
static const WORD k[64] = {
|
||||
0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5,0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5,
|
||||
0xd807aa98,0x12835b01,0x243185be,0x550c7dc3,0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174,
|
||||
0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc,0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da,
|
||||
0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7,0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967,
|
||||
0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13,0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85,
|
||||
0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3,0xd192e819,0xd6990624,0xf40e3585,0x106aa070,
|
||||
0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5,0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3,
|
||||
0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208,0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2
|
||||
};
|
||||
|
||||
/*********************** FUNCTION DEFINITIONS ***********************/
|
||||
void sha256_transform(SHA256_CTX *ctx, const BYTE data[])
|
||||
{
|
||||
WORD a, b, c, d, e, f, g, h, i, j, t1, t2, m[64];
|
||||
|
||||
for (i = 0, j = 0; i < 16; ++i, j += 4)
|
||||
m[i] = (data[j] << 24) | (data[j + 1] << 16) | (data[j + 2] << 8) | (data[j + 3]);
|
||||
for ( ; i < 64; ++i)
|
||||
m[i] = SIG1(m[i - 2]) + m[i - 7] + SIG0(m[i - 15]) + m[i - 16];
|
||||
|
||||
a = ctx->state[0];
|
||||
b = ctx->state[1];
|
||||
c = ctx->state[2];
|
||||
d = ctx->state[3];
|
||||
e = ctx->state[4];
|
||||
f = ctx->state[5];
|
||||
g = ctx->state[6];
|
||||
h = ctx->state[7];
|
||||
|
||||
for (i = 0; i < 64; ++i) {
|
||||
t1 = h + EP1(e) + CH(e,f,g) + k[i] + m[i];
|
||||
t2 = EP0(a) + MAJ(a,b,c);
|
||||
h = g;
|
||||
g = f;
|
||||
f = e;
|
||||
e = d + t1;
|
||||
d = c;
|
||||
c = b;
|
||||
b = a;
|
||||
a = t1 + t2;
|
||||
}
|
||||
|
||||
ctx->state[0] += a;
|
||||
ctx->state[1] += b;
|
||||
ctx->state[2] += c;
|
||||
ctx->state[3] += d;
|
||||
ctx->state[4] += e;
|
||||
ctx->state[5] += f;
|
||||
ctx->state[6] += g;
|
||||
ctx->state[7] += h;
|
||||
}
|
||||
|
||||
void sha256_init(SHA256_CTX *ctx)
|
||||
{
|
||||
ctx->datalen = 0;
|
||||
ctx->bitlen = 0;
|
||||
ctx->state[0] = 0x6a09e667;
|
||||
ctx->state[1] = 0xbb67ae85;
|
||||
ctx->state[2] = 0x3c6ef372;
|
||||
ctx->state[3] = 0xa54ff53a;
|
||||
ctx->state[4] = 0x510e527f;
|
||||
ctx->state[5] = 0x9b05688c;
|
||||
ctx->state[6] = 0x1f83d9ab;
|
||||
ctx->state[7] = 0x5be0cd19;
|
||||
}
|
||||
|
||||
void sha256_update(SHA256_CTX *ctx, const BYTE data[], size_t len)
|
||||
{
|
||||
WORD i;
|
||||
|
||||
for (i = 0; i < len; ++i) {
|
||||
ctx->data[ctx->datalen] = data[i];
|
||||
ctx->datalen++;
|
||||
if (ctx->datalen == 64) {
|
||||
sha256_transform(ctx, ctx->data);
|
||||
ctx->bitlen += 512;
|
||||
ctx->datalen = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void sha256_final(SHA256_CTX *ctx, BYTE hash[])
|
||||
{
|
||||
WORD i;
|
||||
|
||||
i = ctx->datalen;
|
||||
|
||||
// Pad whatever data is left in the buffer.
|
||||
if (ctx->datalen < 56) {
|
||||
ctx->data[i++] = 0x80;
|
||||
while (i < 56)
|
||||
ctx->data[i++] = 0x00;
|
||||
}
|
||||
else {
|
||||
ctx->data[i++] = 0x80;
|
||||
while (i < 64)
|
||||
ctx->data[i++] = 0x00;
|
||||
sha256_transform(ctx, ctx->data);
|
||||
memset(ctx->data, 0, 56);
|
||||
}
|
||||
|
||||
// Append to the padding the total message's length in bits and transform.
|
||||
ctx->bitlen += ctx->datalen * 8;
|
||||
ctx->data[63] = ctx->bitlen;
|
||||
ctx->data[62] = ctx->bitlen >> 8;
|
||||
ctx->data[61] = ctx->bitlen >> 16;
|
||||
ctx->data[60] = ctx->bitlen >> 24;
|
||||
ctx->data[59] = ctx->bitlen >> 32;
|
||||
ctx->data[58] = ctx->bitlen >> 40;
|
||||
ctx->data[57] = ctx->bitlen >> 48;
|
||||
ctx->data[56] = ctx->bitlen >> 56;
|
||||
sha256_transform(ctx, ctx->data);
|
||||
|
||||
// Since this implementation uses little endian byte ordering and SHA uses big endian,
|
||||
// reverse all the bytes when copying the final state to the output hash.
|
||||
for (i = 0; i < 4; ++i) {
|
||||
hash[i] = (ctx->state[0] >> (24 - i * 8)) & 0x000000ff;
|
||||
hash[i + 4] = (ctx->state[1] >> (24 - i * 8)) & 0x000000ff;
|
||||
hash[i + 8] = (ctx->state[2] >> (24 - i * 8)) & 0x000000ff;
|
||||
hash[i + 12] = (ctx->state[3] >> (24 - i * 8)) & 0x000000ff;
|
||||
hash[i + 16] = (ctx->state[4] >> (24 - i * 8)) & 0x000000ff;
|
||||
hash[i + 20] = (ctx->state[5] >> (24 - i * 8)) & 0x000000ff;
|
||||
hash[i + 24] = (ctx->state[6] >> (24 - i * 8)) & 0x000000ff;
|
||||
hash[i + 28] = (ctx->state[7] >> (24 - i * 8)) & 0x000000ff;
|
||||
}
|
||||
}
|
34
sha256.h
Normal file
34
sha256.h
Normal file
@ -0,0 +1,34 @@
|
||||
/*********************************************************************
|
||||
* Filename: sha256.h
|
||||
* Author: Brad Conte (brad AT bradconte.com)
|
||||
* Copyright:
|
||||
* Disclaimer: This code is presented "as is" without any guarantees.
|
||||
* Details: Defines the API for the corresponding SHA1 implementation.
|
||||
*********************************************************************/
|
||||
|
||||
#ifndef SHA256_H
|
||||
#define SHA256_H
|
||||
|
||||
/*************************** HEADER FILES ***************************/
|
||||
#include <stddef.h>
|
||||
|
||||
/****************************** MACROS ******************************/
|
||||
#define SHA256_BLOCK_SIZE 32 // SHA256 outputs a 32 byte digest
|
||||
|
||||
/**************************** DATA TYPES ****************************/
|
||||
typedef unsigned char BYTE; // 8-bit byte
|
||||
typedef unsigned int WORD; // 32-bit word, change to "long" for 16-bit machines
|
||||
|
||||
typedef struct {
|
||||
BYTE data[64];
|
||||
WORD datalen;
|
||||
unsigned long long bitlen;
|
||||
WORD state[8];
|
||||
} SHA256_CTX;
|
||||
|
||||
/*********************** FUNCTION DECLARATIONS **********************/
|
||||
void sha256_init(SHA256_CTX *ctx);
|
||||
void sha256_update(SHA256_CTX *ctx, const BYTE data[], size_t len);
|
||||
void sha256_final(SHA256_CTX *ctx, BYTE hash[]);
|
||||
|
||||
#endif // SHA256_H
|
Loading…
x
Reference in New Issue
Block a user