Complete.Org: Mailing Lists: Archives: freeciv-dev: September 2004:
[Freeciv-Dev] (PR#10124) PATCH: new generator 1, hmap generator (1,5) mv
Home

[Freeciv-Dev] (PR#10124) PATCH: new generator 1, hmap generator (1,5) mv

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
To: undisclosed-recipients: ;
Subject: [Freeciv-Dev] (PR#10124) PATCH: new generator 1, hmap generator (1,5) mv to height_map.[ch]
From: "Marcelo Burda via RT" <mburda@xxxxxxxxx>
Date: Wed, 15 Sep 2004 15:48:08 -0700
Reply-to: RT_CorrespondAddressNotSet@xxxxxxxxxxxxxx

<URL: http://RT::WebBaseURL.not.configured:80/Ticket/Display.html?id=10124 >

FIX: 
some style fixed, rm 2 unused macros and do_in_map_pos is has 0 side 
effect in thers args. 
 
This patch is finished but some eglish speaker has to fix the texts 
 
Marcelo  
? _
Index: common/map.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/map.c,v
retrieving revision 1.195
diff -u -r1.195 map.c
--- common/map.c        14 Sep 2004 08:22:59 -0000      1.195
+++ common/map.c        15 Sep 2004 22:44:16 -0000
@@ -204,6 +204,7 @@
   map.riverlength           = MAP_DEFAULT_RIVERS;
   map.forestsize            = MAP_DEFAULT_FORESTS;
   map.generator             = MAP_DEFAULT_GENERATOR;
+  map.generator_smoth       = MAP_DEFAULT_GENERATOR_SMOTH;
   map.tinyisles             = MAP_DEFAULT_TINYISLES;
   map.separatepoles         = MAP_DEFAULT_SEPARATE_POLES;
   map.alltemperate          = MAP_DEFAULT_ALLTEMPERATE;
Index: common/map.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/map.h,v
retrieving revision 1.214
diff -u -r1.214 map.h
--- common/map.h        14 Sep 2004 08:22:59 -0000      1.214
+++ common/map.h        15 Sep 2004 22:44:17 -0000
@@ -170,6 +170,7 @@
   int riverlength;
   int forestsize;
   int generator;
+  int generator_smoth;
   bool tinyisles;
   bool separatepoles;
   bool alltemperate;
@@ -664,6 +665,10 @@
 #define MAP_MIN_GENERATOR        1
 #define MAP_MAX_GENERATOR        5
 
+#define MAP_DEFAULT_GENERATOR_SMOTH    3
+#define MAP_MIN_GENERATOR_SMOTH        1
+#define MAP_MAX_GENERATOR_SMOTH        8
+
 #define MAP_DEFAULT_TINYISLES    FALSE
 #define MAP_MIN_TINYISLES        FALSE
 #define MAP_MAX_TINYISLES        TRUE
Index: server/savegame.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/savegame.c,v
retrieving revision 1.186
diff -u -r1.186 savegame.c
--- server/savegame.c   14 Sep 2004 08:23:00 -0000      1.186
+++ server/savegame.c   15 Sep 2004 22:44:19 -0000
@@ -3093,6 +3093,9 @@
       map.riches = secfile_lookup_int(file, "map.riches");
       map.huts = secfile_lookup_int(file, "map.huts");
       map.generator = secfile_lookup_int(file, "map.generator");
+      map.generator_smoth =
+         secfile_lookup_int_default(file,
+                      MAP_DEFAULT_GENERATOR_SMOTH, "map.generator_smoth");
       map.seed = secfile_lookup_int(file, "map.seed");
       map.landpercent = secfile_lookup_int(file, "map.landpercent");
       map.grasssize =
@@ -3485,6 +3488,7 @@
     secfile_insert_int(file, map.forestsize, "map.forestsize");
     secfile_insert_int(file, map.huts, "map.huts");
     secfile_insert_int(file, map.generator, "map.generator");
+    secfile_insert_int(file, map.generator_smoth, "map.generator_smoth");
     secfile_insert_bool(file, map.have_huts, "map.have_huts");
     secfile_insert_int(file, map.temperature, "map.temperature");
     secfile_insert_bool(file, map.alltemperate, "map.alltemperate");
Index: server/settings.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/settings.c,v
retrieving revision 1.3
diff -u -r1.3 settings.c
--- server/settings.c   14 Sep 2004 08:23:00 -0000      1.3
+++ server/settings.c   15 Sep 2004 22:44:20 -0000
@@ -274,6 +274,16 @@
             "(Zero indicates a scenario map.)"), NULL,
          MAP_MIN_GENERATOR, MAP_MAX_GENERATOR, MAP_DEFAULT_GENERATOR)
 
+  GEN_INT("generatorsmoth", map.generator_smoth,
+         SSET_MAP_GEN, SSET_GEOLOGY, SSET_VITAL,  SSET_TO_CLIENT,
+         N_("number of smoth passes for random generator 1"),
+         N_("1 = do small continents and islands with irregular shore,"
+            " nice in small maps;\n\n"
+            "3 = default value wiht medium continents ;\n\n"
+            "8 = big continents, only nice for huges maps.\n\n"), NULL,
+         MAP_MIN_GENERATOR_SMOTH, MAP_MAX_GENERATOR_SMOTH,
+          MAP_DEFAULT_GENERATOR_SMOTH)
+
   GEN_BOOL("tinyisles", map.tinyisles,
           SSET_MAP_GEN, SSET_GEOLOGY, SSET_RARE, SSET_TO_CLIENT,
           N_("Presence of 1x1 islands"),
Index: server/generator/height_map.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/generator/height_map.c,v
retrieving revision 1.1
diff -u -r1.1 height_map.c
--- server/generator/height_map.c       14 Sep 2004 08:23:00 -0000      1.1
+++ server/generator/height_map.c       15 Sep 2004 22:44:20 -0000
@@ -1,5 +1,6 @@
 /********************************************************************** 
  Freeciv - Copyright (C) 2004 - Marcelo J. Burda
+           Copyright (C) 2002 - Karen Yeats for make_pseudofractal_hmap
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2, or (at your option)
@@ -11,5 +12,215 @@
    GNU General Public License for more details.
 ***********************************************************************/
 
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "map.h"
+#include "rand.h"
+
+#include "height_map.h"
+#include "mapgen_topology.h"
+#include "utilities.h" 
+
 int *height_map;
 int hmap_shore_level, hmap_mountain_level;
+/****************************************************************************
+  Lower the land near the polar region to avoid too much land there.
+
+  See also renomalize_hmap_poles
+****************************************************************************/
+void normalize_hmap_poles(void)
+{
+  whole_map_iterate(x, y) {
+    if (near_singularity(x, y)) {
+      hmap(x, y) = 0;
+    } else if (map_colatitude(x, y) < 2 * ICE_BASE_LEVEL) {
+      hmap(x, y) *= map_colatitude(x, y) / (2.5 * ICE_BASE_LEVEL);
+    } else if (map.separatepoles 
+              && map_colatitude(x, y) <= 2.5 * ICE_BASE_LEVEL) {
+      hmap(x, y) *= 0.1;
+    } else if (map_colatitude(x, y) <= 2.5 * ICE_BASE_LEVEL) {
+      hmap(x, y) *= map_colatitude(x, y) / (2.5 * ICE_BASE_LEVEL);
+    }
+  } whole_map_iterate_end;
+}
+
+/****************************************************************************
+  Invert the effects of normalize_hmap_poles so that we have accurate heights
+  for texturing the poles.
+****************************************************************************/
+void renormalize_hmap_poles(void)
+{
+  whole_map_iterate(x, y) {
+    if (hmap(x, y) == 0 || map_colatitude(x, y) == 0) {
+      /* Nothing. */
+    } else if (map_colatitude(x, y) < 2 * ICE_BASE_LEVEL) {
+      hmap(x, y) *= (2.5 * ICE_BASE_LEVEL) / map_colatitude(x, y);
+    } else if (map.separatepoles 
+              && map_colatitude(x, y) <= 2.5 * ICE_BASE_LEVEL) {
+      hmap(x, y) *= 10;
+    } else if (map_colatitude(x, y) <= 2.5 * ICE_BASE_LEVEL) {
+      hmap(x, y) *= (2.5 * ICE_BASE_LEVEL) /  map_colatitude(x, y);
+    }
+  } whole_map_iterate_end;
+}
+
+/**********************************************************************
+ Create uncorrelated rand map and do some call to smoth to correlate 
+ it a little and creante randoms shapes
+ **********************************************************************/
+void make_random_hmap(int smooth)
+{
+  int i = 0;
+  height_map = fc_malloc (sizeof(int) * MAX_MAP_INDEX);
+
+  INITIALIZE_ARRAY(height_map, MAX_MAP_INDEX, myrand(1000 * smooth) );
+
+  for (; i < smooth; i++) {
+    smooth_int_map(height_map, TRUE);
+  }
+
+  adjust_int_map(height_map, hmap_max_level);
+}
+
+/**************************************************************************
+  Recursive function which does the work for generator 5.
+
+  All (x0,y0) and (x1,y1) are in native coordinates.
+
+  Freeciv - Copyright (C) 2002 - Karen Yeats
+**************************************************************************/
+static void gen5rec(int step, int x0, int y0, int x1, int y1)
+{
+  int val[2][2];
+  int x1wrap = x1; /* to wrap correctly */ 
+  int y1wrap = y1; 
+
+  /* All x and y values are native. */
+
+  if (((y1 - y0 <= 0) || (x1 - x0 <= 0)) 
+      || ((y1 - y0 == 1) && (x1 - x0 == 1))) {
+    return;
+  }
+
+  if (x1 == map.xsize)
+    x1wrap = 0;
+  if (y1 == map.ysize)
+    y1wrap = 0;
+
+  val[0][0] = hnat(x0, y0);
+  val[0][1] = hnat(x0, y1wrap);
+  val[1][0] = hnat(x1wrap, y0);
+  val[1][1] = hnat(x1wrap, y1wrap);
+
+  /* set midpoints of sides to avg of side's vertices plus a random factor */
+  /* unset points are zero, don't reset if set */
+#define set_midpoints(X, Y, V)                                         \
+  do_in_map_pos(map_x, map_y, (X), (Y)) {                               \
+    if (!near_singularity(map_x, map_y)                                        
\
+       && map_colatitude(map_x, map_y) >  ICE_BASE_LEVEL/2             \
+       && hnat((X), (Y)) == 0) {                                       \
+      hnat((X), (Y)) = (V);                                            \
+    }                                                                  \
+  } do_in_map_pos_end;
+
+  set_midpoints((x0 + x1) / 2, y0,
+               (val[0][0] + val[1][0]) / 2 + myrand(step) - step / 2);
+  set_midpoints((x0 + x1) / 2,  y1wrap,
+               (val[0][1] + val[1][1]) / 2 + myrand(step) - step / 2);
+  set_midpoints(x0, (y0 + y1)/2,
+               (val[0][0] + val[0][1]) / 2 + myrand(step) - step / 2);  
+  set_midpoints(x1wrap,  (y0 + y1) / 2,
+               (val[1][0] + val[1][1]) / 2 + myrand(step) - step / 2);  
+
+  /* set middle to average of midpoints plus a random factor, if not set */
+  set_midpoints((x0 + x1) / 2, (y0 + y1) / 2,
+               ((val[0][0] + val[0][1] + val[1][0] + val[1][1]) / 4
+                + myrand(step) - step / 2));
+
+#undef set_midpoints
+
+  /* now call recursively on the four subrectangles */
+  gen5rec(2 * step / 3, x0, y0, (x1 + x0) / 2, (y1 + y0) / 2);
+  gen5rec(2 * step / 3, x0, (y1 + y0) / 2, (x1 + x0) / 2, y1);
+  gen5rec(2 * step / 3, (x1 + x0) / 2, y0, x1, (y1 + y0) / 2);
+  gen5rec(2 * step / 3, (x1 + x0) / 2, (y1 + y0) / 2, x1, y1);
+}
+
+/**************************************************************************
+Generator 5 makes earthlike worlds with one or more large continents and
+a scattering of smaller islands. It does so by dividing the world into
+blocks and on each block raising or lowering the corners, then the 
+midpoints and middle and so on recursively.  Fiddling with 'xdiv' and 
+'ydiv' will change the size of the initial blocks and, if the map does not 
+wrap in at least one direction, fiddling with 'avoidedge' will change the 
+liklihood of continents butting up to non-wrapped edges.
+
+  All X and Y values used in this function are in native coordinates.
+
+ Freeciv - Copyright (C) 2002 - Karen Yeats
+**************************************************************************/
+void make_pseudofractal1_hmap(void)
+{
+  const bool xnowrap = !topo_has_flag(TF_WRAPX);
+  const bool ynowrap = !topo_has_flag(TF_WRAPY);
+
+  /* 
+   * How many blocks should the x and y directions be divided into
+   * initially. 
+   */
+  const int xdiv = 6;          
+  const int ydiv = 5;
+
+  int xdiv2 = xdiv + (xnowrap ? 1 : 0);
+  int ydiv2 = ydiv + (ynowrap ? 1 : 0);
+
+  int xmax = map.xsize - (xnowrap ? 1 : 0);
+  int ymax = map.ysize - (ynowrap ? 1 : 0);
+  int xn, yn;
+  /* just need something > log(max(xsize, ysize)) for the recursion */
+  int step = map.xsize + map.ysize; 
+  /* edges are avoided more strongly as this increases */
+  int avoidedge = (50 - map.landpercent) * step / 100 + step / 3; 
+
+  height_map = fc_malloc(sizeof(int) * MAX_MAP_INDEX);
+
+ /* initialize map */
+  INITIALIZE_ARRAY(height_map, MAX_MAP_INDEX, 0);
+
+  /* set initial points */
+  for (xn = 0; xn < xdiv2; xn++) {
+    for (yn = 0; yn < ydiv2; yn++) {
+      do_in_map_pos(x, y, (xn * xmax / xdiv), (yn * ymax / ydiv)) {
+       /* set initial points */
+       hmap(x, y) = myrand(2 * step) - (2 * step) / 2;
+
+       if (near_singularity(x, y)) {
+         /* avoid edges (topological singularities) */
+         hmap(x, y) -= avoidedge;
+       }
+
+       if (map_colatitude(x, y) <= ICE_BASE_LEVEL / 2 ) {
+         /* separate poles and avoid too much land at poles */
+         hmap(x, y) -= myrand(avoidedge);
+       }
+      } do_in_map_pos_end;
+    }
+  }
+
+  /* calculate recursively on each block */
+  for (xn = 0; xn < xdiv; xn++) {
+    for (yn = 0; yn < ydiv; yn++) {
+      gen5rec(step, xn * xmax / xdiv, yn * ymax / ydiv, 
+             (xn + 1) * xmax / xdiv, (yn + 1) * ymax / ydiv);
+    }
+  }
+
+  /* put in some random fuzz */
+  whole_map_iterate(x, y) {
+    hmap(x, y) = 8 * hmap(x, y) + myrand(4) - 2;
+  } whole_map_iterate_end;
+
+  adjust_int_map(height_map, hmap_max_level);
+}
Index: server/generator/height_map.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/generator/height_map.h,v
retrieving revision 1.1
diff -u -r1.1 height_map.h
--- server/generator/height_map.h       14 Sep 2004 08:23:00 -0000      1.1
+++ server/generator/height_map.h       15 Sep 2004 22:44:20 -0000
@@ -1,5 +1,6 @@
 /********************************************************************** 
  Freeciv - Copyright (C) 2004 - Marcelo J. Burda
+           Copyright (C) 2002 - Karen Yeats for make_pseudofractal_hmap
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2, or (at your option)
@@ -35,4 +36,9 @@
 extern int *height_map;
 extern int hmap_shore_level, hmap_mountain_level;
 
+void normalize_hmap_poles(void);
+void renormalize_hmap_poles(void);
+void make_random_hmap(int smooth);
+void make_pseudofractal1_hmap(void);
+
 #endif  /* FC__HEIGHT__MAP_H */
Index: server/generator/mapgen.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/generator/mapgen.c,v
retrieving revision 1.2
diff -u -r1.2 mapgen.c
--- server/generator/mapgen.c   14 Sep 2004 08:23:00 -0000      1.2
+++ server/generator/mapgen.c   15 Sep 2004 22:44:21 -0000
@@ -50,12 +50,9 @@
 
 static void make_huts(int number);
 static void add_specials(int prob);
-static void mapgenerator1(void);
 static void mapgenerator2(void);
 static void mapgenerator3(void);
 static void mapgenerator4(void);
-static void mapgenerator5(void);
-static void smooth_map(void);
 static void adjust_terrain_param(void);
 
 #define RIVERS_MAXTRIES 32767
@@ -917,47 +914,6 @@
   river_map = NULL;
 }
 
-/****************************************************************************
-  Lower the land near the polar region to avoid too much land there.
-
-  See also renomalize_hmap_poles
-****************************************************************************/
-static void normalize_hmap_poles(void)
-{
-  whole_map_iterate(x, y) {
-    if (near_singularity(x, y)) {
-      hmap(x, y) = 0;
-    } else if (map_colatitude(x, y) < 2 * ICE_BASE_LEVEL) {
-      hmap(x, y) *= map_colatitude(x, y) / (2.5 * ICE_BASE_LEVEL);
-    } else if (map.separatepoles 
-              && map_colatitude(x, y) <= 2.5 * ICE_BASE_LEVEL) {
-      hmap(x, y) *= 0.1;
-    } else if (map_colatitude(x, y) <= 2.5 * ICE_BASE_LEVEL) {
-      hmap(x, y) *= map_colatitude(x, y) / (2.5 * ICE_BASE_LEVEL);
-    }
-  } whole_map_iterate_end;
-}
-
-/****************************************************************************
-  Invert the effects of normalize_hmap_poles so that we have accurate heights
-  for texturing the poles.
-****************************************************************************/
-static void renormalize_hmap_poles(void)
-{
-  whole_map_iterate(x, y) {
-    if (hmap(x, y) == 0 || map_colatitude(x, y) == 0) {
-      /* Nothing. */
-    } else if (map_colatitude(x, y) < 2 * ICE_BASE_LEVEL) {
-      hmap(x, y) *= (2.5 * ICE_BASE_LEVEL) / map_colatitude(x, y);
-    } else if (map.separatepoles 
-              && map_colatitude(x, y) <= 2.5 * ICE_BASE_LEVEL) {
-      hmap(x, y) *= 10;
-    } else if (map_colatitude(x, y) <= 2.5 * ICE_BASE_LEVEL) {
-      hmap(x, y) *= (2.5 * ICE_BASE_LEVEL) /  map_colatitude(x, y);
-    }
-  } whole_map_iterate_end;
-}
-
 /**************************************************************************
   make land simply does it all based on a generated heightmap
   1) with map.landpercent it generates a ocean/grassland map 
@@ -965,7 +921,7 @@
 **************************************************************************/
 static void make_land(void)
 {
-  adjust_int_map(height_map, hmap_max_level);
+  
   if (HAS_POLES) {
     normalize_hmap_poles();
   }
@@ -1325,16 +1281,26 @@
     adjust_terrain_param();
     /* if one mapgenerator fails, it will choose another mapgenerator */
     /* with a lower number to try again */
-    if (map.generator == 5 )
-      mapgenerator5();
+    if (map.generator == 5 ) {
+      make_pseudofractal1_hmap();
+    }
     if (map.generator == 4 )
       mapgenerator4();
     if (map.generator == 3 )
       mapgenerator3();
-    if( map.generator == 2 )
+    if (map.generator == 2 )
       mapgenerator2();
-    if( map.generator == 1 )
-      mapgenerator1();
+    if (map.generator == 1 ) {
+      make_random_hmap(map.generator_smoth);
+    }
+
+    /* if hmap only generator make anything else */
+    if (map.generator == 1 || map.generator == 5) {
+      make_land();
+      free(height_map);
+      height_map = NULL;
+    }
+
     if (!map.tinyisles) {
       remove_tiny_islands();
     }
@@ -1379,82 +1345,6 @@
   }
 }
 
