X-Git-Url: http://de.git.xonotic.org/?a=blobdiff_plain;f=fractalnoise.c;h=4574902fa496379d920554fddf5022bf24f759fa;hb=2b77a4b0d8f8283a5dcaa86642d46f8ad114f189;hp=3425daf84dca34e94bb7881c1d1939d109176214;hpb=4d162c39ec059b7f3191fbb4fb18304bc9b1db59;p=xonotic%2Fdarkplaces.git diff --git a/fractalnoise.c b/fractalnoise.c index 3425daf8..4574902f 100644 --- a/fractalnoise.c +++ b/fractalnoise.c @@ -1,7 +1,7 @@ #include "quakedef.h" -void fractalnoise(byte *noise, int size, int startgrid) +void fractalnoise(qbyte *noise, int size, int startgrid) { int x, y, g, g2, amplitude, min, max, size1 = size - 1, sizepower, gridpower; int *noisebuf; @@ -18,7 +18,7 @@ void fractalnoise(byte *noise, int size, int startgrid) startgrid = bound(0, startgrid, size); amplitude = 0xFFFF; // this gets halved before use - noisebuf = qmalloc(size*size*sizeof(int)); + noisebuf = Mem_Alloc(tempmempool, size*size*sizeof(int)); memset(noisebuf, 0, size*size*sizeof(int)); for (g2 = startgrid;g2;g2 >>= 1) @@ -59,7 +59,55 @@ void fractalnoise(byte *noise, int size, int startgrid) // normalize noise and copy to output for (y = 0;y < size;y++) for (x = 0;x < size;x++) - *noise++ = (byte) (((n(x,y) - min) * 256) / max); - qfree(noisebuf); + *noise++ = (qbyte) (((n(x,y) - min) * 256) / max); + Mem_Free(noisebuf); #undef n } + +// unnormalized, used for explosions mainly, does not allocate/free memory (hence the name quick) +void fractalnoisequick(qbyte *noise, int size, int startgrid) +{ + int x, y, g, g2, amplitude, size1 = size - 1, sizepower, gridpower; +#define n(x,y) noise[((y)&size1)*size+((x)&size1)] + + for (sizepower = 0;(1 << sizepower) < size;sizepower++); + if (size != (1 << sizepower)) + Sys_Error("fractalnoise: size must be power of 2\n"); + + for (gridpower = 0;(1 << gridpower) < startgrid;gridpower++); + if (startgrid != (1 << gridpower)) + Sys_Error("fractalnoise: grid must be power of 2\n"); + + startgrid = bound(0, startgrid, size); + + amplitude = 255; // this gets halved before use + memset(noise, 0, size*size); + + for (g2 = startgrid;g2;g2 >>= 1) + { + // brownian motion (at every smaller level there is random behavior) + amplitude >>= 1; + for (y = 0;y < size;y += g2) + for (x = 0;x < size;x += g2) + n(x,y) += (rand()&litude); + + g = g2 >> 1; + if (g) + { + // subdivide, diamond-square algorythm (really this has little to do with squares) + // diamond + for (y = 0;y < size;y += g2) + for (x = 0;x < size;x += g2) + n(x+g,y+g) = (qbyte) (((int) n(x,y) + (int) n(x+g2,y) + (int) n(x,y+g2) + (int) n(x+g2,y+g2)) >> 2); + // square + for (y = 0;y < size;y += g2) + for (x = 0;x < size;x += g2) + { + n(x+g,y) = (qbyte) (((int) n(x,y) + (int) n(x+g2,y) + (int) n(x+g,y-g) + (int) n(x+g,y+g)) >> 2); + n(x,y+g) = (qbyte) (((int) n(x,y) + (int) n(x,y+g2) + (int) n(x-g,y+g) + (int) n(x+g,y+g)) >> 2); + } + } + } +#undef n +} +