commit 181aa007edec1c59b29a548d57e0ae2646fbc551
Author: Georges Dupéron <jahvascriptmaniac+github@free.fr>
Date: Wed, 21 Sep 2011 15:54:33 +0200
Ajout de mon générateur de terrain (gd).
Diffstat:
4 files changed, 136 insertions(+), 0 deletions(-)
diff --git a/.gitignore b/.gitignore
@@ -0,0 +1 @@
+simple-terrain
diff --git a/Makefile 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
@@ -0,0 +1,10 @@
+Minimal requirements
+====================
+
+* imagemagick
+* gcc
+
+How to test this program ?
+==========================
+
+ make
diff --git a/simple-terrain.c b/simple-terrain.c
@@ -0,0 +1,120 @@
+#include <stdio.h>
+#include <math.h>
+
+#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) - 1;
+ xd = x >> 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<SIZE; x++)
+ printf("%c", (char)get_z(x,y));
+}