-/**************************************************************************
-  mapgenerator1, highlevel function, that calls all the previous functions
-**************************************************************************/
-static void mapgenerator1(void)
-{
-  int i;
-  height_map = fc_malloc (sizeof(int) * MAX_MAP_INDEX);
-
-  INITIALIZE_ARRAY(height_map, MAX_MAP_INDEX, myrand(40) );
-
-  for (i=0;i<1500;i++) {
-    int x, y;
-
-    rand_map_pos(&x, &y);
-
-    if (near_singularity(x, y)
-       || map_colatitude(x, y) <= ICE_BASE_LEVEL / 2) { 
-      /* Avoid land near singularities or at the poles. */
-      hmap(x, y) -= myrand(5000);
-    } else { 
-      hmap(x, y) += myrand(5000);
-    }
-    if ((i % 100) == 0) {
-      smooth_map(); 
-    }
-  }
-
-  smooth_map(); 
-  smooth_map(); 
-  smooth_map(); 
-
-  make_land();
-  free(height_map);
-  height_map = NULL;
-}
-
-/**************************************************************************
-  smooth_map should be viewed as a corrosion function on the map, it
-  levels out the differences in the heightmap.
-**************************************************************************/
-static void smooth_map(void)
-{
-  /* We make a new height map and then copy it back over the old one.
-   * Care must be taken so that the new height map uses the exact same
-   * storage structure as the real one - it must be the same size and
-   * use the same indexing. The advantage of the new array is there's
-   * no feedback from overwriting in-use values.
-   */
-  int *new_hmap = fc_malloc(sizeof(int) * map.xsize * map.ysize);
-  
-  whole_map_iterate(x, y) {
-    /* double-count this tile */
-    int height_sum = hmap(x, y) * 2;
-
-    /* weight of counted tiles */
-    int counter = 2;
-
-    adjc_iterate(x, y, x2, y2) {
-      /* count adjacent tile once */
-      height_sum += hmap(x2, y2);
-      counter++;
-    } adjc_iterate_end;
-
-    /* random factor: -30..30 */
-    height_sum += myrand(61) - 30;
-
-    if (height_sum < 0)
-      height_sum = 0;
-    new_hmap[map_pos_to_index(x, y)] = height_sum / counter;
-  } whole_map_iterate_end;
-
-  memcpy(height_map, new_hmap, sizeof(int) * map.xsize * map.ysize);
-  free(new_hmap);
-}
-
-
 /****************************************************************************
   Return TRUE if a safe tile is in a radius of 1.  This function is used to
   test where to place specials on the sea.
@@ -2275,142 +2165,3 @@
 }
 
 #undef DMSIS
-
-/**************************************************************************
-  Recursive function which does the work for generator 5.
-
-  All (x0,y0) and (x1,y1) are in native coordinates.
-**************************************************************************/
-static void gen5rec(int step, int x0, int y0, int x1, int y1)
-{
-  int val[2][2];
-  int x1wrap = x1; /* to wrap correctly */ 
-  int y1wrap = y1; 
-
-  /* All x and y values are native. */
-
-  if (((y1 - y0 <= 0) || (x1 - x0 <= 0)) 
-      || ((y1 - y0 == 1) && (x1 - x0 == 1))) {
-    return;
-  }
-
-  if (x1 == map.xsize)
-    x1wrap = 0;
-  if (y1 == map.ysize)
-    y1wrap = 0;
-
-  val[0][0] = hnat(x0, y0);
-  val[0][1] = hnat(x0, y1wrap);
-  val[1][0] = hnat(x1wrap, y0);
-  val[1][1] = hnat(x1wrap, y1wrap);
-
-  /* set midpoints of sides to avg of side's vertices plus a random factor */
-  /* unset points are zero, don't reset if set */
-#define set_midpoints(X, Y, V)                                         \
-  do_in_map_pos(map_x, map_y, (X), (Y)) {                               \
-    if (!near_singularity(map_x, map_y)                                        
\
-       && map_colatitude(map_x, map_y) >  ICE_BASE_LEVEL/2             \
-       && hnat((X), (Y)) == 0) {                                       \
-      hnat((X), (Y)) = (V);                                            \
-    }                                                                  \
-  } do_in_map_pos_end;
-
-  set_midpoints((x0 + x1) / 2, y0,
-               (val[0][0] + val[1][0]) / 2 + myrand(step) - step / 2);
-  set_midpoints((x0 + x1) / 2,  y1wrap,
-               (val[0][1] + val[1][1]) / 2 + myrand(step) - step / 2);
-  set_midpoints(x0, (y0 + y1)/2,
-               (val[0][0] + val[0][1]) / 2 + myrand(step) - step / 2);  
-  set_midpoints(x1wrap,  (y0 + y1) / 2,
-               (val[1][0] + val[1][1]) / 2 + myrand(step) - step / 2);  
-
-  /* set middle to average of midpoints plus a random factor, if not set */
-  set_midpoints((x0 + x1) / 2, (y0 + y1) / 2,
-               ((val[0][0] + val[0][1] + val[1][0] + val[1][1]) / 4
-                + myrand(step) - step / 2));
-
-#undef set_midpoints
-
-  /* now call recursively on the four subrectangles */
-  gen5rec(2 * step / 3, x0, y0, (x1 + x0) / 2, (y1 + y0) / 2);
-  gen5rec(2 * step / 3, x0, (y1 + y0) / 2, (x1 + x0) / 2, y1);
-  gen5rec(2 * step / 3, (x1 + x0) / 2, y0, x1, (y1 + y0) / 2);
-  gen5rec(2 * step / 3, (x1 + x0) / 2, (y1 + y0) / 2, x1, y1);
-}
-
-/**************************************************************************
-Generator 5 makes earthlike worlds with one or more large continents and
-a scattering of smaller islands. It does so by dividing the world into
-blocks and on each block raising or lowering the corners, then the 
-midpoints and middle and so on recursively.  Fiddling with 'xdiv' and 
-'ydiv' will change the size of the initial blocks and, if the map does not 
-wrap in at least one direction, fiddling with 'avoidedge' will change the 
-liklihood of continents butting up to non-wrapped edges.
-
-  All X and Y values used in this function are in native coordinates.
-**************************************************************************/
-static void mapgenerator5(void)
-{
-  const bool xnowrap = !topo_has_flag(TF_WRAPX);
-  const bool ynowrap = !topo_has_flag(TF_WRAPY);
-
-  /* 
-   * How many blocks should the x and y directions be divided into
-   * initially. 
-   */
-  const int xdiv = 6;          
-  const int ydiv = 5;
-
-  int xdiv2 = xdiv + (xnowrap ? 1 : 0);
-  int ydiv2 = ydiv + (ynowrap ? 1 : 0);
-
-  int xmax = map.xsize - (xnowrap ? 1 : 0);
-  int ymax = map.ysize - (ynowrap ? 1 : 0);
-  int xn, yn;
-  /* just need something > log(max(xsize, ysize)) for the recursion */
-  int step = map.xsize + map.ysize; 
-  /* edges are avoided more strongly as this increases */
-  int avoidedge = (50 - map.landpercent) * step / 100 + step / 3; 
-
-  height_map = fc_malloc(sizeof(int) * MAX_MAP_INDEX);
-
- /* initialize map */
-  INITIALIZE_ARRAY(height_map, MAX_MAP_INDEX, 0);
-
-  /* set initial points */
-  for (xn = 0; xn < xdiv2; xn++) {
-    for (yn = 0; yn < ydiv2; yn++) {
-      do_in_map_pos(x, y, (xn * xmax / xdiv), (yn * ymax / ydiv)) {
-       /* set initial points */
-       hmap(x, y) = myrand(2 * step) - (2 * step) / 2;
-
-       if (near_singularity(x, y)) {
-         /* avoid edges (topological singularities) */
-         hmap(x, y) -= avoidedge;
-       }
-
-       if (map_colatitude(x, y) <= ICE_BASE_LEVEL / 2 ) {
-         /* separate poles and avoid too much land at poles */
-         hmap(x, y) -= myrand(avoidedge);
-       }
-      } do_in_map_pos_end;
-    }
-  }
-
-  /* calculate recursively on each block */
-  for (xn = 0; xn < xdiv; xn++) {
-    for (yn = 0; yn < ydiv; yn++) {
-      gen5rec(step, xn * xmax / xdiv, yn * ymax / ydiv, 
-             (xn + 1) * xmax / xdiv, (yn + 1) * ymax / ydiv);
-    }
-  }
-
-  /* put in some random fuzz */
-  whole_map_iterate(x, y) {
-    hmap(x, y) = 8 * hmap(x, y) + myrand(4) - 2;
-  } whole_map_iterate_end;
-
-  make_land();
-  free(height_map);
-  height_map = NULL;
-}
Index: server/generator/utilities.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/generator/utilities.c,v
retrieving revision 1.1
diff -u -r1.1 utilities.c
--- server/generator/utilities.c        14 Sep 2004 08:23:00 -0000      1.1
+++ server/generator/utilities.c        15 Sep 2004 22:44:21 -0000
@@ -134,3 +134,88 @@
     }
   }
 }
