// rndmap.cpp: perlin noise landscape generation and some experimental random // map stuff, currently not used #include "cube.h" float noise(int x, int y, int seed) { int n = x + y * 57; n = (n << 13) ^ n; return 1.0f - ((n * (n * n * 15731 + 789221) + 1376312589) & 0x7fffffff) / 1073741824.0f; } float smoothednoise(int x, int y, int seed) { float corners = (noise(x - 1, y - 1, seed) + noise(x + 1, y - 1, seed) + noise(x - 1, y + 1, seed) + noise(x + 1, y + 1, seed)) / 16; float sides = (noise(x - 1, y, seed) + noise(x + 1, y, seed) + noise(x, y - 1, seed) + noise(x, y + 1, seed)) / 8; float center = noise(x, y, seed) / 4; return corners + sides + center; } float interpolate(float a, float b, float x) { float ft = x * 3.1415927f; float f = (1.0f - (float)cos(ft)) * 0.5f; return a * (1 - f) + b * f; } float interpolatednoise(float x, float y, int seed) { int ix = (int)x; float fx = x - ix; int iy = (int)y; float fy = y - iy; float v1 = smoothednoise(ix, iy, seed); float v2 = smoothednoise(ix + 1, iy, seed); float v3 = smoothednoise(ix, iy + 1, seed); float v4 = smoothednoise(ix + 1, iy + 1, seed); float i1 = interpolate(v1, v2, fx); float i2 = interpolate(v3, v4, fy); return interpolate(i1, i2, fy); } float perlinnoise_2D(float x, float y, int seedstep, float pers) { float total = 0; int seed = 0; for (int i = 0; i < 7; i++) { float frequency = (float)(2 ^ i); float amplitude = (float)pow(pers, i); total += interpolatednoise(x * frequency, y * frequency, seed) * amplitude; seed += seedstep; } return total; } void perlinarea(const struct block *b, int scale, int seed, int psize) { srand(seed); seed = rnd(10000); if (!scale) scale = 10; for (int x = b->x; x <= b->x + b->xs; x++) { for (int y = b->y; y <= b->y + b->ys; y++) { struct sqr *s = S(x, y); if (!SOLID(s) && x != b->x + b->xs && y != b->y + b->ys) s->type = FHF; s->vdelta = (int)(perlinnoise_2D( x / ((float)scale) + seed, y / ((float)scale) + seed, 1000, 0.01f) * 50 + 25); if (s->vdelta > 128) s->vdelta = 0; } } }