From 181aa007edec1c59b29a548d57e0ae2646fbc551 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Georges=20Dup=C3=A9ron?= Date: Wed, 21 Sep 2011 15:54:33 +0200 Subject: [PATCH] =?UTF-8?q?Ajout=20de=20mon=20g=C3=A9n=C3=A9rateur=20de=20?= =?UTF-8?q?terrain=20(gd).?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 1 + Makefile | 5 ++ README.markdown | 10 ++++ simple-terrain.c | 120 +++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 136 insertions(+) create mode 100644 .gitignore create mode 100644 Makefile create mode 100644 README.markdown create mode 100644 simple-terrain.c diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a200f5e --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +simple-terrain diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..712b688 --- /dev/null +++ b/Makefile @@ -0,0 +1,5 @@ +all: simple-terrain + ./simple-terrain | display + +simple-terrain: simple-terrain.c + gcc simple-terrain.c -o simple-terrain diff --git a/README.markdown b/README.markdown new file mode 100644 index 0000000..fad719c --- /dev/null +++ b/README.markdown @@ -0,0 +1,10 @@ +Minimal requirements +==================== + +* imagemagick +* gcc + +How to test this program ? +========================== + + make diff --git a/simple-terrain.c b/simple-terrain.c new file mode 100644 index 0000000..7c6c786 --- /dev/null +++ b/simple-terrain.c @@ -0,0 +1,120 @@ +#include +#include + +#define SIZE 1024 +// best value for MAX_DETAIL is 8 +#define MAX_DETAIL 8 + +int bsr(int x) { + asm volatile("bsr %0, %0" : "=r" (x) : "0" (x) : "0"); + return x; +} + +int random_from_rec2(int a, int b, int c) { + b += a; // b = a + b // 2 bytes + a *= b; // a = a * (a + b) // 2 bytes + b ^= a; // b = (a + b) ^ (a * (a + b)) // 2 bytes + a += 211; // a = (a * (a + b)) + 5 // 2-3 bytes ; 211 is wonderfull. + b /= 2; // b = ((a + b) ^ (a * (a + b))) / 2 // 2 bytes + + if (c == 0) +// return a >> 2; // 3 bytes :( , but we can do with >>1 or even without. + return a >> 1; + return random_from_rec2(a, b, c-1); +} + +unsigned char random_from(int a, int b) { + return (random_from_rec2(a, b, 1)) & 0xff; +} + +/* Alternate method to compute a single detail level for z. + // This square + z = random_from(xd, yd); + + // x interpolation + zb = random_from(xd + 1, yd); + z += ((zb-z) * (x & mask)) >> detail; + + // y interpolation + zc = random_from(xd, yd + 1); + zb = random_from(xd + 1, yd + 1); + zc += ((zb-zc) * (x & mask)) >> detail; + z += ((zc-z) * (y & mask)) >> detail; +*/ + +int get_z(int x, int y) { + int detail, mask; + int xd, yd; + int z00, z01, z10, z11; + int xm, ym, mxm, mym; + unsigned int z, ztot; + + ztot = 0; + for (detail = 0; detail < MAX_DETAIL; detail++) { + x++; // slightly blurs vertical + y++; // and horizontal artifacts. + + mask = (1<> detail; + yd = y >> detail; + + if (0 == 0) { + // Method one + z00 = random_from(xd + 0, yd + 0); + z01 = random_from(xd + 0, yd + 1); + z10 = random_from(xd + 1, yd + 0); + z11 = random_from(xd + 1, yd + 1); + + xm = ((xd + 1) << detail) - x; + ym = ((yd + 1) << detail) - y; + mxm = (1 << detail) - xm; + mym = (1 << detail) - ym; + + z = 0; + z += z00 * xm * ym ; + z += z01 * xm * mym; + z += z10 * mxm * ym ; + z += z11 * mxm * mym; + + z >>= ((detail * 2) + (MAX_DETAIL - detail)); + // Method two + } else { + // Alternate method + int zb, zc; + // This square + z = random_from(xd, yd); + + // x interpolation + zb = random_from(xd, yd + 1); + z += ((zb-z) * (y & mask)) >> detail; + + // y interpolation + zc = random_from(xd + 1, yd); + zb = random_from(xd + 1, yd + 1); + zc += ((zb-zc) * (y & mask)) >> detail; + z += ((zc-z) * (x & mask)) >> detail; + + z >>= 0; + // Alternate method + } + + // add this detail level + ztot += z; + } + //x = x - MAX_DETAIL; // when using x++ and y++ + //y = y - MAX_DETAIL; // to reduce artifacts. + + return ztot & 0xff; +} + +int main(int argc, char** argv) { + int y; + int x; + fprintf(stderr, "Aide :\n"); + fprintf(stderr, "Utilisez ./simple-terrain | display pour visualiser la sortie.\n"); + fprintf(stderr, "Utilisez ./simple-terrain > fichier.pnm pour sauvegarder.\n"); + printf("P5 %d %d 255\n", SIZE, SIZE); + for (y=SIZE-1; y>=0; y--) + for (x=0; x