+bool normalize_nat_pos(int *x, int  *y) 
+{
+    int map_x, map_y;
+    bool return_value;
+
+    NATIVE_TO_MAP_POS(&map_x, &map_y, *x, *y);
+    return_value = normalize_map_pos(&map_x, &map_y);
+    MAP_TO_NATIVE_POS(x, y, map_x, map_y);
+
+    return return_value;
+}
+
+bool is_normal_nat_pos(int x, int y)
+{
+  do_in_map_pos(map_x, map_y, x, y) {
+    return is_normal_map_pos(map_x, map_y);
+  } do_in_map_pos_end;
+}
+
+#define iterate_axe(x, y, i, x0, y0, dist, Xaxe) \
+{ \
+    int x, y, i; \
+ \
+    for (i = -(dist); i <= (dist); i++) { \
+       x = x0 + (Xaxe ? i : 0); \
+       y = y0 + (Xaxe ? 0 : i); \
+       if(!normalize_nat_pos(&x, &y)) { \
+           continue; \
+       } 
+
+#define iterate_axe_end \      
+    } \
+} 
+/**************************************************************************
+ * Apply a difusion filtre on the map
+ * we assume the size is MAX_MAP_INDEX and is indexed has the main map
+ * native_to_index is used! 
+ * code assume out map value of 0 if zeroes_at_edges is set. else code dont't 
+ * diffuse from outside the real map.
+ * the filter is a Gaussian difusion 
+ * aproximated by -2..+2 tiles finite math
+ ****************************************************************************/
+ void smooth_int_map(int *int_map, bool zeroes_at_edges)
+{
+  assert(int_map != NULL);
+  float weight[5] =  {0.35,  0.5 ,1 , 0.5, 0.35};
+  float total_weight = 2.70;
+  int x, y;
+  bool axe = TRUE;
+  int alt_int_map[MAX_MAP_INDEX];
+  int *target_map, *source_map;
+
+  target_map = alt_int_map;
+  source_map = int_map;
+
+  do {
+    for (y = 0; y < map.ysize; y++) {
+      for (x = 0; x < map.xsize; x++) {
+         int  N = 0, D = 0;
+         iterate_axe(x1, y1, i, x, y, 2, axe) {
+             D += weight[i + 2];
+             N += weight[i + 2] * source_map[native_pos_to_index(x1, y1)];
+         } iterate_axe_end;
+         if(zeroes_at_edges) {
+           D = total_weight;
+         }
+         target_map[native_pos_to_index(x, y)] = N / D;
+         
+      }
+    }
+
+  if (topo_has_flag(TF_ISO) || topo_has_flag(TF_HEX)) {
+    weight[0] = weight[4] = 0.5;
+    weight[1] = weight[3] = 0.7;
+    total_weight = 3.4;  
+  }
+
+  axe = !axe;
+
+  source_map = alt_int_map;
+  target_map = int_map;
+
+  } while ( !axe );
+}
+
Index: server/generator/utilities.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/generator/utilities.h,v
retrieving revision 1.1
diff -u -r1.1 utilities.h
--- server/generator/utilities.h        14 Sep 2004 08:23:00 -0000      1.1
+++ server/generator/utilities.h        15 Sep 2004 22:44:21 -0000
@@ -17,20 +17,28 @@
  *   do_in_map_pos(mx, my, xn, yn) {
  *     map_set_terrain(mx, my, T_OCEAN);
  *   } do_in_map_pos_end;
