Complete.Org: Mailing Lists: Archives: freeciv-dev: December 2003:
[Freeciv-Dev] Re: (PR#6721) A Quincuncial topology
Home

[Freeciv-Dev] Re: (PR#6721) A Quincuncial topology

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
To: rt-guest@xxxxxxxxxxx
Subject: [Freeciv-Dev] Re: (PR#6721) A Quincuncial topology
From: "Marcelo Burda" <mburda@xxxxxxxxx>
Date: Tue, 2 Dec 2003 16:12:08 -0800
Reply-to: rt@xxxxxxxxxxx

<URL: http://rt.freeciv.org/Ticket/Display.html?id=6721 >

Hello,

> I don't quite understand the splitting of patches.
yes not relay clear
> Can you send me one full patch for testing?  Then we can split off small
> parts of it for merging to CVS.

There is a full core patch in one file, i am definitely spited the GTK
client patch from the core one because i want assert there are no
problems in others clients. 

The clients work best if (civ -t trident)

I am tested in linux SuSe9.0 and it work fine, (most of the time with
gen 1)

The cvs after the 27/11 no more compile for me then the patch is to the
27/11 cvs version.

There are a rare client bug (assert) in quincuncials topology but it is
not so bad and i go fix it when working in clients.

thx for your help

Marcelo

diff -ru -Xfreeciv/diff_ignore freeciv-cvs-Nov-27/client/mapview_common.c 
freeciv/client/mapview_common.c
--- freeciv-cvs-Nov-27/client/mapview_common.c  2003-11-18 07:02:24.000000000 
+0100
+++ freeciv/client/mapview_common.c     2003-12-02 23:49:30.000000000 +0100
@@ -186,9 +186,6 @@
   base_canvas_to_map_pos(&center_map_x, &center_map_y,
                         mapview_canvas.width / 2,
                         mapview_canvas.height / 2);
-  map_distance_vector(&dx, &dy, center_map_x, center_map_y, map_x, map_y);
-  map_x = center_map_x + dx;
-  map_y = center_map_y + dy;
 
   if (is_isometric) {
     /* For a simpler example of this math, see city_to_canvas_pos(). */
@@ -292,6 +289,7 @@
   TRUE if the position is real; in this case it will be normalized. Returns
   FALSE if the tile is unreal - caller may use nearest_real_pos() if
   required.
+  no more, in reversed wrapping we need to preserve non normal pos ![mburda]
 **************************************************************************/
 bool canvas_to_map_pos(int *map_x, int *map_y, int canvas_x, int canvas_y)
 {
@@ -311,13 +309,13 @@
   map_to_native_pos(&nat_x0, &nat_y0, map_x0, map_y0);
   get_mapview_scroll_window(&xmin, &ymin, &xmax, &ymax, &xsize, &ysize);
 
-  if (topo_has_flag(TF_WRAPX)) {
+  if (XWRAP_TYPE_IS(WT_SIMPLEST)) {
     nat_x0 = FC_WRAP(nat_x0, map.xsize);
   } else {
     nat_x0 = CLIP(xmin, nat_x0, xmax - xsize);
   }
 
-  if (topo_has_flag(TF_WRAPY)) {
+  if (YWRAP_TYPE_IS(WT_SIMPLEST)) {
     nat_y0 = FC_WRAP(nat_y0, map.ysize);
   } else {
     nat_y0 = CLIP(ymin, nat_y0, ymax - ysize);
@@ -464,14 +462,22 @@
   /* Now override the above to satisfy wrapping constraints.  We allow the
    * scrolling to cover the full range of the map, plus one unit in each
    * direction (to allow scrolling with the scroll bars, for instance). */
-  if (topo_has_flag(TF_WRAPX)) {
+  if (XWRAP_TYPE_IS(WT_SIMPLEST)) {
     *xmin = -1;
     *xmax = map.xsize + *xsize;
   }
-  if (topo_has_flag(TF_WRAPY)) {
+  if (XWRAP_TYPE_IS(WT_REVERSED)) {
+    *xmin -= 5;
+    *xmax += 5;
+  }
+  if (YWRAP_TYPE_IS(WT_SIMPLEST)) {
     *ymin = -1;
     *ymax = map.ysize + *ysize;
   }
+  if (YWRAP_TYPE_IS(WT_REVERSED)) {
+    *ymin -= 5;
+    *ymax += 5;
+  }
 
   freelog(LOG_DEBUG, "x: %d<-%d->%d; y: %d<-%d->%d",
          *xmin, *xsize, *xmax, *ymin, *ymax, *ysize);
@@ -575,19 +581,19 @@
    * border, then it's a border tile.  We can only really check the
    * scrolling when the mapview window lines up with the map. */
   if (canvas_x < border_x
-      && (!same || scroll_x > xmin || topo_has_flag(TF_WRAPX))) {
+      && (!same || scroll_x > xmin || XWRAP_TYPE_IS(WT_SIMPLEST))) {
     return FALSE;
   }
   if (canvas_y < border_y
-      && (!same || scroll_y > ymin || topo_has_flag(TF_WRAPY))) {
+      && (!same || scroll_y > ymin || YWRAP_TYPE_IS(WT_SIMPLEST))) {
     return FALSE;
   }
   if (canvas_x + NORMAL_TILE_WIDTH > mapview_canvas.width - border_x
-      && (!same || scroll_x + xsize >= xmax || topo_has_flag(TF_WRAPX))) {
+      && (!same || scroll_x + xsize >= xmax || XWRAP_TYPE_IS(WT_SIMPLEST))) {
     return FALSE;
   }
   if (canvas_y + NORMAL_TILE_HEIGHT > mapview_canvas.height - border_y
-      && (!same || scroll_y + ysize >= ymax || topo_has_flag(TF_WRAPY))) {
+      && (!same || scroll_y + ysize >= ymax || YWRAP_TYPE_IS(WT_SIMPLEST))) {
     return FALSE;
   }
 
@@ -650,7 +656,7 @@
 **************************************************************************/
 static void tile_draw_borders(struct canvas_store *pcanvas_store,
                              int map_x, int map_y,
-                             int canvas_x, int canvas_y)
+                             int canvas_x, int canvas_y, bool is_reversed)
 {
   struct player *this_owner = map_get_owner(map_x, map_y), *adjc_owner;
   int x1, y1;
@@ -660,7 +666,7 @@
   }
 
   /* left side */
-  if (MAPSTEP(x1, y1, map_x, map_y, DIR8_WEST)
+  if (MAPSTEP(x1, y1, map_x, map_y, NORMALIZE_DIR(DIR8_WEST,is_reversed))
       && this_owner != (adjc_owner = map_get_owner(x1, y1))
       && tile_get_known(x1, y1)
       && this_owner) {
@@ -670,7 +676,7 @@
   }
 
   /* top side */
-  if (MAPSTEP(x1, y1, map_x, map_y, DIR8_NORTH)
+  if (MAPSTEP(x1, y1, map_x, map_y, NORMALIZE_DIR(DIR8_NORTH,is_reversed))
       && this_owner != (adjc_owner = map_get_owner(x1, y1))
       && tile_get_known(x1, y1)
       && this_owner) {
@@ -679,7 +685,7 @@
   }
 
   /* right side */
-  if (MAPSTEP(x1, y1, map_x, map_y, DIR8_EAST)
+  if (MAPSTEP(x1, y1, map_x, map_y, NORMALIZE_DIR(DIR8_EAST,is_reversed))
       && this_owner != (adjc_owner = map_get_owner(x1, y1))
       && tile_get_known(x1, y1)
       && this_owner) {
@@ -689,7 +695,7 @@
   }
 
   /* bottom side */
-  if (MAPSTEP(x1, y1, map_x, map_y, DIR8_SOUTH)
+  if (MAPSTEP(x1, y1, map_x, map_y, NORMALIZE_DIR(DIR8_SOUTH,is_reversed))
       && this_owner != (adjc_owner = map_get_owner(x1, y1))
       && tile_get_known(x1, y1)
       && this_owner) {
@@ -709,11 +715,12 @@
   struct drawn_sprite tile_sprs[80];
   bool solid_bg;
   struct player *pplayer;
-  bool is_real = normalize_map_pos(&map_x, &map_y);
+  bool is_tile_reversed, is_real = 
+   normalize_map_pos_isreversed(&map_x, &map_y, &is_tile_reversed);
 
   if (is_real && tile_get_known(map_x, map_y)) {
     int count = fill_tile_sprite_array(tile_sprs, map_x, map_y, citymode,
-                                      &solid_bg, &pplayer);
+                                      &solid_bg, &pplayer, is_tile_reversed);
     int i = 0;
 
     if (solid_bg) {
@@ -775,14 +782,14 @@
     }
 
     /* Draw national borders. */
-    tile_draw_borders(pcanvas_store, map_x, map_y, canvas_x, canvas_y);
+    tile_draw_borders(pcanvas_store, map_x, map_y, canvas_x, canvas_y, 
is_tile_reversed);
 
     if (draw_coastline && !draw_terrain) {
       enum tile_terrain_type t1 = map_get_terrain(map_x, map_y), t2;
       int x1, y1;
 
       /* left side */
-      if (MAPSTEP(x1, y1, map_x, map_y, DIR8_WEST)) {
+      if (MAPSTEP(x1, y1, map_x, map_y, 
NORMALIZE_DIR(DIR8_WEST,is_tile_reversed))) {
        t2 = map_get_terrain(x1, y1);
        if (is_ocean(t1) ^ is_ocean(t2)) {
          gui_put_line(pcanvas_store, COLOR_STD_OCEAN, LINE_NORMAL,
@@ -791,7 +798,7 @@
       }
 
       /* top side */
-      if (MAPSTEP(x1, y1, map_x, map_y, DIR8_NORTH)) {
+      if (MAPSTEP(x1, y1, map_x, map_y, 
NORMALIZE_DIR(DIR8_NORTH,is_tile_reversed))) {
        t2 = map_get_terrain(x1, y1);
        if (is_ocean(t1) ^ is_ocean(t2)) {
          gui_put_line(pcanvas_store, COLOR_STD_OCEAN, LINE_NORMAL,
@@ -812,7 +819,7 @@
       enum direction8 dir;
 
       for (dir = 0; dir < 8; dir++) {
-       if (get_drawn(map_x, map_y, dir)) {
+       if (get_drawn(map_x, map_y, NORMALIZE_DIR(dir,is_tile_reversed))) {
          draw_segment(map_x, map_y, dir);
        }
       }
diff -ru -Xfreeciv/diff_ignore freeciv-cvs-Nov-27/client/packhand.c 
freeciv/client/packhand.c
--- freeciv-cvs-Nov-27/client/packhand.c        2003-11-18 07:02:24.000000000 
+0100
+++ freeciv/client/packhand.c   2003-12-02 23:49:30.000000000 +0100
@@ -1231,7 +1231,7 @@
 {
   map.xsize=pinfo->xsize;
   map.ysize=pinfo->ysize;
-  map.topology_id = pinfo->topology_id;
+  map_init_topology(pinfo->topology_id);
   map.is_earth=pinfo->is_earth;
 
   map_allocate();
diff -ru -Xfreeciv/diff_ignore freeciv-cvs-Nov-27/client/tilespec.c 
freeciv/client/tilespec.c
--- freeciv-cvs-Nov-27/client/tilespec.c        2003-10-16 06:59:07.000000000 
+0200
+++ freeciv/client/tilespec.c   2003-12-02 23:49:30.000000000 +0100
@@ -1358,11 +1358,14 @@
     ttype_near     : terrain types of all adjacent terrain
     tspecial_near  : specials of all adjacent terrain
 **************************************************************************/
-static void build_tile_data(int map_x, int map_y,
+#define  build_tile_data(A,B,C,D,E,F)\
+  build_tile_data_reversed((A),(B),(C),(D),(E),(F),FALSE)
+static void build_tile_data_reversed(int map_x, int map_y,
                            enum tile_terrain_type *ttype,
                            enum tile_special_type *tspecial,
                            enum tile_terrain_type *ttype_near,
-                           enum tile_special_type *tspecial_near)
+                           enum tile_special_type *tspecial_near,
+                            bool is_reversed)
 {
   enum direction8 dir;
 
@@ -1379,8 +1382,7 @@
   /* Loop over all adjacent tiles.  We should have an iterator for this. */
   for (dir = 0; dir < 8; dir++) {
     int x1, y1;
-
-    if (MAPSTEP(x1, y1, map_x, map_y, dir)
+    if (MAPSTEP(x1, y1, map_x, map_y,NORMALIZE_DIR(dir, is_reversed) )
        && tile_get_known(x1, y1) != TILE_UNKNOWN) {
       tspecial_near[dir] = map_get_special(x1, y1);
       ttype_near[dir] = map_get_terrain(x1, y1);
@@ -2050,7 +2052,7 @@
 ***********************************************************************/
 int fill_tile_sprite_array(struct drawn_sprite *sprs, int abs_x0, int abs_y0,
                           bool citymode, bool *solid_bg,
-                          struct player **pplayer)
+                          struct player **pplayer, bool is_reversed)
 {
   enum tile_terrain_type ttype, ttype_near[8];
   enum tile_special_type tspecial, tspecial_near[8];
@@ -2095,8 +2097,8 @@
     }
   }
 
-  build_tile_data(abs_x0, abs_y0, 
-                 &ttype, &tspecial, ttype_near, tspecial_near);
+  build_tile_data_reversed(abs_x0, abs_y0, 
+                 &ttype, &tspecial, ttype_near, tspecial_near,is_reversed);
 
   if(map.is_earth &&
      abs_x0>=34 && abs_x0<=36 && abs_y0>=den_y && abs_y0<=den_y+1) {
@@ -2207,7 +2209,7 @@
     for (dir = 0; dir < 4; dir++) {
       int x1, y1;
 
-      if (MAPSTEP(x1, y1, abs_x0, abs_y0, DIR4_TO_DIR8[dir]))
+      if (MAPSTEP(x1, y1, abs_x0, 
abs_y0,NORMALIZE_DIR(DIR4_TO_DIR8[dir],is_reversed)))
         known[dir] = (tile_get_known(x1, y1) != TILE_UNKNOWN);
       else
         known[dir] = TRUE;
diff -ru -Xfreeciv/diff_ignore freeciv-cvs-Nov-27/client/tilespec.h 
freeciv/client/tilespec.h
--- freeciv-cvs-Nov-27/client/tilespec.h        2003-10-16 06:59:07.000000000 
+0200
+++ freeciv/client/tilespec.h   2003-12-02 23:49:30.000000000 +0100
@@ -53,15 +53,14 @@
 void tilespec_free_city_tiles(int count);
 
 /* Gfx support */
-
 int fill_tile_sprite_array_iso(struct drawn_sprite *sprs,
                               struct Sprite **coasts,
                               struct Sprite **dither,
                               int x, int y, bool citymode,
                               bool *solid_bg);
-int fill_tile_sprite_array(struct drawn_sprite *sprs, int abs_x0, int abs_y0,
-                          bool citymode, bool *solid_bg,
-                          struct player **pplayer);
+int fill_tile_sprite_array (struct drawn_sprite *sprs, int abs_x0,
+                           int abs_y0,  bool citymode, bool *solid_bg,
+                          struct player **pplayer, bool is_reversed);
 int fill_unit_sprite_array(struct drawn_sprite *sprs,
                           struct unit *punit, bool *solid_bg);
 int fill_city_sprite_array_iso(struct drawn_sprite *sprs,
diff -ru -Xfreeciv/diff_ignore freeciv-cvs-Nov-27/common/aicore/path_finding.c 
freeciv/common/aicore/path_finding.c
--- freeciv-cvs-Nov-27/common/aicore/path_finding.c     2003-11-23 
07:07:50.000000000 +0100
+++ freeciv/common/aicore/path_finding.c        2003-12-02 23:49:30.000000000 
+0100
@@ -265,7 +265,7 @@
     /* Processing Stage */
     /* The previous position is contained in {x,y} fields of map */
 
-    adjc_dir_iterate(pf_map->x, pf_map->y, x1, y1, dir) {
+    adjc_dir_iterate_isreversed(pf_map->x, pf_map->y, x1, y1, dir, 
is_reversed) {
       mapindex_t index1 = map_pos_to_index(x1, y1);
       struct pf_node *node1 = &pf_map->lattice[index1];
       utiny_t *status = &pf_map->status[index1];
@@ -324,7 +324,7 @@
          *status = NS_NEW;
          node1->extra_cost = extra;
          node1->cost = cost;
-         node1->dir_to_here = dir;
+         node1->dir_to_here = NORMALIZE_DIR(dir,is_reversed);
          pq_insert(pf_map->queue, index1, -cost_of_path);
        }
       }
@@ -707,7 +707,7 @@
 /***********************************************************************
   Creating path segment going back from d_node1 to a safe tile.
 ***********************************************************************/
-static void create_danger_segment(struct pf_map *pf_map, enum direction8 dir,
+static void create_danger_segment(struct pf_map *pf_map,
                                   struct danger_node *d_node1, int length)
 {
   int i;
@@ -817,7 +817,7 @@
            : d_node->step + 1);
 
     /* The previous position is contained in {x,y} fields of map */
-    adjc_dir_iterate(pf_map->x, pf_map->y, x1, y1, dir) {
+    adjc_dir_iterate_isreversed(pf_map->x, pf_map->y, x1, y1, dir, 
is_reversed) {
       mapindex_t index1 = map_pos_to_index(x1, y1);
       struct pf_node *node1 = &pf_map->lattice[index1];
       struct danger_node *d_node1 = &pf_map->d_lattice[index1];
@@ -880,11 +880,11 @@
                < get_total_CC(pf_map, node1->cost, node1->extra_cost))) {
          node1->extra_cost = extra;
          node1->cost = cost;
-         node1->dir_to_here = dir;
+         node1->dir_to_here = NORMALIZE_DIR(dir, is_reversed);
           d_node1->step = loc_step + 1;
          if (d_node->is_dangerous) {
            /* Transition from red to blue, need to record the path back */
-           create_danger_segment(pf_map, dir, d_node1, 
+           create_danger_segment(pf_map, d_node1, 
                                   d_node->segment_length);
          } else {
            /* Clear the path back */
@@ -917,7 +917,7 @@
                && pf_map->status[index1] == NS_PROCESSED)) {
          node1->extra_cost = extra;
          node1->cost = cost;
-         node1->dir_to_here = dir;
+         node1->dir_to_here = NORMALIZE_DIR(dir, is_reversed);
           d_node1->step = loc_step + 1;
           if (d_node->is_dangerous) {
             /* Increment the number of steps we are making across danger */
diff -ru -Xfreeciv/diff_ignore freeciv-cvs-Nov-27/common/map.c 
freeciv/common/map.c
--- freeciv-cvs-Nov-27/common/map.c     2003-11-18 07:02:27.000000000 +0100
+++ freeciv/common/map.c        2003-12-03 00:26:55.000000000 +0100
@@ -169,15 +169,90 @@
 {
   return !map.tiles;
 }
+/********************************************************************
+ choice of legal xsize and ysize near the selected ratio,
+ priority to preserve xsize*ysize over ratio 
+ this is a crude code but generaly is ok (mburda)
+*********************************************************************/ 
+void setmapratio(int Xratio, int Yratio)
+{
+    int size= map.xsize*map.ysize;
+    map.xsize=sqrt(size * Xratio/ Yratio);
+    if(map.xsize< MAP_MIN_WIDTHandHEIGHT) map.xsize=MAP_MIN_WIDTHandHEIGHT;
+    if(map.xsize> MAP_MAX_WIDTHandHEIGHT) map.xsize=MAP_MAX_WIDTHandHEIGHT;
+    map.ysize=size/map.xsize;
+    if(map.ysize< MAP_MIN_WIDTHandHEIGHT) map.ysize=MAP_MIN_WIDTHandHEIGHT;
+    if(map.ysize> MAP_MAX_WIDTHandHEIGHT) map.ysize=MAP_MAX_WIDTHandHEIGHT;
+    /* this is not a error, priority to map size */
+    map.xsize=size/map.ysize;
+    if(map.xsize< MAP_MIN_WIDTHandHEIGHT) map.xsize=MAP_MIN_WIDTHandHEIGHT;
+    if(map.xsize> MAP_MAX_WIDTHandHEIGHT) map.xsize=MAP_MAX_WIDTHandHEIGHT;
+}
+/*************************************************************************** 
+   WARNING: set topology_id this way or at last call it:
+       map_init_topology(map.topology_id) 
+
+   only set topology_id if a god one, be carrefuly to set oters flags 
+   and select the best ratio for this topology if topo as changed 
+   Alow set xsize or ysize freely after the choice of topology (mburda)
+
+   After WRAPX and WRAPY flags disapear we can symplify it a litle.
+*************************************************************************/
+
+void map_init_topology(int topology_id)
+{
+    switch(topology_id & TF_MASK)
+ {
+   case TF_FLAT: 
+       if(!( XWRAP_TYPE_IS(WT_NONE) &&  YWRAP_TYPE_IS(WT_NONE)))  
setmapratio(1, 1) ;
+       map.xwrap_type=WT_NONE; map.ywrap_type=WT_NONE;map.topology_id = 
topology_id;  
+       break;
+   case TF_CLASSIC:
+       if(!( XWRAP_TYPE_IS(WT_SIMPLEST) &&  YWRAP_TYPE_IS(WT_NONE)))  
setmapratio(8, 5) ;
+       map.xwrap_type=WT_SIMPLEST; map.ywrap_type=WT_NONE;
+       map.topology_id = topology_id | TF_WRAPX ;
+       break;
+   case TF_CLASSIC_R:
+       if(!( XWRAP_TYPE_IS(WT_NONE) &&  YWRAP_TYPE_IS(WT_SIMPLEST)))  
setmapratio(5, 8) ;
+       map.xwrap_type=WT_NONE; map.ywrap_type=WT_SIMPLEST;
+       map.topology_id = topology_id | TF_WRAPY;
+       break;
+   case TF_TORUS:
+       if(!( XWRAP_TYPE_IS(WT_SIMPLEST) &&  YWRAP_TYPE_IS(WT_SIMPLEST)))  
setmapratio(1, 1) ;
+       map.xwrap_type=WT_SIMPLEST; map.ywrap_type=WT_SIMPLEST;
+       map.topology_id = topology_id |  TF_WRAPX | TF_WRAPY;
+ 
+       break;
+   case TF_QUINCUNCIAL_SQ:
+       if(!( XWRAP_TYPE_IS(WT_REVERSED) &&  YWRAP_TYPE_IS(WT_REVERSED)))  
setmapratio(1, 1) ;
+       map.xwrap_type=WT_REVERSED; map.ywrap_type=WT_REVERSED;map.topology_id 
= topology_id;
+       break;
+   case TF_QUINCUNCIAL:
+       if(!( XWRAP_TYPE_IS(WT_SIMPLEST) &&  YWRAP_TYPE_IS(WT_REVERSED)))  
setmapratio(2, 1) ;
+       map.xwrap_type=WT_SIMPLEST; map.ywrap_type=WT_REVERSED;
+       map.topology_id = topology_id |  TF_WRAPX ;
+       break;
+   case TF_SPIN: 
+       if(!( XWRAP_TYPE_IS(WT_REVERSED) &&  YWRAP_TYPE_IS(WT_NONE)))  
setmapratio(2, 3) ;
+       map.xwrap_type=WT_REVERSED; map.ywrap_type=WT_NONE;map.topology_id = 
topology_id;
+       break;
+ 
+ };
+    /* reversed topologies test sizes */ 
+ if(XWRAP_TYPE_IS(WT_REVERSED) && (map.xsize%2 == 1)) map.xsize++;
+ if(YWRAP_TYPE_IS(WT_REVERSED) && (map.ysize%2 == 1)) map.ysize++;
+}
 
 /***************************************************************
  put some sensible values into the map structure
 ***************************************************************/
 void map_init(void)
 {
-  map.topology_id = MAP_DEFAULT_TOPO;
-  map.xsize                 = MAP_DEFAULT_WIDTH;
+  map.xsize                 = MAP_DEFAULT_WIDTH; 
   map.ysize                 = MAP_DEFAULT_HEIGHT;
+  /* i love my default ratio */
+  map_init_topology(MAP_DEFAULT_TOPO);
+
   map.seed                  = MAP_DEFAULT_SEED;
   map.riches                = MAP_DEFAULT_RICHES;
   map.is_earth              = FALSE;
@@ -199,8 +274,11 @@
   map.have_specials         = FALSE;
   map.have_rivers_overlay   = FALSE;
   map.have_huts             = FALSE;
+  
 }
 
+ 
+
 /***************************************************************
 ...
 ***************************************************************/
@@ -1371,49 +1449,128 @@
 
   Note, we need to leave x and y with sane values even in the unreal case.
   Some callers may for instance call nearest_real_pos on these values.
-**************************************************************************/
+ *************************************************************************
+ *alow the 9 topology xwrap_type-ywrap_type (mburda)
+ *************************************************************************/
 bool normalize_map_pos(int *x, int *y)
 {
-  int nat_x, nat_y;
+    bool tmp;
+    return normalize_map_pos_isreversed(x, y , &tmp);
+}
+/**************************************************************************
+ * Some of normalize_map_pos and return a is_reversed flag if the tiles is
+ * turned 180° in the original x,y map pos  (mburda)
+ * if unreal is_reversed not well defined!
+ **************************************************************************/
+bool normalize_map_pos_isreversed(int *x, int *y,bool *is_reversed)
+{
+    return normalize_map_pos_isreversed_in_a_city(x, y , is_reversed, NULL);
+}
+
+/*****************************************************************************
+ * Some of normalize_map_pos_isreversed 
+ * the tiles are real only in one pos in the city map
+ * if there are a 2 image for this one  normalize_map_pos_isreversed_in_a_city
+ * return FALSE  (mburda)
+ *****************************************************************************/
 
+bool normalize_map_pos_isreversed_in_a_city(int *px, int *py,bool 
*pis_reversed,struct city *pcity )
+{
+  int nat_x, nat_y;
+ 
   /* Normalization is best done in native coordinatees. */
-  map_to_native_pos(&nat_x, &nat_y, *x, *y);
-
+  map_to_native_pos(&nat_x, &nat_y, *px, *py);
+  if(pcity != NULL )
+  {
+      map_to_native_pos(&nat_x, &nat_y, *px, *py);
+  }
+  
   /* If the position is out of range in a non-wrapping direction, it is
    * unreal. */
-  if (!((topo_has_flag(TF_WRAPX) || (nat_x >= 0 && nat_x < map.xsize))
-       && (topo_has_flag(TF_WRAPY) || (nat_y >= 0 && nat_y < map.ysize)))) {
+  if (!(
+      ( !XWRAP_TYPE_IS(WT_NONE) || (nat_x >= 0 && nat_x < map.xsize) ) &&
+      ( !YWRAP_TYPE_IS(WT_NONE) || (nat_y >= 0 && nat_y < map.ysize) ) 
+     )) {
     return FALSE;
   }
-
-  /* Wrap in X and Y directions, as needed. */
-  if (topo_has_flag(TF_WRAPX)) {
-    nat_x = FC_WRAP(nat_x, map.xsize);
-  }
-  if (topo_has_flag(TF_WRAPY)) {
-    nat_y = FC_WRAP(nat_y, map.ysize);
+  assert(WT_SIMPLEST==1 && WT_REVERSED==2); /* next math assume this */
+  *pis_reversed=
+      (
+    ( XWRAP_TYPE_IS(WT_NONE) ||
+      (MODULO(nat_x,map.xwrap_type*map.xsize) <  map.xsize))
+     !=
+    ( YWRAP_TYPE_IS(WT_NONE) || 
+      (MODULO(nat_y,map.ywrap_type*map.ysize) < map.ysize))
+      );
+
+  /* Wrap in X and Y directions and rotate, as needed. */
+  if( *pis_reversed )
+  {
+   nat_x=MODULO(-nat_x-1, map.xsize);
+   nat_y=MODULO(-nat_y-1, map.ysize);
+  }
+  else 
+  { 
+   nat_x=MODULO(nat_x, map.xsize);
+   nat_y=MODULO(nat_y, map.ysize);
+  }
+
+  /* if in a city and there are singularities*/
+  if(*pis_reversed && (pcity != NULL) )
+  {
+      int DX,DY, city_x,city_y;
+      map_to_native_pos(&city_x, &city_y, pcity->x, pcity->y);
+      DX=abs(nat_x-city_x);
+      DY=abs(nat_y-city_y);
+      if((DX<=2 && DY<=1) || (DX<=1 && DY<=2)) return FALSE;
   }
 
   /* Now transform things back to map coordinates. */
-  native_to_map_pos(x, y, nat_x, nat_y);
+  native_to_map_pos(px, py, nat_x, nat_y);
   return TRUE;
 }
 
 /**************************************************************************
 Twiddle *x and *y to point the the nearest real tile, and ensure that the
-position is normalized.
+position is normalized. 
+alow the 9 topology xwrap_type-ywrap_type
 **************************************************************************/
 void nearest_real_pos(int *x, int *y)
 {
   int nat_x, nat_y;
+  bool is_reversed;
 
   map_to_native_pos(&nat_x, &nat_y, *x, *y);
-  if (!topo_has_flag(TF_WRAPX)) {
-    nat_x = CLIP(0, nat_x, map.xsize - 1);
-  }
-  if (!topo_has_flag(TF_WRAPY)) {
-    nat_y = CLIP(0, nat_y, map.ysize - 1);
+  assert(WT_SIMPLEST==1 && WT_REVERSED==2); /* next math assume this */
+  is_reversed=
+      (
+    ( XWRAP_TYPE_IS(WT_NONE) ||
+      (MODULO(nat_x,map.xwrap_type*map.xsize) <  map.xsize))
+     !=
+    ( YWRAP_TYPE_IS(WT_NONE) || 
+      (MODULO(nat_y,map.ywrap_type*map.ysize) < map.ysize))
+      );
+  if( is_reversed)
+  {
+   nat_x=XWRAP_TYPE_IS(WT_NONE)
+       ?CLIP(0, map.xsize-nat_x-1, map.xsize - 1)
+       :MODULO(-nat_x-1, map.xsize);
+         
+   nat_y=YWRAP_TYPE_IS(WT_NONE)
+       ?CLIP(0, map.ysize-nat_y-1, map.ysize - 1)
+       :MODULO(-nat_y-1, map.ysize);
+         
+  }
+  else 
+  { 
+   nat_x=XWRAP_TYPE_IS(WT_NONE)
+       ?CLIP(0, nat_x, map.xsize - 1)
+       :MODULO(nat_x, map.xsize);
+   nat_y=YWRAP_TYPE_IS(WT_NONE)
+         ?CLIP(0, nat_y, map.ysize - 1)
+         :MODULO(nat_y, map.ysize);
   }
+  
   native_to_map_pos(x, y, nat_x, nat_y);
 
   if (!normalize_map_pos(x, y)) {
@@ -1441,36 +1598,132 @@
 
   (See also: real_map_distance, map_distance, and sq_map_distance.)
 
-  With the standard topology the ranges of the return value are:
-    -map.xsize/2 <= dx <= map.xsize/2
+  With all 9 topology the ranges of the return value are:
+    -map.xsize   <  dx < map.xsize
     -map.ysize   <  dy <  map.ysize
 ****************************************************************************/
 void map_distance_vector(int *dx, int *dy, int x0, int y0, int x1, int y1)
 {
-  if (topo_has_flag(TF_WRAPX) || topo_has_flag(TF_WRAPY)) {
-    /* Wrapping is done in native coordinates. */
+    int Dist,_Dist,Dx,Dy,_dx,_dy;
+    /* Work is done in native coordinates. */
     map_to_native_pos(&x0, &y0, x0, y0);
     map_to_native_pos(&x1, &y1, x1, y1);
-
-    /* Find the "native" distance vector. This corresponds closely to the
-     * map distance vector but is easier to wrap. */
     *dx = x1 - x0;
     *dy = y1 - y0;
-    if (topo_has_flag(TF_WRAPX)) {
-      /* Wrap dx to be in [-map.xsize/2, map.xsize/2). */
-      *dx = FC_WRAP(*dx + map.xsize / 2, map.xsize) - map.xsize / 2;
+    /* simplest wraps */
+    if(XWRAP_TYPE_IS(WT_SIMPLEST))
+    {
+       while (*dx > map.xsize / 2) *dx -= map.xsize;
+       while (*dx <= -map.xsize / 2) *dx += map.xsize;
+    } 
+    if(YWRAP_TYPE_IS(WT_SIMPLEST))
+    {
+       while (*dy > map.ysize / 2) *dy -= map.ysize; 
+       while (*dy <= -map.ysize / 2) *dy += map.ysize;
+    } 
+    Dist=MAX(abs( *dx ),abs( *dy ));
+
+    /* reversed toologies : */    
+  
+    if(XWRAP_TYPE_IS(WT_REVERSED) && YWRAP_TYPE_IS(WT_REVERSED))
+    {
+        /* Selection of best vector to a unmirrored destination */
+               _dx = *dx-map.xsize;
+       _dy = *dy-map.ysize;
+       while (_dx > map.xsize  ) _dx -= 2*map.xsize;
+       while (_dx <= -map.xsize ) _dx += 2*map.xsize;
+       while (_dy > map.ysize ) _dy -= 2*map.ysize;
+       while (_dy <= -map.ysize ) _dy += 2*map.ysize;
+       _Dist=MAX(abs( _dx ),abs( _dy ));
+        /* best way a this point of code */
+       if (Dist > _Dist)
+       {
+           *dx = _dx ; 
+           *dy = _dy ;
+           Dist = _Dist ;
+       } 
+
+       /* Selection of best vector to a mirrored verticaly destination */
+       _dx = (map.xsize - 1 - x1) - x0 ;
+       _dy = (-1 - y1) - y0;
+       while (_dx > map.xsize  ) _dx -= 2*map.xsize;
+       while (_dx <= -map.xsize ) _dx += 2*map.xsize;
+       while (_dy > map.ysize ) _dy -= 2*map.ysize;
+       while (_dy <= -map.ysize ) _dy += 2*map.ysize;
+       _Dist=MAX(abs( _dx ),abs( _dy ));
+       /* best way a this point of code */
+       if (Dist > _Dist)
+       {
+           *dx = _dx ; 
+           *dy = _dy ;
+           Dist = _Dist ;
+       } 
+
+       /* Selection of best vector to a mirrored horizontaly destination */
+
+       _dx =( - 1 - x1) - x0 ;
+       _dy = (map.ysize-1 - y1) - y0;
+       while (_dx > map.xsize  ) _dx -= 2*map.xsize;
+       while (_dx <= -map.xsize ) _dx += 2*map.xsize;
+       while (_dy > map.ysize ) _dy -= 2*map.ysize;
+       while (_dy <= -map.ysize ) _dy += 2*map.ysize;
+       _Dist=MAX(abs( _dx ),abs( _dy ));
+
+
+       /* best way is...*/
+       if (Dist > _Dist)
+       {
+           *dx = _dx ; 
+           *dy = _dy ;
+           Dist = _Dist ;
+       } 
+
     }
-    if (topo_has_flag(TF_WRAPY)) {
-      /* Wrap dy to be in [-map.ysize/2, map.ysize/2). */
-      *dy = FC_WRAP(*dy + map.ysize / 2, map.ysize) - map.ysize / 2;
+    else if(YWRAP_TYPE_IS(WT_REVERSED))
+    {
+        // central symetry 
+       Dy=(-1-y1) - y0; 
+       Dx=(map.xsize-x1-1) - x0;
+
+        /* periodicity in y over 2 maps */ 
+        while (Dy > map.ysize ) Dy -= 2*map.ysize; 
+       while (Dy <= -map.ysize ) Dy += 2*map.ysize;
+       
+       _Dist=MAX(abs(Dx),abs(Dy)); 
+        // get the best way 
+       if(_Dist<Dist) 
+       { 
+           Dist=_Dist; 
+           *dx=Dx; 
+           *dy=Dy; 
+       } 
     }
-
+    else if( XWRAP_TYPE_IS(WT_REVERSED) )
+    {
+        // central symetry 
+       Dx=(-1-x1) - x0; 
+       Dy=(map.ysize-y1-1) - y0;
+
+        /* periodicity in y over 2 maps */ 
+        while (Dx > map.xsize ) Dx -= 2*map.xsize; 
+       while (Dx <= -map.xsize ) Dx += 2*map.xsize;
+       
+       _Dist=MAX(abs(Dx),abs(Dy)); 
+        // get the best way 
+       if(_Dist<Dist) 
+       { 
+           Dist=_Dist; 
+           *dx=Dx; 
+           *dy=Dy; 
+       } 
+    }
+    
     /* Convert the native delta vector back to a pair of map positions. */
     x1 = x0 + *dx;
     y1 = y0 + *dy;
     native_to_map_pos(&x0, &y0, x0, y0);
     native_to_map_pos(&x1, &y1, x1, y1);
-  }
+  
 
   /* Find the final (map) vector. */
   *dx = x1 - x0;
diff -ru -Xfreeciv/diff_ignore freeciv-cvs-Nov-27/common/map.h 
freeciv/common/map.h
--- freeciv-cvs-Nov-27/common/map.h     2003-11-18 07:02:27.000000000 +0100
+++ freeciv/common/map.h        2003-12-03 00:43:38.000000000 +0100
@@ -165,6 +165,8 @@
 
 struct civ_map { 
   int topology_id;
+  int xwrap_type;
+  int ywrap_type;
   int xsize, ysize; /* native dimensions */
   int seed;
   int riches;
@@ -193,18 +195,57 @@
 };
 
 enum topo_flag {
-  /* Bit-values. */
-  TF_WRAPX = 1,
-  TF_WRAPY = 2,
-  TF_ISO = 4
+  /* Bit-values(deprecated). and topos index */
+  TF_FLAT=0,    /* xwrap_type = 0 , ywrap_type = 0 */
+  TF_CLASSIC,   /* xwrap_type = 1 , ywrap_type = 0 */
+  TF_CLASSIC_R, /* xwrap_type = 0 , ywrap_type = 1 */ /* i thincs this is not 
needed for the gamers (mburda)*/
+  TF_TORUS,     /* xwrap_type = 1 , ywrap_type = 1 */
+  TF_QUINCUNCIAL_SQ,   /* xwrap_type = 2 , ywrap_type = 2 */
+  TF_QUINCUNCIAL,      /* xwrap_type = 1 , ywrap_type = 2 */ 
+  TF_SPIN,             /* xwrap_type = 2 , ywrap_type = 0 */
+  /* index_mask */
+  TF_MASK=7,
+  /* Bit-value, non deprecated flag */
+  TF_ISO = 8,
+  /* Bit-values(deprecated) */
+  TF_WRAPX = 16,  
+  TF_WRAPY = 32,  
 };
 
+enum topo_wrap_type {
+    WT_NONE=0,
+    WT_SIMPLEST=1, 
+    WT_REVERSED=2
+};
+
+/*
+
+ TF_WRAPX and TF_WRAPY are deprecated. i precerve its fontionality for 
+ the simplest topologies 
+ new code can use XWRAP_TYPE_IS() and YWRAP_TYPE_IS()
+
+ xwrap_type = WT_NONE : no wrap
+ xwrap_type = WT_SIMPLEST : simple wrap
+ xwrap_type = WT_REVERSED : wrap and reverse
+ xwrap_type = ... : wrap and ...?
+                                                                  (mburda)
+*/
+
+
 #define CURRENT_TOPOLOGY (map.topology_id)
 
 #define topo_has_flag(flag) ((CURRENT_TOPOLOGY & (flag)) != 0)
 
+#define XWRAP_TYPE_IS(WTYPE) (map.xwrap_type==(WTYPE))
+
+#define YWRAP_TYPE_IS(WTYPE) (map.ywrap_type==(WTYPE))
+ 
+#define NORMALIZE_DIR(DIR, REVERSE_FLAG) \
+      ((REVERSE_FLAG)?DIR_REVERSE(DIR):(DIR))
+
 bool map_is_empty(void);
 void map_init(void);
+void map_set_topology(int);
 void map_allocate(void);
 void map_free(void);
 
@@ -286,11 +327,19 @@
  *    MAPSTEP(x, y, x, y, dir)
  * we bend this rule here.
  */
+
+
+
 #define MAPSTEP(dest_x, dest_y, src_x, src_y, dir)     \
 (    (dest_x) = (src_x) + DIR_DX[(dir)],               \
      (dest_y) = (src_y) + DIR_DY[(dir)],               \
      normalize_map_pos(&(dest_x), &(dest_y)))
 
+#define MAPSTEP_isreversed(dest_x, dest_y, src_x, src_y, dir, reversed)        
\
+(    (dest_x) = (src_x) + DIR_DX[(dir)],               \
+     (dest_y) = (src_y) + DIR_DY[(dir)],               \
+     normalize_map_pos_isreversed(&(dest_x), &(dest_y),&(reversed)))
+
 struct player *map_get_owner(int x, int y);
 void map_set_owner(int x, int y, struct player *pplayer);
 struct city *map_get_city(int x, int y);
@@ -327,6 +376,8 @@
    || (y) < (dist) || (y) >= map.ysize - (dist))
 
 bool normalize_map_pos(int *x, int *y);
+bool normalize_map_pos_isreversed(int *x, int *y,bool *is_reversed);
+bool normalize_map_pos_isreversed_in_a_city(int *x, int *y,bool 
*is_reversed,struct city *pcity );
 void nearest_real_pos(int *x, int *y);
 void map_distance_vector(int *dx, int *dy, int x0, int y0, int x1, int y1);
 int map_num_tiles(void);
@@ -407,6 +458,7 @@
    As a special case positive is initialized as 0 (ie we start in step 2) ),
    as the center tile would else be returned by both step 1) and 2).
 */
+/* Only one time in reversed-wrapping (mburda) (TODO verify cycles !)*/
 #define iterate_outward(ARG_start_x, ARG_start_y, ARG_max_dist, ARG_x_itr, 
ARG_y_itr) \
 {                                                                             \
   int ARG_x_itr, ARG_y_itr;                                                   \
@@ -416,6 +468,7 @@
   bool MACRO_positive = FALSE;                                                \
   bool MACRO_is_border = IS_BORDER_MAP_POS(ARG_start_x, ARG_start_y,          \
                                            ARG_max_dist);                     \
+  bool MACRO_is_reversed_out=FALSE;                                            
     \
   int MACRO_dxy = 0, MACRO_do_xy;                                             \
   CHECK_MAP_POS(ARG_start_x, ARG_start_y);                                    \
   while(MACRO_dxy <= (ARG_max_dist)) {                                        \
@@ -440,9 +493,16 @@
        if (MACRO_dx > MACRO_max_dx || MACRO_dx < MACRO_min_dx)               \
          continue;                                                           \
       }                                                                       \
-      if (MACRO_is_border && !normalize_map_pos(&ARG_x_itr, &ARG_y_itr)) {    \
+      if (MACRO_is_border && !normalize_map_pos_isreversed(&ARG_x_itr,        \
+          &ARG_y_itr,&MACRO_is_reversed_out)) {                               \
        continue;                                                             \
-      }
+      }                                                                       \
+      if( MACRO_is_reversed_out &&                                            \
+      /*Only one time in reversed-wraping but not strictly outward (mburda)*/ \
+       (MAX(abs(ARG_start_x-ARG_x_itr),abs(ARG_start_y-ARG_y_itr))            \
+                                                       <=ARG_max_dist)) {     \
+        continue;                                                             \
+       }
 
 #define iterate_outward_end                                                   \
     }                                                                         \
@@ -478,18 +538,28 @@
  * position. Note that when the square is larger than the map the
  * distance vector may not be the minimum distance vector.
  */
+/*
+ * only one time if reversed wrapping [mburda]
+ */
+
 #define square_dxy_iterate(center_x, center_y, radius, x_itr, y_itr,          \
                            dx_itr, dy_itr)                                    \
 {                                                                             \
   int dx_itr, dy_itr;                                                         \
+  bool macro_is_reversed;                                                     \
   bool _is_border = IS_BORDER_MAP_POS((center_x), (center_y), (radius));      \
   CHECK_MAP_POS((center_x), (center_y));                                      \
   for (dy_itr = -(radius); dy_itr <= (radius); dy_itr++) {                    \
     for (dx_itr = -(radius); dx_itr <= (radius); dx_itr++) {                  \
       int x_itr = dx_itr + (center_x), y_itr = dy_itr + (center_y);           \
-      if (_is_border && !normalize_map_pos(&x_itr, &y_itr)) {                 \
+      if (_is_border &&                                                       \
+       !normalize_map_pos_isreversed(&x_itr, &y_itr,&macro_is_reversed)) {    \
         continue;                                                             \
-      }
+      }                                                                       \
+  if( _is_border && macro_is_reversed &&                                      \
+                    (MAX(abs(x_itr-center_x),abs(y_itr-center_y))<=radius)) { \
+      continue;                                                               \
+    }
 
 #define square_dxy_iterate_end                                                \
     }                                                                         \
@@ -541,9 +611,45 @@
 /* Iterate through all tiles adjacent to a tile.  dir_itr is the
    directional value (see DIR_D[XY]).  This assumes that center_x and
    center_y are normalized. --JDS */
+
 #define adjc_dir_iterate(center_x, center_y, x_itr, y_itr, dir_itr)           \
 {                                                                             \
   int x_itr, y_itr, dir_itr;                                                  \
+  bool MACRO_is_map_at_itr_reversed=FALSE;                                     
     \
+  bool MACRO_border = IS_BORDER_MAP_POS((center_x), (center_y), 1);           \
+  int MACRO_center_x = (center_x);                                            \
+  int MACRO_center_y = (center_y);                                            \
+  CHECK_MAP_POS(MACRO_center_x, MACRO_center_y);                              \
+  for (dir_itr = 0; dir_itr < 8; dir_itr++) {                                 \
+    DIRSTEP(x_itr, y_itr, dir_itr);                                           \
+    x_itr += MACRO_center_x;                                                  \
+    y_itr += MACRO_center_y;                                                  \
+    if (MACRO_border && !normalize_map_pos_isreversed(&x_itr, &y_itr,          
      \
+        &MACRO_is_map_at_itr_reversed)) {                                     \
+       continue;                                                             \
+    } 
+   
+#define adjc_dir_iterate_isreversed(center_x, center_y, x_itr, y_itr, 
dir_itr,_is_map_at_itr_reversed ) \
+{                                                                             \
+  int x_itr, y_itr, dir_itr;                                                  \
+  bool _is_map_at_itr_reversed=FALSE;                                          
     \
+  bool MACRO_border = IS_BORDER_MAP_POS((center_x), (center_y), 1);           \
+  int MACRO_center_x = (center_x);                                            \
+  int MACRO_center_y = (center_y);                                            \
+  CHECK_MAP_POS(MACRO_center_x, MACRO_center_y);                              \
+  for (dir_itr = 0; dir_itr < 8; dir_itr++) {                                 \
+    DIRSTEP(x_itr, y_itr, dir_itr);                                           \
+    x_itr += MACRO_center_x;                                                  \
+    y_itr += MACRO_center_y;                                                  \
+    if (MACRO_border && !normalize_map_pos_isreversed(&x_itr, &y_itr,         \
+        &_is_map_at_itr_reversed)) {                                          \
+       continue;                                                             \
+    } 
+/*  only one time if near a border in reversed-wraps topologies     [mburda] */
+#define adjc_dir_iterate_isreversed_onetime(center_x, center_y, x_itr, y_itr, 
dir_itr,_is_map_at_itr_reversed ) \
+{                                                                             \
+  int x_itr, y_itr, dir_itr;                                                  \
+  bool _is_map_at_itr_reversed=FALSE;                                          
     \
   bool MACRO_border = IS_BORDER_MAP_POS((center_x), (center_y), 1);           \
   int MACRO_center_x = (center_x);                                            \
   int MACRO_center_y = (center_y);                                            \
@@ -552,14 +658,27 @@
     DIRSTEP(x_itr, y_itr, dir_itr);                                           \
     x_itr += MACRO_center_x;                                                  \
     y_itr += MACRO_center_y;                                                  \
-    if (MACRO_border && !normalize_map_pos(&x_itr, &y_itr)) {                 \
+    if (MACRO_border && !normalize_map_pos_isreversed(&x_itr, &y_itr,         \
+        &_is_map_at_itr_reversed)) {                                          \
        continue;                                                             \
+    }                                                                         \
+    if( MACRO_border && _is_map_at_itr_reversed &&                            \
+    (MAX(abs(x_itr-center_x),abs(y_itr-center_y))<=1)) { \
+      continue;                                          \
     }
 
 #define adjc_dir_iterate_end                                                  \
   }                                                                           \
 }
 
+#define adjc_dir_iterate_isreversed_end                                       \
+  }                                                                           \
+}
+
+#define adjc_dir_iterate_isreversed_onetime_end                                
       \
+  }                                                                           \
+}
+
 /* Iterate over all positions on the globe. */
 #define whole_map_iterate(map_x, map_y)                                     \
 {                                                                           \
@@ -630,16 +749,21 @@
 {                                                                             \
   int IAC_i;                                                                  \
   int IAC_x, IAC_y;                                                           \
-  bool _is_border = IS_BORDER_MAP_POS(x, y, 1);                               \
+  bool car_is_reversed, _is_border = IS_BORDER_MAP_POS(x, y, 1);              \
   CHECK_MAP_POS(x, y);                                                        \
   for (IAC_i = 0; IAC_i < 4; IAC_i++) {                                       \
     IAC_x = x + CAR_DIR_DX[IAC_i];                                            \
     IAC_y = y + CAR_DIR_DY[IAC_i];                                            \
                                                                               \
-    if (_is_border && !normalize_map_pos(&IAC_x, &IAC_y)) {                   \
+    if (_is_border &&                                                         \
+    !normalize_map_pos_isreversed(&IAC_x, &IAC_y, &car_is_reversed)) {        \
+      continue;                                                               \
+    }                                                                         \
+  if( _is_border && car_is_reversed && (MAX(abs(x-IAC_x),abs(y-IAC_y))<=1)) { \
       continue;                                                               \
     }
 
+
 #define cartesian_adjacent_iterate_end                                        \
   }                                                                           \
 }
@@ -651,18 +775,25 @@
 #define MAP_MIN_HUTS             0
 #define MAP_MAX_HUTS             500
 
-#define MAP_DEFAULT_WIDTH        80
-#define MAP_MIN_WIDTH            40
-#define MAP_MAX_WIDTH            200
 
+/* map_init_topology() modifiy it by the x-y ratios */
+#define MAP_DEFAULT_WIDTH        80
 #define MAP_DEFAULT_HEIGHT       50
-#define MAP_MIN_HEIGHT           25
-#define MAP_MAX_HEIGHT           100
 
-#define MAP_ORIGINAL_TOPO        TF_WRAPX
-#define MAP_DEFAULT_TOPO         TF_WRAPX
+#define MAP_MIN_WIDTHandHEIGHT   20
+#define MAP_MAX_WIDTHandHEIGHT   200
+
+
+#define MAP_MIN_WIDTH           MAP_MIN_WIDTHandHEIGHT   
+#define MAP_MAX_WIDTH           MAP_MAX_WIDTHandHEIGHT
+
+#define MAP_MIN_HEIGHT           MAP_MIN_WIDTHandHEIGHT   
+#define MAP_MAX_HEIGHT           MAP_MAX_WIDTHandHEIGHT
+
+#define MAP_ORIGINAL_TOPO        TF_CLASSIC
+#define MAP_DEFAULT_TOPO         TF_CLASSIC
 #define MAP_MIN_TOPO             0
-#define MAP_MAX_TOPO             3
+#define MAP_MAX_TOPO             8
 
 #define MAP_DEFAULT_SEED         0
 #define MAP_MIN_SEED             0
diff -ru -Xfreeciv/diff_ignore freeciv-cvs-Nov-27/common/packets.c 
freeciv/common/packets.c
--- freeciv-cvs-Nov-27/common/packets.c 2003-10-30 06:59:31.000000000 +0100
+++ freeciv/common/packets.c    2003-12-02 23:49:30.000000000 +0100
@@ -1792,7 +1792,7 @@
 
   if (packet->x == -1) {
     /* since we can currently only send unsigned ints... */
-    assert(MAP_MAX_WIDTH <= 255 && MAP_MAX_HEIGHT <= 255);
+    assert(MAP_MAX_WIDTHandHEIGHT <= 255);
     dio_put_uint8(&dout, 255);
     dio_put_uint8(&dout, 255);
   } else {
diff -ru -Xfreeciv/diff_ignore freeciv-cvs-Nov-27/common/shared.h 
freeciv/common/shared.h
--- freeciv-cvs-Nov-27/common/shared.h  2003-11-23 07:07:50.000000000 +0100
+++ freeciv/common/shared.h     2003-12-03 00:35:29.000000000 +0100
@@ -99,6 +99,9 @@
 #define DIVIDE(n, d) \
     ( (n) / (d) - (( (n) < 0 && (n) % (d) < 0 ) ? 1 : 0) )
 
+/* Good version of % operator : */
+#define MODULO(X,M) ((X)%(M)+((X)%(M)>=0?0:(M)))
+
 /* Deletes bit no in val,
    moves all bits larger than no one down,
    and inserts a zero at the top. */
diff -ru -Xfreeciv/diff_ignore freeciv-cvs-Nov-27/server/gotohand.c 
freeciv/server/gotohand.c
--- freeciv-cvs-Nov-27/server/gotohand.c        2003-10-22 06:59:52.000000000 
+0200
+++ freeciv/server/gotohand.c   2003-12-02 23:49:30.000000000 +0100
@@ -299,7 +299,7 @@
                          ? WARMAP_SEACOST(x, y) : WARMAP_COST(x, y));
 
     ptile = map_get_tile(x, y);
-    adjc_dir_iterate(x, y, x1, y1, dir) {
+    adjc_dir_iterate_isreversed(x, y, x1, y1, dir, x1y1_reversed) {
       switch (move_type) {
       case LAND_MOVING:
        if (WARMAP_COST(x1, y1) <= cost)
@@ -321,7 +321,7 @@
        /* else c = ptile->move_cost[k]; 
           This led to a bad bug where a unit in a swamp was considered too far 
away */
         else { /* we have a city */
-         int tmp = map_get_tile(x1, y1)->move_cost[DIR_REVERSE(dir)];
+         int tmp = map_get_tile(x1, 
y1)->move_cost[NORMALIZE_DIR(dir,!x1y1_reversed)]; /* REVERSED_DUR(dir) */
           move_cost = (ptile->move_cost[dir] + tmp +
                       (ptile->move_cost[dir] > tmp ? 1 : 0))/2;
         }
@@ -351,7 +351,7 @@
        move_cost = 0; /* silence compiler warning */
        die("Bad/unimplemented move_type in really_generate_warmap().");
       }
-    } adjc_dir_iterate_end;
+    } adjc_dir_iterate_isreversed_end;
   }
 
   freelog(LOG_DEBUG, "Generated warmap for (%d,%d).",
@@ -485,7 +485,7 @@
 
     adjc_dir_iterate(src_x, src_y, x, y, dir) {
       /* if we didn't come from there */
-      if (!BV_ISSET(came_from, dir)
+      if (!BV_ISSET(came_from, dir) /* no normalize dir */
          && !is_ocean(map_get_terrain(x, y))
          /* and there is an enemy there */
          && is_enemy_unit_tile(map_get_tile(x, y), owner)) {
@@ -629,7 +629,7 @@
 
     /* Try to move to all tiles adjacent to x,y. The coordinats of the tile we
        try to move to are x1,y1 */
-    adjc_dir_iterate(x, y, x1, y1, dir) {
+    adjc_dir_iterate_isreversed(x, y, x1, y1, dir, x1y1_reversed) {
       if ((restriction == GOTO_MOVE_CARDINAL_ONLY)
          && !DIR_IS_CARDINAL(dir)) continue;
 
@@ -788,12 +788,14 @@
          warmap_cost[map_pos_to_index(x1, y1)] = total_cost;
          add_to_mapqueue(total_cost, x1, y1);
          BV_CLR_ALL(LOCAL_VECTOR(x1, y1));
-         BV_SET(LOCAL_VECTOR(x1, y1), DIR_REVERSE(dir));
+         BV_SET(LOCAL_VECTOR(x1, y1),NORMALIZE_DIR(dir,!x1y1_reversed));
+                                             /* DIR_REVERSE(dir) */
          freelog(LOG_DEBUG,
                  "Candidate: %s from (%d, %d) to (%d, %d), cost %d",
                  dir_get_name(dir), x, y, x1, y1, total_cost);
        } else if (warmap_cost[map_pos_to_index(x1, y1)] == total_cost) {
-         BV_SET(LOCAL_VECTOR(x1, y1), DIR_REVERSE(dir));
+         BV_SET(LOCAL_VECTOR(x1, y1),NORMALIZE_DIR(dir,!x1y1_reversed))
+                                      /*  DIR_REVERSE(dir) */;
          freelog(LOG_DEBUG,
                  "Co-Candidate: %s from (%d, %d) to (%d, %d), cost %d",
                  dir_get_name(dir), x, y, x1, y1, total_cost);
@@ -805,7 +807,7 @@
        /* Make sure we stop searching when we have no hope of finding a 
shorter path */
         maxcost = total_cost + 1;
       }
-    } adjc_dir_iterate_end;
+    } adjc_dir_iterate_isreversed_end;
   }
 
   freelog(LOG_DEBUG, "GOTO: (%d, %d) -> (%d, %d), cost = %d", 
@@ -826,7 +828,7 @@
     if (!get_from_mapqueue(&x, &y))
       break;
 
-    adjc_dir_iterate(x, y, x1, y1, dir) {
+    adjc_dir_iterate_isreversed(x, y, x1, y1, dir, x1y1_reversed) {
       if ((restriction == GOTO_MOVE_CARDINAL_ONLY)
          && !DIR_IS_CARDINAL(dir)) continue;
 
@@ -837,12 +839,13 @@
 
         add_to_mapqueue(MAXCOST-1 - move_cost, x1, y1);
        /* Mark it on the warmap */
-       WARMAP_VECTOR(x1, y1) |= 1 << DIR_REVERSE(dir); 
+       WARMAP_VECTOR(x1, y1) |= 1 << NORMALIZE_DIR(dir,!x1y1_reversed);
+                                      /* DIR_REVERSE(dir) */   
        BV_CLR(LOCAL_VECTOR(x, y), dir); /* avoid repetition */
        freelog(LOG_DEBUG, "PATH-SEGMENT: %s from (%d, %d) to (%d, %d)",
-               dir_get_name(DIR_REVERSE(dir)), x1, y1, x, y);
+               dir_get_name(NORMALIZE_DIR(dir,!x1y1_reversed)), x1, y1, x, y);
       }
-    } adjc_dir_iterate_end;
+    } adjc_dir_iterate_isreversed_end;
   }
 
   return TRUE;
diff -ru -Xfreeciv/diff_ignore freeciv-cvs-Nov-27/server/savegame.c 
freeciv/server/savegame.c
--- freeciv-cvs-Nov-27/server/savegame.c        2003-10-28 06:59:41.000000000 
+0100
+++ freeciv/server/savegame.c   2003-12-02 23:49:30.000000000 +0100
@@ -322,8 +322,8 @@
 ***************************************************************/
 static void map_tiles_load(struct section_file *file)
 {
-  map.topology_id = secfile_lookup_int_default(file, MAP_ORIGINAL_TOPO,
-                                              "map.topology_id");
+  map_init_topology(secfile_lookup_int_default(file, MAP_ORIGINAL_TOPO,
+                                              "map.topology_id"));
 
   map.is_earth=secfile_lookup_bool(file, "map.is_earth");
 
@@ -1527,7 +1527,7 @@
       assert(len > 0);
       secfile_insert_int(file, len, "player%d.u%d.goto_length", plrno, i);
       /* assumption about the chars per map position */
-      assert(MAP_MAX_HEIGHT < 1000 && MAP_MAX_WIDTH < 1000);
+      assert(MAP_MAX_WIDTHandHEIGHT < 1000);
       {
        char *goto_buf = fc_malloc(4 * len + 1);
        char *goto_buf_ptr = goto_buf;
diff -ru -Xfreeciv/diff_ignore freeciv-cvs-Nov-27/server/stdinhand.c 
freeciv/server/stdinhand.c
--- freeciv-cvs-Nov-27/server/stdinhand.c       2003-11-11 07:00:02.000000000 
+0100
+++ freeciv/server/stdinhand.c  2003-12-03 00:54:06.000000000 +0100
@@ -224,25 +224,54 @@
   
 /* Map size parameters: adjustable if we don't yet have a map */  
   GEN_INT("xsize", map.xsize, SSET_MAP_SIZE, SSET_TO_CLIENT,
-         N_("Map width in squares"), "", NULL,
-         MAP_MIN_WIDTH, MAP_MAX_WIDTH, MAP_DEFAULT_WIDTH)
+         N_("Map width in squares"),
+         N_("This value is modified when setting topology_id"), NULL,
+         MAP_MIN_WIDTHandHEIGHT,MAP_MAX_WIDTHandHEIGHT , MAP_DEFAULT_WIDTH)
     
   GEN_INT("ysize", map.ysize, SSET_MAP_SIZE, SSET_TO_CLIENT,
-         N_("Map height in squares"), "", NULL,
-         MAP_MIN_HEIGHT, MAP_MAX_HEIGHT, MAP_DEFAULT_HEIGHT)
-
+         N_("Map height in squares"),
+         N_("This value is modified when setting topology_id"), NULL,
+         MAP_MIN_WIDTHandHEIGHT, MAP_MAX_WIDTHandHEIGHT, MAP_DEFAULT_HEIGHT)
+
+/* map.topology_id determine map.xwrap_type and map.ywrap_type
+   the best way to set it is a call to map_init_topology(id) or
+   a call  map_init_topology(map.topology_id) to actualize xwrap_type
+   and ywrap_type */
   GEN_INT("topology", map.topology_id, SSET_MAP_SIZE, SSET_TO_CLIENT,
          N_("The map topology index"),
          N_("Two-dimensional maps can wrap at the north-south or \n"
-            "east-west edges, and use a cartesian or isometric \n"
-            "rectangular grid.  See the manual for further explanation.\n"
-             "  0 Flat Earth (unwrapped)          4 Flat Earth (isometric)\n"
-             "  1 Earth (wraps E-W)               5 Earth (isometric)\n"
-             "  2 Uranus (wraps N-S)              6 Uranus (isometric)\n"
-             "  3 Donut World (wraps N-S, E-W)    7 Donut World (isometric)"
+            "east-west edges or can use a nice quincuncial topology\n"
+             " and use a cartesian or isometric rectangular grid.  \n"
+            "See the manual for further explanation.\n"
+            "  Index  (+8=Isometric map) : Name ( Wraps )  \n"
+            "  0 (8) : Flat Earth     (unwrapped)\n"
+            "  1 | 17 (9 ) : Cylindrical Earth (wraps E-W)  Classic Civ2 style 
\n"
+            "  2 | 34 (10) : Cylindrical Uranus (wraps N-S)\n"
+            "  3 | 51 (11) : Donut World (wraps N-S, E-W)\n"
+            "  4  (12) : Spherical Earth (wraps E-E N-N W-W S-S) best for real 
Earth map  \n"
+            "  5 | 21 (13) : Spherical Planet (wraps E-W N-N S-S) best for 
generated map    \n"
+            "  6 (14) : Cylinderical electron (wraps E-E W-W)\n"
+           " when | you set left index but you see right one (cvs only)" 
           ), NULL, 
          MAP_MIN_TOPO, MAP_MAX_TOPO, MAP_DEFAULT_TOPO)
-
+ GEN_INT("xwrap_type", map.xwrap_type, SSET_MAP_SIZE, SSET_TO_CLIENT,
+         N_("The map xwrap type"),
+         N_("This index determine the wrapx mode \n"
+            "actualy determined by the more general topology index \n"
+             "  0 Flat on x  (unwrapped) \n"
+             "  1 Wrap on x              \n"
+             "  2 Wrap on x and reversed  "
+          ), NULL, 
+         0, 2, 1)
+ GEN_INT("ywrap_type", map.ywrap_type, SSET_MAP_SIZE, SSET_TO_CLIENT,
+         N_("The map xwrap type"),
+         N_("This index determine the wrapx mode \n"
+            "actualy determined by the more general topology index \n"
+             "  0 Flat on y  (unwrapped) \n"
+             "  1 Wrap on y              \n"
+             "  2 Wrap on y and reversed "
+          ), NULL, 
+         0, 2, 0)
 /* Map generation parameters: once we have a map these are of historical
  * interest only, and cannot be changed.
  */
@@ -3167,6 +3196,9 @@
   }
 
   if (do_update) {
+        /* if map.topology_id as modified we need to call map_init_topology */
+        /* there is not the best place for it, you can FIX IT       (mburda)*/
+        map_init_topology(map.topology_id);
     /* 
      * send any modified game parameters to the clients -- if sent
      * before RUN_GAME_STATE, triggers a popdown_races_dialog() call

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