]> icculus.org git repositories - divverent/darkplaces.git/blob - fractalnoise.c
extern fix
[divverent/darkplaces.git] / fractalnoise.c
1
2 #include <stdlib.h>
3
4 void fractalnoise(unsigned char *noise, int size)
5 {
6         int x, y, g, g2, amplitude, min, max, size1 = size - 1;
7         int *noisebuf;
8 #define n(x,y) noisebuf[((y)&size1)*size+((x)&size1)]
9         noisebuf = calloc(size*size, sizeof(int));
10
11         amplitude = 32767;
12         g2 = size;
13         n(0,0) = 0;
14         for (;(g = g2 >> 1) >= 1;g2 >>= 1)
15         {
16                 // subdivide, diamond-square algorythm (really this has little to do with squares)
17                 // diamond
18                 for (y = 0;y < size;y += g2)
19                         for (x = 0;x < size;x += g2)
20                                 n(x+g,y+g) = (n(x,y) + n(x+g2,y) + n(x,y+g2) + n(x+g2,y+g2)) >> 2;
21                 // square
22                 for (y = 0;y < size;y += g2)
23                         for (x = 0;x < size;x += g2)
24                         {
25                                 n(x+g,y) = (n(x,y) + n(x+g2,y) + n(x+g,y-g) + n(x+g,y+g)) >> 2;
26                                 n(x,y+g) = (n(x,y) + n(x,y+g2) + n(x-g,y+g) + n(x+g,y+g)) >> 2;
27                         }
28                 // brownian motion theory
29                 amplitude >>= 1;
30                 for (y = 0;y < size;y += g)
31                         for (x = 0;x < size;x += g)
32                                 n(x,y) += (rand()&amplitude);
33         }
34         // find range of noise values
35         min = max = 0;
36         for (y = 0;y < size;y++)
37                 for (x = 0;x < size;x++)
38                 {
39                         if (n(x,y) < min) min = n(x,y);
40                         if (n(x,y) > max) max = n(x,y);
41                 }
42         max -= min;
43         // normalize noise and copy to output
44         for (y = 0;y < size;y++)
45                 for (x = 0;x < size;x++)
46                         *noise++ = (n(x,y) - min) * 255 / max;
47         free(noisebuf);
48 #undef n
49 }