- * Note that changing the value of the map coordinates won't change the native
- * coordinates.
+ * Note: that the map position is declared as const and can't be changed
+ * inside the block.
  */
 #define do_in_map_pos(map_x, map_y, nat_x, nat_y)                           \
 {                                                                           \
-  int map_x, map_y;                                                         \
-  NATIVE_TO_MAP_POS(&map_x, &map_y, nat_x, nat_y);                          \
-  {                                                                         
+  int _tmp_x = (nat_x), _tmp_y = (nat_y);                                   \
+  NATIVE_TO_MAP_POS(&_tmp_x, &_tmp_y, _tmp_x, _tmp_y);                      \
+  {                                                                         \
+      const int map_x = _tmp_x, map_y = _tmp_y;
 
 #define do_in_map_pos_end                                                   \
   }                                                                         \
 }
 
+bool normalize_nat_pos(int *x, int  *y);
+bool is_normal_nat_pos(int x, int y);
+
+/* int maps tools */
 void adjust_int_map(int *int_map, int int_map_max);
+void smooth_int_map(int *int_map, bool zeroes_at_edges);
+
+/* placed_map tool*/
 void create_placed_map(void);
 void destroy_placed_map(void);
 void map_set_placed(int x, int y);
@@ -41,4 +49,5 @@
 void set_placed_near_pos(int map_x, int map_y, int dist);
 
 
+
 #endif  /* FC__UTILITIES_H */

[Prev in Thread] Current Thread [Next in Thread]