4 void fractalnoise(unsigned char *noise, int size, int startgrid)
6 int x, y, g, g2, amplitude, min, max, size1 = size - 1;
8 #define n(x,y) noisebuf[((y)&size1)*size+((x)&size1)]
11 noisebuf = calloc(size*size, sizeof(int));
14 // quick 1x1 case which the rest of the code can't handle
17 for (x = 0;x < size*size;x++)
18 *noise++ = (rand()&255);
22 // clear the starting grid (the rest does not need to be cleared, it will simply be overwritten)
23 for (y = 0;y < size;y += g2)
24 for (x = 0;x < size;x += g2)
26 for (;(g = g2 >> 1) >= 1;g2 >>= 1)
28 // subdivide, diamond-square algorythm (really this has little to do with squares)
30 for (y = 0;y < size;y += g2)
31 for (x = 0;x < size;x += g2)
32 n(x+g,y+g) = (n(x,y) + n(x+g2,y) + n(x,y+g2) + n(x+g2,y+g2)) >> 2;
34 for (y = 0;y < size;y += g2)
35 for (x = 0;x < size;x += g2)
37 n(x+g,y) = (n(x,y) + n(x+g2,y) + n(x+g,y-g) + n(x+g,y+g)) >> 2;
38 n(x,y+g) = (n(x,y) + n(x,y+g2) + n(x-g,y+g) + n(x+g,y+g)) >> 2;
40 // brownian motion theory
42 for (y = 0;y < size;y += g)
43 for (x = 0;x < size;x += g)
44 n(x,y) += (rand()&litude);
46 // find range of noise values
48 for (y = 0;y < size;y++)
49 for (x = 0;x < size;x++)
51 if (n(x,y) < min) min = n(x,y);
52 if (n(x,y) > max) max = n(x,y);
55 // normalize noise and copy to output
56 for (y = 0;y < size;y++)
57 for (x = 0;x < size;x++)
58 *noise++ = (n(x,y) - min) * 255 / max;