Complete.Org: Mailing Lists: Archives: freeciv-dev: January 2004:
[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: Sun, 11 Jan 2004 10:37:11 -0800
Reply-to: rt@xxxxxxxxxxx

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

Le jeu 08/01/2004 à 01:17, Jason Short a écrit :
> <URL: http://rt.freeciv.org/Ticket/Display.html?id=6721 >
> 
> One thing -
> 
> The patch will need support for the gtk2 client (iso and non-iso view) 
> before it can be considered for inclusion.  If possible I'd suggest 
> developing for the gtk2 client and not the xaw client.
> 
> jason
this thing go wait some time, gtk2 crash all te time in my SuSe9,0:

> 1: Translated name is too long, truncating: Société de commerce de A.
Smith
civclient: shared.c:606: check_strlen:  l'assertion « 0 » a échoué.

in latest cvs version.

until this there is my latest code gtk1, xaw clients and server

Last Changes,
 all math are separated and optimized
flat is 10% faster Classical 3% and the more complex topology is no less
fast than original freeciv.
the separated fonctions are more clear to read and extend.

Marcelo

diff -ruN -Xdiff_ignore freeciv-cvs-Jan-08/client/citydlg_common.c 
freeciv/client/citydlg_common.c
--- freeciv-cvs-Jan-08/client/citydlg_common.c  2003-11-29 07:05:21.000000000 
+0100
+++ freeciv/client/citydlg_common.c     2004-01-09 20:49:32.000000000 +0100
@@ -20,6 +20,8 @@
 #include "log.h"
 #include "support.h"
 
+#include "mapview_common.h" /* for mapview_reverse_canvas */
+
 #include "clinet.h"
 #include "control.h"
 #include "options.h"           /* for concise_city_production */
@@ -70,6 +72,10 @@
     *canvas_x = (iso_x - 1) * NORMAL_TILE_WIDTH / 2;
     *canvas_y = (iso_y - 1) * NORMAL_TILE_HEIGHT / 2;
   } else {
+    if (mapview_canvas_reverse) {
+      city_x = CITY_MAP_SIZE - 1 - city_x;
+      city_y = CITY_MAP_SIZE - 1 - city_y;
+    } 
     *canvas_x = city_x * NORMAL_TILE_WIDTH;
     *canvas_y = city_y * NORMAL_TILE_HEIGHT;
   }
@@ -108,6 +114,10 @@
   } else {
     *city_x = canvas_x / NORMAL_TILE_WIDTH;
     *city_y = canvas_y / NORMAL_TILE_HEIGHT;
+    if (mapview_canvas_reverse) {
+      *city_x = CITY_MAP_SIZE - 1 - *city_x;
+      *city_y = CITY_MAP_SIZE - 1 - *city_y;
+    } 
   }
   freelog(LOG_DEBUG, "canvas_to_city_pos(pos=(%d,%d))=(%d,%d)",
          orig_canvas_x, orig_canvas_y, *city_x, *city_y);
diff -ruN -Xdiff_ignore freeciv-cvs-Jan-08/client/control.c 
freeciv/client/control.c
--- freeciv-cvs-Jan-08/client/control.c 2003-12-17 07:09:41.000000000 +0100
+++ freeciv/client/control.c    2004-01-09 20:49:32.000000000 +0100
@@ -35,6 +35,7 @@
 #include "gui_main_g.h"
 #include "mapctrl_g.h"
 #include "mapview_g.h"
+#include "mapview_common.h"
 #include "menu_g.h"
 #include "options.h"
 #include "tilespec.h"
@@ -1243,6 +1244,7 @@
 **************************************************************************/
 void do_map_click(int xtile, int ytile, enum quickselect_type qtype)
 {
+  normalize_map_pos(&xtile, &ytile);
   struct city *pcity = map_get_city(xtile, ytile);
   struct tile *ptile = map_get_tile(xtile, ytile);
   struct unit *punit = player_find_unit_by_id(game.player_ptr, hover_unit);
@@ -1580,7 +1582,8 @@
 void key_unit_move(enum direction8 gui_dir)
 {
   if (punit_focus) {
-    enum direction8 map_dir = gui_to_map_dir(gui_dir);
+    enum direction8 map_dir 
+       = NORMALIZE_DIR(gui_to_map_dir(gui_dir),mapview_canvas_reverse);
     request_move_unit_direction(punit_focus, map_dir);
   }
 }
diff -ruN -Xdiff_ignore freeciv-cvs-Jan-08/client/goto.c freeciv/client/goto.c
--- freeciv-cvs-Jan-08/client/goto.c    2004-01-04 07:15:53.000000000 +0100
+++ freeciv/client/goto.c       2004-01-09 20:49:32.000000000 +0100
@@ -59,6 +59,8 @@
    *   only one has number less than 4
    * 2. There _can_ be more than one line drawn between two tiles, because of 
    * the waypoints. */
+  /* FIX ME there are no more good, in reversed topoloies, we can not more 
+   * choice the number  less than 4 in the borders areas          [mburda] */
   struct {
     unsigned char drawn[4];
   } *tiles;
@@ -569,6 +571,7 @@
 {
   int x1, y1;
   bool is_real;
+  REVERSE_DESCRIPTOR_TYPE is_reversed;
 
   assert(is_valid_dir(dir));
 
@@ -576,10 +579,12 @@
   assert(is_real_map_pos(x, y));
   normalize_map_pos(&x, &y);
 
-  is_real = MAPSTEP(x1, y1, x, y, dir);
+  is_real = MAPSTEP_REVDES(x1, y1, x, y, dir, is_reversed);
 
   /* It makes no sense to draw a goto line to a non-existent tile. */
   assert(is_real);
+  /* we need to review this for reversed topologies */
+  assert(!is_reversed);
 
   if (dir >= 4) {
     x = x1;
@@ -630,8 +635,10 @@
 int get_drawn(int x, int y, int dir)
 {
   int dummy_x, dummy_y;
+  REVERSE_DESCRIPTOR_TYPE is_reversed;
 
-  if (!MAPSTEP(dummy_x, dummy_y, x, y, dir)) {
+  if (!MAPSTEP_REVDES(dummy_x, dummy_y, x, y, dir, is_reversed)
+      || is_reversed) {
     return 0;
   }
 
diff -ruN -Xdiff_ignore freeciv-cvs-Jan-08/client/gui-gtk/citydlg.c 
freeciv/client/gui-gtk/citydlg.c
--- freeciv-cvs-Jan-08/client/gui-gtk/citydlg.c 2004-01-07 07:15:45.000000000 
+0100
+++ freeciv/client/gui-gtk/citydlg.c    2004-01-09 20:49:32.000000000 +0100
@@ -1827,28 +1827,37 @@
 
   for (y = 0; y < CITY_MAP_SIZE; y++)
     for (x = 0; x < CITY_MAP_SIZE; x++) {
-      int map_x, map_y;
+      int map_x, map_y, nmap_x, nmap_y, rx=x, ry=y;
+ 
+      if (mapview_canvas_reverse) {
+         rx = CITY_MAP_SIZE - 1 - x;
+         ry = CITY_MAP_SIZE - 1 - y;
+      }
 
-      if (is_valid_city_coords(x, y)
-         && city_map_to_map(&map_x, &map_y, pcity, x, y)
-         && tile_get_known(map_x, map_y)) {
-       put_one_tile(&store, map_x, map_y,
-                    x * NORMAL_TILE_WIDTH, y * NORMAL_TILE_WIDTH, TRUE);
-       if (pcity->city_map[x][y] == C_TILE_WORKER)
-         put_city_tile_output(pdialog->map_canvas_store,
-                              x * NORMAL_TILE_WIDTH,
-                              y * NORMAL_TILE_HEIGHT,
-                              city_get_food_tile(x, y, pcity),
-                              city_get_shields_tile(x, y, pcity),
-                              city_get_trade_tile(x, y, pcity));
-       else if (pcity->city_map[x][y] == C_TILE_UNAVAILABLE)
-         pixmap_frame_tile_red(pdialog->map_canvas_store,
-                               x * NORMAL_TILE_WIDTH,
-                               y * NORMAL_TILE_HEIGHT);
+      if (is_valid_city_coords(x, y)) {        
+        city_map_to_map(&map_x, &map_y, pcity, x, y);
+       nmap_x = map_x;
+       nmap_y = map_y;
+       normalize_map_pos(&nmap_x, &nmap_y);
+       if (tile_get_known(nmap_x,nmap_y)) {
+         put_one_tile(&store, map_x, map_y,
+                      rx * NORMAL_TILE_WIDTH, ry * NORMAL_TILE_WIDTH, TRUE);
+         if (pcity->city_map[x][y] == C_TILE_WORKER)
+           put_city_tile_output(pdialog->map_canvas_store,
+                                rx * NORMAL_TILE_WIDTH,
+                                ry * NORMAL_TILE_HEIGHT,
+                                city_get_food_tile(x, y, pcity),
+                                city_get_shields_tile(x, y, pcity),
+                                city_get_trade_tile(x, y, pcity));
+         else if (pcity->city_map[x][y] == C_TILE_UNAVAILABLE)
+           pixmap_frame_tile_red(pdialog->map_canvas_store,
+                                 rx * NORMAL_TILE_WIDTH,
+                                 ry * NORMAL_TILE_HEIGHT);
+       }
       } else {
-       pixmap_put_black_tile(pdialog->map_canvas_store,
-                             x * NORMAL_TILE_WIDTH,
-                             y * NORMAL_TILE_HEIGHT);
+         pixmap_put_black_tile(pdialog->map_canvas_store,
+                             rx * NORMAL_TILE_WIDTH,
+                             ry * NORMAL_TILE_HEIGHT);
       }
     }
 }
diff -ruN -Xdiff_ignore freeciv-cvs-Jan-08/client/gui-gtk/mapctrl.c 
freeciv/client/gui-gtk/mapctrl.c
--- freeciv-cvs-Jan-08/client/gui-gtk/mapctrl.c 2004-01-04 07:15:54.000000000 
+0100
+++ freeciv/client/gui-gtk/mapctrl.c    2004-01-09 20:49:32.000000000 +0100
@@ -214,6 +214,7 @@
   gtk_widget_grab_focus(turn_done_button);
   is_real = canvas_to_map_pos(&xtile, &ytile, ev->x, ev->y);
   if (is_real) {
+    normalize_map_pos( &xtile, &ytile);
     pcity = map_get_city(xtile, ytile);
   }
 
diff -ruN -Xdiff_ignore freeciv-cvs-Jan-08/client/gui-gtk/mapview.c 
freeciv/client/gui-gtk/mapview.c
--- freeciv-cvs-Jan-08/client/gui-gtk/mapview.c 2003-11-20 07:02:21.000000000 
+0100
+++ freeciv/client/gui-gtk/mapview.c    2004-01-09 20:49:32.000000000 +0100
@@ -38,6 +38,7 @@
 #include "climisc.h"
 #include "control.h"           /* get_unit_in_focus() */
 #include "goto.h"
+#include "mapview_common.h"
 #include "options.h"
 #include "tilespec.h"
 
@@ -1269,6 +1270,7 @@
 **************************************************************************/
 void draw_segment(int src_x, int src_y, int dir)
 {
+  REVERSE_DESCRIPTOR_TYPE is_reversed;
   assert(get_drawn(src_x, src_y, dir) > 0);
 
   if (is_isometric) {
@@ -1279,14 +1281,27 @@
     is_real = MAPSTEP(dest_x, dest_y, src_x, src_y, dir);
     assert(is_real);
 
-    if (tile_visible_mapcanvas(src_x, src_y)) {
-      put_line(map_canvas_store, src_x, src_y, dir);
-      put_line(map_canvas->window, src_x, src_y, dir);
-    }
-    if (tile_visible_mapcanvas(dest_x, dest_y)) {
-      put_line(map_canvas_store, dest_x, dest_y, DIR_REVERSE(dir));
-      put_line(map_canvas->window, dest_x, dest_y, DIR_REVERSE(dir));
-    }
+    near_orbit_iterate(src_x, src_y, orb_x, orb_y) {
+      is_reversed = COMBINE_DESCRIPTOR(revdes_map_pos(orb_x, orb_y),
+                                      mapview_canvas_reverse);
+      if (tile_visible_mapcanvas(orb_x, orb_y)) {
+       put_line(map_canvas_store, orb_x, orb_y,
+                NORMALIZE_DIR(dir, is_reversed));
+       put_line(map_canvas->window, orb_x, orb_y,
+                NORMALIZE_DIR(dir, is_reversed));
+      }
+    } near_orbit_iterate_end;
+
+    near_orbit_iterate(dest_x, dest_y, orb_x, orb_y) {
+      is_reversed = COMBINE_DESCRIPTOR(revdes_map_pos(orb_x, orb_y),
+                                      mapview_canvas_reverse);
+      if (tile_visible_mapcanvas(orb_x, orb_y)) {
+       put_line(map_canvas_store, orb_x, orb_y,
+                NORMALIZE_DIR(dir, !is_reversed));
+       put_line(map_canvas->window, orb_x, orb_y,
+                NORMALIZE_DIR(dir, !is_reversed));
+      }
+    } near_orbit_iterate_end;
   }
 }
 
@@ -1483,14 +1498,21 @@
   struct unit *punit, *pfocus;
   enum tile_special_type special;
   int count, i = 0;
-  bool solid_bg, fog, tile_hilited;
+  bool solid_bg, fog, tile_hilited, is_reversed;
   struct canvas_store canvas_store = {pm};
 
   if (!width || !(height || height_unit))
     return;
+  
 
-  count = fill_tile_sprite_array_iso(tile_sprs, coasts, dither,
-                                    x, y, citymode, &solid_bg);
+  if (normalize_map_pos_revdes(&x, &y, &is_reversed)) {
+    is_reversed = COMBINE_DESCRIPTOR(is_reversed, mapview_canvas_reverse);
+    count = fill_tile_sprite_array_iso(tile_sprs, coasts, dither,
+                                      x, y, citymode, &solid_bg,
+                                      is_reversed);
+  } else {
+    count = -1;
+  }
 
   if (count == -1) { /* tile is unknown */
     pixmap_put_black_tile_iso(pm, canvas_x, canvas_y,
@@ -1498,10 +1520,6 @@
     return;
   }
 
-  /* Replace with check for is_normal_tile later */
-  assert(is_real_map_pos(x, y));
-  normalize_map_pos(&x, &y);
-
   fog = tile_get_known(x, y) == TILE_KNOWN_FOGGED && draw_fog_of_war;
   pcity = map_get_city(x, y);
   punit = get_drawable_unit(x, y, citymode);
@@ -1656,7 +1674,8 @@
   }
 
   /* National borders */
-  tile_draw_borders_iso(&canvas_store, x, y, canvas_x, canvas_y, draw);
+  tile_draw_borders_iso(&canvas_store, x, y, canvas_x, canvas_y, draw,
+                       is_reversed);
 
   if (draw_coastline && !draw_terrain) {
     enum tile_terrain_type t1 = map_get_terrain(x, y), t2;
diff -ruN -Xdiff_ignore freeciv-cvs-Jan-08/client/gui-sdl/mapview.c 
freeciv/client/gui-sdl/mapview.c
--- freeciv-cvs-Jan-08/client/gui-sdl/mapview.c 2004-01-05 07:15:55.000000000 
+0100
+++ freeciv/client/gui-sdl/mapview.c    2004-01-09 20:49:32.000000000 +0100
@@ -2109,7 +2109,7 @@
 
   count =
        fill_tile_sprite_array_iso(pTile_sprs, pCoasts, NULL, map_col,
-                                map_row, citymode, &solid_bg);
+                                map_row, citymode, &solid_bg,FALSE);
 
   if (count == -1) { /* tile is unknown */
     des.x = map_x;
diff -ruN -Xdiff_ignore freeciv-cvs-Jan-08/client/gui-xaw/citydlg.c 
freeciv/client/gui-xaw/citydlg.c
--- freeciv-cvs-Jan-08/client/gui-xaw/citydlg.c 2004-01-07 07:15:47.000000000 
+0100
+++ freeciv/client/gui-xaw/citydlg.c    2004-01-09 20:49:32.000000000 +0100
@@ -1539,22 +1539,26 @@
 
   for(y=0; y<CITY_MAP_SIZE; y++) {
     for(x=0; x<CITY_MAP_SIZE; x++) {
-      int map_x, map_y, canvas_x, canvas_y;
+      int map_x, map_y, nmap_x, nmap_y, canvas_x, canvas_y;
 
-      if (is_valid_city_coords(x, y)
-         && city_map_to_map(&map_x, &map_y, pcity, x, y)
-         && tile_get_known(map_x, map_y)
-         && city_to_canvas_pos(&canvas_x, &canvas_y, x, y)) {
-       put_one_tile(&store, map_x, map_y, canvas_x, canvas_y, TRUE);
-       if (pcity->city_map[x][y] == C_TILE_WORKER)
-         put_city_tile_output(XtWindow(pdialog->map_canvas),
-                              canvas_x, canvas_y,
-                              city_get_food_tile(x, y, pcity),
-                              city_get_shields_tile(x, y, pcity),
-                              city_get_trade_tile(x, y, pcity));
-       else if (pcity->city_map[x][y] == C_TILE_UNAVAILABLE)
-         pixmap_frame_tile_red(XtWindow(pdialog->map_canvas),
-                               canvas_x, canvas_y);
+      if (is_valid_city_coords(x, y)) {
+         city_map_to_map(&map_x, &map_y, pcity, x, y);
+         nmap_x=map_x;
+         nmap_y=map_y;
+         normalize_map_pos(&nmap_x, &nmap_y);
+         if(tile_get_known(nmap_x, nmap_y)
+            && city_to_canvas_pos(&canvas_x, &canvas_y, x, y)) {
+           put_one_tile(&store, map_x, map_y, canvas_x, canvas_y, TRUE);
+           if (pcity->city_map[x][y] == C_TILE_WORKER)
+               put_city_tile_output(XtWindow(pdialog->map_canvas),
+                                    canvas_x, canvas_y,
+                                    city_get_food_tile(x, y, pcity),
+                                    city_get_shields_tile(x, y, pcity),
+                                    city_get_trade_tile(x, y, pcity));
+           else if (pcity->city_map[x][y] == C_TILE_UNAVAILABLE)
+               pixmap_frame_tile_red(XtWindow(pdialog->map_canvas),
+                                     canvas_x, canvas_y);
+         }
       }
     }
   }
diff -ruN -Xdiff_ignore freeciv-cvs-Jan-08/client/gui-xaw/mapview.c 
freeciv/client/gui-xaw/mapview.c
--- freeciv-cvs-Jan-08/client/gui-xaw/mapview.c 2003-11-20 07:02:21.000000000 
+0100
+++ freeciv/client/gui-xaw/mapview.c    2004-01-09 20:49:32.000000000 +0100
@@ -1110,21 +1110,31 @@
 void draw_segment(int src_x, int src_y, int dir)
 {
   int dest_x, dest_y, is_real;
-
-  assert(get_drawn(src_x, src_y, dir) > 0);
-
+  REVERSE_DESCRIPTOR_TYPE is_reversed;
   is_real = MAPSTEP(dest_x, dest_y, src_x, src_y, dir);
   assert(is_real);
 
-  if (tile_visible_mapcanvas(src_x, src_y)) {
-    put_line(map_canvas_store, src_x, src_y, dir);
-    put_line(XtWindow(map_canvas), src_x, src_y, dir);
-  }
-
-  if (tile_visible_mapcanvas(dest_x, dest_y)) {
-    put_line(map_canvas_store, dest_x, dest_y, DIR_REVERSE(dir));
-    put_line(XtWindow(map_canvas), dest_x, dest_y, DIR_REVERSE(dir));
-  }
+  near_orbit_iterate(src_x, src_y, orb_x, orb_y) {
+    is_reversed = COMBINE_DESCRIPTOR(revdes_map_pos(orb_x, orb_y),
+                                    mapview_canvas_reverse);
+    if (tile_visible_mapcanvas(orb_x, orb_y)) {
+      put_line(map_canvas_store, orb_x, orb_y,
+              NORMALIZE_DIR(dir, is_reversed));
+      put_line(XtWindow(map_canvas), orb_x, orb_y,
+              NORMALIZE_DIR(dir, is_reversed));
+    }
+  } near_orbit_iterate_end;
+
+  near_orbit_iterate(dest_x, dest_y, orb_x, orb_y) {
+    is_reversed = COMBINE_DESCRIPTOR(revdes_map_pos(orb_x, orb_y),
+                                    mapview_canvas_reverse);
+    if (tile_visible_mapcanvas(orb_x, orb_y)) {
+      put_line(map_canvas_store, orb_x, orb_y,
+              NORMALIZE_DIR(dir, !is_reversed));
+      put_line(XtWindow(map_canvas), orb_x, orb_y,
+              NORMALIZE_DIR(dir, !is_reversed));
+    }
+  } near_orbit_iterate_end;
 }
 
 /**************************************************************************
diff -ruN -Xdiff_ignore freeciv-cvs-Jan-08/client/mapctrl_common.c 
freeciv/client/mapctrl_common.c
--- freeciv-cvs-Jan-08/client/mapctrl_common.c  2004-01-08 07:15:53.000000000 
+0100
+++ freeciv/client/mapctrl_common.c     2004-01-09 20:49:32.000000000 +0100
@@ -141,6 +141,7 @@
 
       /*  Tile passed all tests; process it.
        */
+      normalize_map_pos(&tile_x, &tile_y);
       ptile = map_get_tile(tile_x, tile_y);
       pcity = ptile->city;
       if (pcity && pcity->owner == game.player_idx) {
@@ -602,7 +603,8 @@
       && draw_goto_line) {
     int x, y, old_x, old_y;
 
-    if (!canvas_to_map_pos(&x, &y, canvas_x, canvas_y)) {
+    canvas_to_map_pos(&x, &y, canvas_x, canvas_y);     
+    if (!normalize_map_pos(&x, &y)) {
       nearest_real_pos(&x, &y);
     }
 
diff -ruN -Xdiff_ignore freeciv-cvs-Jan-08/client/mapview_common.c 
freeciv/client/mapview_common.c
--- freeciv-cvs-Jan-08/client/mapview_common.c  2003-11-18 07:02:24.000000000 
+0100
+++ freeciv/client/mapview_common.c     2004-01-09 20:49:32.000000000 +0100
@@ -9,7 +9,7 @@
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
-***********************************************************************/
+******************************************************************2*****/
 
 #ifdef HAVE_CONFIG_H
 #include <config.h>
@@ -32,8 +32,9 @@
 #include "mapview_common.h"
 
 struct canvas mapview_canvas;
+bool mapview_canvas_reverse=FALSE;
 
-/* Overview oordinates of the upper left corner of the map overview. */
+/* Overview coordinates of the upper left corner of the map overview. */
 int map_overview_x0, map_overview_y0;
 
 static void base_canvas_to_map_pos(int *map_x, int *map_y,
@@ -43,70 +44,67 @@
 /**************************************************************************
  Refreshes a single tile on the map canvas.
 **************************************************************************/
-void refresh_tile_mapcanvas(int x, int y, bool write_to_screen)
-{
-  assert(is_real_map_pos(x, y));
-  if (!normalize_map_pos(&x, &y)) {
-    return;
-  }
-
-  if (tile_visible_mapcanvas(x, y)) {
-    update_map_canvas(x, y, 1, 1, FALSE);
 
-    if (update_city_text_in_refresh_tile
-       && (draw_city_names || draw_city_productions)) {
-      /* FIXME: update_map_canvas() will overwrite the city descriptions.
-       * This is a workaround that redraws the city descriptions (most of
-       * the time).  Although it seems inefficient to redraw the
-       * descriptions for so many tiles, remember that most of them don't
-       * have cities on them.
-       *
-       * This workaround is unnecessary for clients that use a separate
-       * buffer for the city descriptions, and will not work well for
-       * anti-aliased text (since it uses partial transparency).  Thus some
-       * clients may turn it off by setting
-       * update_city_text_in_refresh_tile. */
-      int canvas_x, canvas_y;
-      struct city *pcity;
-
-      if (is_isometric) {
-       /* We assume the city description will be directly below the city,
-        * with a width of 1-2 tiles and a height of less than one tile.
-        * Remember that units are 50% taller than the normal tile height.
-        *      9
-        *     7 8
-        *    6 4 5
-        *     2 3
-        *      1
-        * Tile 1 is the one being updated; we redraw the city description
-        * for tiles 2-8 (actually we end up drawing 1 as well). */
-       rectangle_iterate(x - 2, y - 2, 3, 3, city_x, city_y) {
-         if ((pcity = map_get_city(city_x, city_y))) {
-           map_to_canvas_pos(&canvas_x, &canvas_y, city_x, city_y);
-           show_city_desc(pcity, canvas_x, canvas_y);
-         }
-       } rectangle_iterate_end;
-      } else {
+void refresh_tile_mapcanvas(int map_x, int map_y, bool write_to_screen)
+{
+  near_orbit_iterate(map_x, map_y, orb_x, orb_y) {
+    if (tile_visible_mapcanvas(orb_x, orb_y)) {
+      update_map_canvas(orb_x, orb_y, 1, 1, FALSE);
+
+      if (update_city_text_in_refresh_tile
+         && (draw_city_names || draw_city_productions)) {
+       /* FIXME: update_map_canvas() will overwrite the city descriptions.
+        * This is a workaround that redraws the city descriptions (most of
+        * the time).  Although it seems inefficient to redraw the
+        * descriptions for so many tiles, remember that most of them don't
+        * have cities on them.
+        *
+        * This workaround is unnecessary for clients that use a separate
+        * buffer for the city descriptions, and will not work well for
+        * anti-aliased text (since it uses partial transparency).  Thus some
+        * clients may turn it off by setting
+        * update_city_text_in_refresh_tile. */
+       int canvas_x, canvas_y;
+       struct city *pcity;
+       if (is_isometric) {
+         /* We assume the city description will be directly below the city,
+          * with a width of 1-2 tiles and a height of less than one tile.
+          * Remember that units are 50% taller than the normal tile height.
+          *      9
+          *     7 8
+          *    6 4 5
+          *     2 3
+          *      1
+          * Tile 1 is the one being updated; we redraw the city description
+          * for tiles 2-8 (actually we end up drawing 1 as well). */
+         rectangle_iterate(orb_x - 2, orb_y - 2, 3, 3, city_x, city_y) {
+           if ((pcity = map_get_city(city_x, city_y))) {
+             map_to_canvas_pos(&canvas_x, &canvas_y, city_x, city_y);
+             show_city_desc(pcity, canvas_x, canvas_y);
+           }
+         } rectangle_iterate_end;
+       } else {
        /* We assume the city description will be held in the three tiles
         * right below the city.
         *       234
         *        1
         * Tile 1 is the one being updated; we redraw the city description
         * for tiles 2, 3, and 4. */
-       rectangle_iterate(x - 1, y - 1, 3, 1, city_x, city_y) {
+       rectangle_iterate(orb_x - 1, orb_y - 1, 3, 1, city_x, city_y) {
          if ((pcity = map_get_city(city_x, city_y))) {
            map_to_canvas_pos(&canvas_x, &canvas_y, city_x, city_y);
            show_city_desc(pcity, canvas_x, canvas_y);
          }
        } rectangle_iterate_end;
+       }
       }
     }
 
     if (write_to_screen) {
       flush_dirty();
-    }
-  }
-  overview_update_tile(x, y);
+    }       
+  } near_orbit_iterate_end;
+  overview_update_tile(map_x, map_y);
 }
 
 /**************************************************************************
@@ -173,22 +171,15 @@
   parts of the code assume NORMAL_TILE_WIDTH and NORMAL_TILE_HEIGHT
   to be even numbers.
 **************************************************************************/
-bool map_to_canvas_pos(int *canvas_x, int *canvas_y, int map_x, int map_y)
+bool map_to_canvas_pos(int *pcancas_x, int *pcancas_y, int map_x, int map_y)
 {
-  int center_map_x, center_map_y, dx, dy;
+  map_x -= mapview_canvas.map_x0;
+  map_y -= mapview_canvas.map_y0;
 
-  /*
-   * First we wrap the coordinates to hopefully be within the the mapview
-   * window.  We do this by finding the position closest to the center
-   * of the window.
-   */
-  /* TODO: Cache the value of this position */
-  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 (mapview_canvas_reverse) {
+    map_x = -map_x + mapview_canvas.tile_width - 1;
+    map_y = -map_y + mapview_canvas.tile_height - 1;
+  }
 
   if (is_isometric) {
     /* For a simpler example of this math, see city_to_canvas_pos(). */
@@ -205,11 +196,9 @@
      * 789                4 8
      *                     7
      */
-    iso_x = (map_x - map_y)
-      - (mapview_canvas.map_x0 - mapview_canvas.map_y0);
-    iso_y = (map_x + map_y)
-      - (mapview_canvas.map_x0 + mapview_canvas.map_y0);
-
+    iso_x = (map_x - map_y);
+    iso_y = (map_x + map_y);
+        
     /*
      * As the above picture shows, each isometric-coordinate unit
      * corresponds to a half-tile on the canvas.  Since the (x0, y0)
@@ -218,24 +207,27 @@
      * corner of the surrounding rectangle we must subtract off an
      * additional half-tile in the X direction.
      */
-    *canvas_x = (iso_x - 1) * NORMAL_TILE_WIDTH / 2;
-    *canvas_y = iso_y * NORMAL_TILE_HEIGHT / 2;
+   
+    *pcancas_x = (iso_x - 1) * NORMAL_TILE_WIDTH / 2;
+    *pcancas_y = iso_y * NORMAL_TILE_HEIGHT / 2;
+   
   } else {                     /* is_isometric */
-    *canvas_x = map_x - mapview_canvas.map_x0;
-    *canvas_y = map_y - mapview_canvas.map_y0;
 
-    *canvas_x *= NORMAL_TILE_WIDTH;
-    *canvas_y *= NORMAL_TILE_HEIGHT;
+      *pcancas_x = map_x;
+      *pcancas_y = map_y;
+
+      *pcancas_x *= NORMAL_TILE_WIDTH;
+      *pcancas_y *= NORMAL_TILE_HEIGHT;
   }
 
   /*
    * Finally we clip; checking to see if _any part_ of the tile is
    * visible on the canvas.
    */
-  return (*canvas_x > -NORMAL_TILE_WIDTH
-         && *canvas_x < mapview_canvas.width
-         && *canvas_y > -NORMAL_TILE_HEIGHT
-         && *canvas_y < mapview_canvas.height);
+  return (*pcancas_x > -NORMAL_TILE_WIDTH
+         && *pcancas_x < mapview_canvas.width
+         && *pcancas_y > -NORMAL_TILE_HEIGHT
+         && *pcancas_y < mapview_canvas.height);
 }
 
 /****************************************************************************
@@ -273,8 +265,10 @@
      *
      * For another example of this math, see canvas_to_city_pos().
      */
-    *map_x = DIVIDE(canvas_x * H + canvas_y * W, W * H);
-    *map_y = DIVIDE(canvas_y * W - canvas_x * H, W * H);
+     
+     *map_x = DIVIDE(canvas_x * H + canvas_y * W, W * H);
+     *map_y = DIVIDE(canvas_y * W - canvas_x * H, W * H);
+     
   } else {                     /* is_isometric */
     /* We use DIVIDE so that we will get the correct result even
      * for negative (off-canvas) coordinates. */
@@ -282,6 +276,10 @@
     *map_y = DIVIDE(canvas_y, H);
   }
 
+  if (mapview_canvas_reverse) {
+    *map_x = mapview_canvas.tile_width  - 1 - *map_x;
+    *map_y = mapview_canvas.tile_height - 1 - *map_y;
+  }
   *map_x += mapview_canvas.map_x0;
   *map_y += mapview_canvas.map_y0;
 }
@@ -292,11 +290,12 @@
   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)
 {
   base_canvas_to_map_pos(map_x, map_y, canvas_x, canvas_y);
-  return normalize_map_pos(map_x, map_y);
+  return is_real_map_pos(*map_x, *map_y);
 }
 
 /****************************************************************************
@@ -304,29 +303,37 @@
 ****************************************************************************/
 static void set_mapview_origin(int map_x0, int map_y0)
 {
-  int nat_x0, nat_y0, xmin, xmax, ymin, ymax, xsize, ysize;
-
+  int nat_x0, nat_y0, nat_center_x, nat_center_y, xmin, xmax, ymin, ymax,
+      xsize, ysize;
+  REVERSE_DESCRIPTOR_TYPE reverse;
+  
   /* First wrap/clip the position.  Wrapping is done in native positions
    * while clipping is done in scroll (native) positions. */
   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)) {
-    nat_x0 = FC_WRAP(nat_x0, map.xsize);
-  } else {
+  if (XWRAP_TYPE_IS(WT_NONE)) {
     nat_x0 = CLIP(xmin, nat_x0, xmax - xsize);
   }
-
-  if (topo_has_flag(TF_WRAPY)) {
-    nat_y0 = FC_WRAP(nat_y0, map.ysize);
-  } else {
+  if (YWRAP_TYPE_IS(WT_NONE)) {
     nat_y0 = CLIP(ymin, nat_y0, ymax - ysize);
   }
 
+  nat_center_x = nat_x0 + mapview_canvas.tile_width / 2;
+  nat_center_y = nat_y0 + mapview_canvas.tile_height / 2;
+  normalize_nat_pos_revdes(&nat_center_x, &nat_center_y, &reverse);
+  if ((REVERSE_CANVAS_IN_ISOVIEW && is_isometric) || !is_isometric) {
+    mapview_canvas_reverse =
+       COMBINE_DESCRIPTOR(reverse, mapview_canvas_reverse);
+    refresh_overview_canvas();
+  }
+  nat_x0=  nat_center_x - mapview_canvas.tile_width/2;
+  nat_y0=  nat_center_y - mapview_canvas.tile_height/2;
   native_to_map_pos(&map_x0, &map_y0, nat_x0, nat_y0);
 
   /* Then update everything. */
-  if (mapview_canvas.map_x0 != map_x0 || mapview_canvas.map_y0 != map_y0) {
+  if (mapview_canvas.map_x0 != map_x0 || mapview_canvas.map_y0 != map_y0
+      || reverse != REVERSE_NONE) {
     int map_center_x, map_center_y;
 
     mapview_canvas.map_x0 = map_x0;
@@ -464,13 +471,13 @@
   /* 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)) {
-    *xmin = -1;
-    *xmax = map.xsize + *xsize;
-  }
-  if (topo_has_flag(TF_WRAPY)) {
-    *ymin = -1;
-    *ymax = map.ysize + *ysize;
+  if (!XWRAP_TYPE_IS(WT_NONE)) {
+    *xmin = -mapview_canvas.tile_width / 2;
+    *xmax = map.xsize-1 + mapview_canvas.tile_width / 2;
+  }
+  if (!YWRAP_TYPE_IS(WT_NONE)) {
+    *ymin = -mapview_canvas.tile_height / 2;
+    *ymax = map.ysize-1 + mapview_canvas.tile_height / 2;
   }
 
   freelog(LOG_DEBUG, "x: %d<-%d->%d; y: %d<-%d->%d",
@@ -480,10 +487,17 @@
 /****************************************************************************
   Find the current scroll position (origin) of the mapview.
 ****************************************************************************/
-void get_mapview_scroll_pos(int *scroll_x, int *scroll_y)
+void get_mapview_scroll_pos(int *pscroll_x, int *pscroll_y)
 {
-  map_to_native_pos(scroll_x, scroll_y,
+  int xmin, ymin, xmax, ymax, xsize, ysize;
+
+  map_to_native_pos(pscroll_x, pscroll_y,
                    mapview_canvas.map_x0, mapview_canvas.map_y0);
+  if (mapview_canvas_reverse) {
+    get_mapview_scroll_window(&xmin, &ymin, &xmax, &ymax, &xsize, &ysize);
+    *pscroll_x = xmax -  *pscroll_x  + xmin - xsize;
+    *pscroll_y = ymax -  *pscroll_y  + ymin - ysize;
+  }
 }
 
 /****************************************************************************
@@ -492,6 +506,16 @@
 void set_mapview_scroll_pos(int scroll_x, int scroll_y)
 {
   int map_x0, map_y0;
+  int xmin, ymin, xmax, ymax, xsize, ysize;
+
+  get_mapview_scroll_window(&xmin, &ymin, &xmax, &ymax, &xsize, &ysize);
+ 
+  if (scroll_x > xmax - xsize) { scroll_x = xmax - xsize;}
+  if (scroll_y > ymax - ysize) { scroll_y = ymax - ysize;}
+  if (mapview_canvas_reverse) {
+    scroll_x = xmax -  scroll_x  + xmin - xsize;
+    scroll_y = ymax -  scroll_y  + ymin - ysize;
+  } 
 
   native_to_map_pos(&map_x0, &map_y0, scroll_x, scroll_y);
   set_mapview_origin(map_x0, map_y0);
@@ -515,13 +539,20 @@
 void center_tile_mapcanvas(int map_center_x, int map_center_y)
 {
   int map_x = map_center_x, map_y = map_center_y;
+  
+  if(mapview_canvas_reverse) {
+    map_center_x = map.xsize - 1 - map_center_x;
+    map_center_y = map.ysize - 1 - map_center_y;
+  }
 
   /* Find top-left corner. */
   if (is_isometric) {
-    map_x -= mapview_canvas.tile_width / 2;
-    map_y += mapview_canvas.tile_width / 2;
-    map_x -= mapview_canvas.tile_height / 2;
-    map_y -= mapview_canvas.tile_height / 2;
+    {
+      map_x -= mapview_canvas.tile_width / 2;
+      map_y += mapview_canvas.tile_width / 2;
+      map_x -= mapview_canvas.tile_height / 2;
+      map_y -= mapview_canvas.tile_height / 2;
+    }
   } else {
     map_x -= mapview_canvas.tile_width / 2;
     map_y -= mapview_canvas.tile_height / 2;
@@ -575,19 +606,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_NONE))) {
     return FALSE;
   }
   if (canvas_y < border_y
-      && (!same || scroll_y > ymin || topo_has_flag(TF_WRAPY))) {
+      && (!same || scroll_y > ymin || !YWRAP_TYPE_IS(WT_NONE))) {
     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_NONE))) {
     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_NONE))) {
     return FALSE;
   }
 
@@ -650,7 +681,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 +691,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 +701,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 +710,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 +720,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 +740,15 @@
   struct drawn_sprite tile_sprs[80];
   bool solid_bg;
   struct player *pplayer;
-  bool is_real = normalize_map_pos(&map_x, &map_y);
+  REVERSE_DESCRIPTOR_TYPE is_tile_reversed;
+  bool is_real =
+      normalize_map_pos_revdes(&map_x, &map_y, &is_tile_reversed);
+  int combined_reversed =
+      COMBINE_DESCRIPTOR(is_tile_reversed, mapview_canvas_reverse);
 
   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, combined_reversed);
     int i = 0;
 
     if (solid_bg) {
@@ -775,14 +810,16 @@
     }
 
     /* 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,
+                     combined_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, combined_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 +828,8 @@
       }
 
       /* top side */
-      if (MAPSTEP(x1, y1, map_x, map_y, DIR8_NORTH)) {
+      if (MAPSTEP(x1, y1, map_x, map_y,
+          NORMALIZE_DIR(DIR8_NORTH, combined_reversed))) {
        t2 = map_get_terrain(x1, y1);
        if (is_ocean(t1) ^ is_ocean(t2)) {
          gui_put_line(pcanvas_store, COLOR_STD_OCEAN, LINE_NORMAL,
@@ -854,7 +892,7 @@
 void tile_draw_borders_iso(struct canvas_store *pcanvas_store,
                           int map_x, int map_y,
                           int canvas_x, int canvas_y,
-                          enum draw_type draw)
+                          enum draw_type draw, bool is_reversed)
 {
   struct player *this_owner = map_get_owner(map_x, map_y), *adjc_owner;
   int x1, y1;
@@ -864,7 +902,9 @@
   }
 
   /* left side */
-  if ((draw & D_M_L) && MAPSTEP(x1, y1, map_x, map_y, DIR8_WEST)
+  if ((draw & D_M_L)
+      && 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)) {
     if (adjc_owner) {
@@ -884,7 +924,9 @@
   }
 
   /* top side */
-  if ((draw & D_M_R) && MAPSTEP(x1, y1, map_x, map_y, DIR8_NORTH)
+  if ((draw & D_M_R)
+      && 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)) {
     if (adjc_owner) {
@@ -955,15 +997,9 @@
       offset_y_unit = NORMAL_TILE_HEIGHT;
     }
 
-    if (normalize_map_pos(&map_x, &map_y)) {
-      gui_map_put_tile_iso(map_x, map_y, canvas_x, canvas_y,
-                          offset_x, offset_y, offset_y_unit,
-                          width, height, height_unit,
-                          draw);
-    } else {
-      gui_put_sprite(mapview_canvas.store, canvas_x, canvas_y,
-                    sprites.black_tile, offset_x, offset_y, width, height);
-    }
+    gui_map_put_tile_iso(map_x, map_y, canvas_x, canvas_y,
+                        offset_x, offset_y, offset_y_unit,
+                        width, height, height_unit, draw);
   }
 }
 
@@ -1232,6 +1268,11 @@
   static struct timer *anim_timer = NULL; 
   int dest_x, dest_y;
 
+  if (mapview_canvas_reverse) {
+    dx = -dx;
+    dy = -dy;
+  }
+
   /* only works for adjacent-square moves */
   if (dx < -1 || dx > 1 || dy < -1 || dy > 1 || (dx == 0 && dy == 0)) {
     return;
@@ -1529,7 +1570,7 @@
 /**************************************************************************
   Finds the overview (canvas) coordinates for a given map position.
 **************************************************************************/
-void map_to_overview_pos(int *overview_x, int *overview_y,
+void map_to_overview_pos(int *poverview_x, int *poverview_y,
                         int map_x, int map_y)
 {
   int gui_x, gui_y;
@@ -1541,27 +1582,38 @@
   map_to_native_pos(&gui_x, &gui_y, map_x, map_y);
   gui_x -= map_overview_x0;
   gui_y -= map_overview_y0;
+
+  if( mapview_canvas_reverse) {
+    gui_x = map.xsize - 1 - gui_x;
+    gui_y = map.ysize - 1 - gui_y;
+  }
+
   if (topo_has_flag(TF_WRAPX)) {
     gui_x = FC_WRAP(gui_x, map.xsize);
   }
   if (topo_has_flag(TF_WRAPY)) {
     gui_y = FC_WRAP(gui_y, map.ysize);
   }
-  *overview_x = OVERVIEW_TILE_WIDTH * gui_x;
-  *overview_y = OVERVIEW_TILE_HEIGHT * gui_y;
+
+  *poverview_x = OVERVIEW_TILE_WIDTH * gui_x;
+  *poverview_y = OVERVIEW_TILE_HEIGHT * gui_y;
 }
 
 /**************************************************************************
   Finds the map coordinates for a given overview (canvas) position.
 **************************************************************************/
-void overview_to_map_pos(int *map_x, int *map_y,
+void overview_to_map_pos(int *pmap_x, int *pmap_y,
                         int overview_x, int overview_y)
 {
   int nat_x = overview_x / OVERVIEW_TILE_WIDTH + map_overview_x0;
   int nat_y = overview_y / OVERVIEW_TILE_HEIGHT + map_overview_y0;
-
-  native_to_map_pos(map_x, map_y, nat_x, nat_y);
-  if (!normalize_map_pos(map_x, map_y)) {
+ 
+  if( mapview_canvas_reverse) {
+    nat_x = map.xsize - 1 - nat_x;
+    nat_y = map.ysize - 1 - nat_y;
+  }  
+  native_to_map_pos(pmap_x, pmap_y, nat_x, nat_y);
+  if (!normalize_map_pos(pmap_x, pmap_y)) {
     /* All positions on the overview should be valid. */
     assert(FALSE);
   }
@@ -1575,7 +1627,7 @@
 {
   map_to_overview_pos(&x[0], &y[0],
                      mapview_canvas.map_x0, mapview_canvas.map_y0);
-
+  
   /* Note: these calculations operate on overview coordinates as if they
    * are native. */
   if (is_isometric && !topo_has_flag(TF_ISO)) {
@@ -1611,6 +1663,11 @@
     int screen_width = mapview_canvas.tile_width;
     int screen_height = mapview_canvas.tile_height * (is_isometric ? 2 : 1);
 
+    if (mapview_canvas_reverse) {
+       *x -= OVERVIEW_TILE_WIDTH * screen_width;
+       *y -= OVERVIEW_TILE_HEIGHT * screen_height;
+    }
+
     /* Northeast */
     x[1] = x[0] + OVERVIEW_TILE_WIDTH * screen_width - 1;
     y[1] = y[0];
@@ -1622,6 +1679,7 @@
     /* Southwest */
     x[3] = x[0];
     y[3] = y[2];
+
   }
 
   freelog(LOG_DEBUG, "(%d,%d)->(%d,%x)->(%d,%d)->(%d,%d)",
@@ -1633,14 +1691,18 @@
   position.  This may be used by the GUI code to draw to the minimap's
   backing store.
 **************************************************************************/
-void map_to_base_overview_pos(int *base_overview_x, int *base_overview_y,
+void map_to_base_overview_pos(int *pbase_overview_x, int *pbase_overview_y,
                              int map_x, int map_y)
 {
   /* Base overview positions are just like native positions, but scaled to
    * the overview tile dimensions. */
-  map_to_native_pos(base_overview_x, base_overview_y, map_x, map_y);
-  *base_overview_x *= OVERVIEW_TILE_WIDTH;
-  *base_overview_y *= OVERVIEW_TILE_HEIGHT;
+  map_to_native_pos(pbase_overview_x, pbase_overview_y, map_x, map_y);
+  if( mapview_canvas_reverse) {
+    *pbase_overview_x = map.xsize - 1 - *pbase_overview_x;
+    *pbase_overview_y = map.ysize - 1 - *pbase_overview_y;
+  }  
+  *pbase_overview_x *= OVERVIEW_TILE_WIDTH;
+  *pbase_overview_y *= OVERVIEW_TILE_HEIGHT;
 }
 
 /**************************************************************************
diff -ruN -Xdiff_ignore freeciv-cvs-Jan-08/client/mapview_common.h 
freeciv/client/mapview_common.h
--- freeciv-cvs-Jan-08/client/mapview_common.h  2003-10-01 06:59:02.000000000 
+0200
+++ freeciv/client/mapview_common.h     2004-01-09 20:49:32.000000000 +0100
@@ -158,7 +158,7 @@
 void tile_draw_borders_iso(struct canvas_store *pcanvas_store,
                           int map_x, int map_y,
                           int canvas_x, int canvas_y,
-                          enum draw_type draw);
+                          enum draw_type draw,bool is_reversed);
 
 void update_map_canvas(int x, int y, int width, int height,
                       bool write_to_screen);
@@ -198,4 +198,10 @@
 
 extern int map_overview_x0, map_overview_y0;
 
+/* for auto reverse canvas in reversed wrapping topologies */
+extern bool mapview_canvas_reverse;
+/* activate reverse canvas in iso view, reverse canvas is actived all the
+   time in no iso view (this is a devel option only ) */
+#define REVERSE_CANVAS_IN_ISOVIEW FALSE
+
 #endif /* FC__MAPVIEW_COMMON_H */
diff -ruN -Xdiff_ignore freeciv-cvs-Jan-08/client/packhand.c 
freeciv/client/packhand.c
--- freeciv-cvs-Jan-08/client/packhand.c        2004-01-07 07:15:44.000000000 
+0100
+++ freeciv/client/packhand.c   2004-01-09 20:49:32.000000000 +0100
@@ -1239,9 +1239,12 @@
 **************************************************************************/
 void handle_map_info(int xsize, int ysize, bool is_earth, int topology_id)
 {
+  /* order warning */
+  map_init_topology(topology_id);
+  map.size = 0;
   map.xsize = xsize;
   map.ysize = ysize;
-  map.topology_id = topology_id;
+  /* End order warning */
   map.is_earth = is_earth;
 
   map_allocate();
diff -ruN -Xdiff_ignore freeciv-cvs-Jan-08/client/tilespec.c 
freeciv/client/tilespec.c
--- freeciv-cvs-Jan-08/client/tilespec.c        2003-11-30 07:05:57.000000000 
+0100
+++ freeciv/client/tilespec.c   2004-01-09 20:49:32.000000000 +0100
@@ -42,6 +42,8 @@
 #include "support.h"
 #include "unit.h"
 
+#include "mapview_common.h"     /* for  mapview_canvas_reverse   */
+
 #include "civclient.h"         /* for get_client_state() */
 #include "climap.h"            /* for tile_get_known() */
 #include "control.h"           /* for fill_xxx */
@@ -961,6 +963,7 @@
   SET_SPRITE_ALT(tx.fortress_back, "tx.fortress_back", "tx.fortress");
   SET_SPRITE(tx.airbase,    "tx.airbase");
   SET_SPRITE(tx.fog,        "tx.fog");
+  SET_SPRITE(tx.lfog,       "tx.lfog");
 
   for(i=0; i<NUM_DIRECTION_NSEW; i++) {
     my_snprintf(buffer, sizeof(buffer), "tx.s_river_%s", nsew_str(i));
@@ -1369,11 +1372,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;
 
@@ -1390,8 +1396,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);
@@ -1859,7 +1864,7 @@
                               struct Sprite **coasts,
                               struct Sprite **dither,
                               int x, int y, bool citymode,
-                              bool *solid_bg)
+                              bool *solid_bg,bool is_reversed)
 {
   enum tile_terrain_type ttype, ttype_near[8];
   enum tile_special_type tspecial, tspecial_near[8];
@@ -1874,7 +1879,8 @@
 
   pcity = map_get_city(x, y);
 
-  build_tile_data(x, y, &ttype, &tspecial, ttype_near, tspecial_near);
+  build_tile_data_reversed(x, y, &ttype, &tspecial, ttype_near,
+                          tspecial_near, is_reversed);
 
   if (draw_terrain) {
     if (is_ocean(ttype)) {
@@ -2031,10 +2037,13 @@
     for (dir = 0; dir < 4; dir++) {
       int x1, y1, other;
 
-      if (MAPSTEP(x1, y1, x, y, DIR4_TO_DIR8[dir]))
-        other = (tile_get_known(x1, y1) != TILE_UNKNOWN) ? 
ttype_near[DIR4_TO_DIR8[dir]]:T_UNKNOWN;
+      if (MAPSTEP
+         (x1, y1, x, y, NORMALIZE_DIR(DIR4_TO_DIR8[dir], is_reversed)))
+       other =
+           (tile_get_known(x1, y1) !=
+            TILE_UNKNOWN) ? ttype_near[DIR4_TO_DIR8[dir]] : T_UNKNOWN;
       else
-        other = ttype_near[dir];
+       other = ttype_near[dir];
       dither[dir] = get_dither(ttype, other);
     }
   }
@@ -2058,10 +2067,11 @@
 10) pollution
 11) fallout
 12) FoW
+13) ligth fog (reversed to canvas)
 ***********************************************************************/
 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];
@@ -2106,8 +2116,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) {
@@ -2205,6 +2215,10 @@
     ADD_SPRITE_SIMPLE(sprites.tx.fog);
   }
 
+  if( mapview_canvas_reverse != is_reversed) {
+    ADD_SPRITE_SIMPLE(sprites.tx.lfog);
+  }
+
   if (!citymode) {
     /* 
      * We're looking to find the INDEX_NSEW for the directions that
@@ -2218,10 +2232,11 @@
     for (dir = 0; dir < 4; dir++) {
       int x1, y1;
 
-      if (MAPSTEP(x1, y1, abs_x0, abs_y0, DIR4_TO_DIR8[dir]))
-        known[dir] = (tile_get_known(x1, y1) != TILE_UNKNOWN);
+      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;
+       known[dir] = TRUE;
     }
 
     tileno =
@@ -2412,10 +2427,13 @@
 enum color_std overview_tile_color(int x, int y)
 {
   enum color_std color;
-  struct tile *ptile=map_get_tile(x, y);
+  struct tile *ptile;
   struct unit *punit;
   struct city *pcity;
 
+  normalize_map_pos(&x, &y);
+  ptile = map_get_tile(x, y);
+
   if (tile_get_known(x, y) == TILE_UNKNOWN) {
     color=COLOR_STD_BLACK;
   } else if((pcity=map_get_city(x, y))) {
diff -ruN -Xdiff_ignore freeciv-cvs-Jan-08/client/tilespec.h 
freeciv/client/tilespec.h
--- freeciv-cvs-Jan-08/client/tilespec.h        2003-10-16 06:59:07.000000000 
+0200
+++ freeciv/client/tilespec.h   2004-01-09 20:49:32.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);
+                              bool *solid_bg,bool is_reversed);
+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,
@@ -198,6 +197,7 @@
       *airbase,
       *fallout,
       *fog,
+      *lfog,
       *spec_river[NUM_DIRECTION_NSEW],
       *darkness[NUM_DIRECTION_NSEW],         /* first unused */
       *river_outlet[4],                /* indexed by enum direction4 */
diff -ruN -Xdiff_ignore freeciv-cvs-Jan-08/common/aicore/cm.c 
freeciv/common/aicore/cm.c
--- freeciv-cvs-Jan-08/common/aicore/cm.c       2003-11-23 07:07:50.000000000 
+0100
+++ freeciv/common/aicore/cm.c  2004-01-09 20:49:32.000000000 +0100
@@ -217,15 +217,6 @@
   } tiles[CITY_MAP_SIZE][CITY_MAP_SIZE];
 };
 
-#define my_city_map_iterate(pcity, cx, cy) {                           \
-  city_map_checked_iterate(pcity->x, pcity->y, cx, cy, map_x, map_y) { \
-    if(!is_city_center(cx, cy)) {
-
-#define my_city_map_iterate_end \
-    }                                \
-  } city_map_checked_iterate_end;    \
-}
-
 /****************************************************************************
  * implementation of utility functions (these are relatively independent
  * of the algorithms used)
diff -ruN -Xdiff_ignore freeciv-cvs-Jan-08/common/aicore/path_finding.c 
freeciv/common/aicore/path_finding.c
--- freeciv-cvs-Jan-08/common/aicore/path_finding.c     2003-11-23 
07:07:50.000000000 +0100
+++ freeciv/common/aicore/path_finding.c        2004-01-09 20:49:32.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_full(pf_map->x, pf_map->y, x1, y1, dir, dir1, rev_des) {
       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,13 +324,13 @@
          *status = NS_NEW;
          node1->extra_cost = extra;
          node1->cost = cost;
-         node1->dir_to_here = dir;
+         node1->dir_to_here = dir1;
          pq_insert(pf_map->queue, index1, -cost_of_path);
        }
       }
 
     }
-    adjc_dir_iterate_end;
+    adjc_dir_iterate_full_end;
   }
 
   /* Get the next nearest node */
@@ -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_full(pf_map->x, pf_map->y, x1, y1, dir, dir1, rev_des) {
       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 = dir1;
           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 = dir1;
           d_node1->step = loc_step + 1;
           if (d_node->is_dangerous) {
             /* Increment the number of steps we are making across danger */
diff -ruN -Xdiff_ignore freeciv-cvs-Jan-08/common/city.c freeciv/common/city.c
--- freeciv-cvs-Jan-08/common/city.c    2003-12-07 07:08:41.000000000 +0100
+++ freeciv/common/city.c       2004-01-10 10:50:05.000000000 +0100
@@ -128,16 +128,32 @@
 
 /**************************************************************************
 Finds the map position for a given city map coordinate of a certain
-city. Returns true if the map position found is real.
+city.
 **************************************************************************/
-bool base_city_map_to_map(int *map_x, int *map_y,
+void base_city_map_to_map(int *map_x, int *map_y,
                         int city_center_x, int city_center_y,
                         int city_map_x, int city_map_y)
 {
   assert(is_valid_city_coords(city_map_x, city_map_y));
   *map_x = city_center_x + city_map_x - CITY_MAP_SIZE / 2;
   *map_y = city_center_y + city_map_y - CITY_MAP_SIZE / 2;
-  return normalize_map_pos(map_x, map_y);
+}
+
+/**************************************************************************
+Finds the normal map position for a given city map coordinate of a 
+certain city. Returns true if the map position found is real.
+**************************************************************************/
+bool normal_city_map_to_map(int *map_x, int *map_y,
+                        int city_center_x, int city_center_y,
+                        int city_map_x, int city_map_y)
+{
+  assert(is_valid_city_coords(city_map_x, city_map_y));
+  *map_x = city_center_x + city_map_x - CITY_MAP_SIZE / 2;
+  *map_y = city_center_y + city_map_y - CITY_MAP_SIZE / 2;
+  if(IS_BORDER_MAP_POS(city_center_x, city_center_y, 3)) {
+    return normalize_map_pos(map_x, map_y);
+  }
+  return TRUE;
 }
 
 /**************************************************************************
@@ -145,11 +161,15 @@
 city. Returns true if the map position found is real.
 **************************************************************************/
 bool city_map_to_map(int *map_x, int *map_y,
-                   const struct city *const pcity,
-                   int city_map_x, int city_map_y)
+                    const struct city *const pcity,
+                    int city_map_x, int city_map_y)
 {
-  return base_city_map_to_map(map_x, map_y,
-                             pcity->x, pcity->y, city_map_x, city_map_y);
+  base_city_map_to_map(map_x, map_y,
+                      pcity->x, pcity->y, city_map_x, city_map_y);
+  if (IS_BORDER_MAP_POS(pcity->x, pcity->y, 3)) {
+    return is_real_map_pos(*map_x, *map_y);
+  }
+  return TRUE;
 }
 
 /**************************************************************************
@@ -160,7 +180,8 @@
 {
   int map_x, map_y;
 
-  if (city_map_to_map(&map_x, &map_y, pcity, city_x, city_y)) {
+  if (normal_city_map_to_map(&map_x, &map_y, pcity->x, pcity->y,
+                            city_x, city_y)) {
     struct tile *ptile = map_get_tile(map_x, map_y);
 
     if (pcity->city_map[city_x][city_y] == C_TILE_WORKER
@@ -563,7 +584,8 @@
   int before_penalty = (is_celebrating ? g->celeb_shields_before_penalty
                        : g->shields_before_penalty);
   
-  is_real = city_map_to_map(&map_x, &map_y, pcity, x, y);
+  is_real = normal_city_map_to_map(&map_x, &map_y,
+                                  pcity->x, pcity->y, x, y);
   assert(is_real);
 
   spec_t = map_get_special(map_x, map_y);
@@ -656,7 +678,8 @@
   bool is_real;
   int map_x, map_y, t;
 
-  is_real = city_map_to_map(&map_x, &map_y, pcity, x, y);
+  is_real = normal_city_map_to_map(&map_x, &map_y,
+                                  pcity->x, pcity->y, x, y);
   assert(is_real);
 
   spec_t = map_get_special(map_x, map_y);
@@ -766,7 +789,8 @@
                        : g->food_before_penalty);
   bool city_auto_water;
 
-  is_real = city_map_to_map(&map_x, &map_y, pcity, x, y);
+  is_real = normal_city_map_to_map(&map_x, &map_y,
+                                  pcity->x, pcity->y,  x, y);
   assert(is_real);
 
   spec_t = map_get_special(map_x, map_y);
diff -ruN -Xdiff_ignore freeciv-cvs-Jan-08/common/city.h freeciv/common/city.h
--- freeciv-cvs-Jan-08/common/city.h    2003-12-07 07:08:41.000000000 +0100
+++ freeciv/common/city.h       2004-01-09 20:49:32.000000000 +0100
@@ -116,6 +116,16 @@
   }                                                                            
\
 }
 
+#define my_city_map_iterate(pcity, cx, cy) {                           \
+  city_map_checked_iterate(pcity->x, pcity->y, cx, cy, map_x, map_y) { \
+    if(!is_city_center(cx, cy)) {
+
+#define my_city_map_iterate_end \
+    }                                \
+  } city_map_checked_iterate_end;    \
+}
+
+
 /*
  * Iterate a city map in checked real map coordinates. The center of
  * the city is given as a map position (x0,y0). cx and cy will be
@@ -125,7 +135,7 @@
 #define city_map_checked_iterate(x0, y0, cx, cy, mx, my) {     \
   city_map_iterate_outwards(cx, cy) {                          \
     int mx, my;                                                \
-    if (base_city_map_to_map(&mx, &my, x0, y0, cx, cy)) {
+    if (normal_city_map_to_map(&mx, &my, x0, y0, cx, cy)) {
 
 #define city_map_checked_iterate_end \
     }                                \
@@ -380,7 +390,10 @@
 bool map_to_city_map(int *city_map_x, int *city_map_y,
                    const struct city *const pcity, int map_x, int map_y);
 
-bool base_city_map_to_map(int *map_x, int *map_y, int city_center_x,
+void base_city_map_to_map(int *map_x, int *map_y, int city_center_x,
+                        int city_center_y, int city_map_x,
+                        int city_map_y);
+bool normal_city_map_to_map(int *map_x, int *map_y, int city_center_x,
                         int city_center_y, int city_map_x,
                         int city_map_y);
 bool city_map_to_map(int *map_x, int *map_y, const struct city *const pcity,
diff -ruN -Xdiff_ignore freeciv-cvs-Jan-08/common/map.c freeciv/common/map.c
--- freeciv-cvs-Jan-08/common/map.c     2003-12-09 07:08:06.000000000 +0100
+++ freeciv/common/map.c        2004-01-11 18:38:40.000000000 +0100
@@ -69,6 +69,51 @@
 
 #define MAP_TILE(x,y)  (map.tiles + map_pos_to_index(x, y))
 
+
+bool normalize_map_pos_INIT(int *x, int *y);
+bool normalize_map_pos_CLASSIC(int *x, int *y);
+bool normalize_map_pos_TORUS(int *x, int *y);
+bool normalize_map_pos_FLAT(int *x, int *y);
+bool normalize_map_pos_MOBIUS(int *x, int *y);
+bool normalize_map_pos_QUINCUNCIAL_SQ(int *x, int *y);
+bool normalize_map_pos_QUINCUNCIAL(int *x, int *y);
+bool normalize_map_pos_SPIN(int *x, int *y);
+
+bool normalize_map_pos_revdes_INIT(int *x, int *y,bool *prd);
+bool normalize_map_pos_revdes_CLASSIC(int *x, int *y,bool *prd);
+bool normalize_map_pos_revdes_TORUS(int *x, int *y,bool *prd);
+bool normalize_map_pos_revdes_FLAT(int *x, int *y,bool *prd);
+bool normalize_map_pos_revdes_MOBIUS(int *x, int *y,bool *prd);
+bool normalize_map_pos_revdes_QUINCUNCIAL_SQ(int *x, int *y,bool *prd);
+bool normalize_map_pos_revdes_QUINCUNCIAL(int *x, int *ybool,bool *prd);
+bool normalize_map_pos_revdes_SPIN(int *x, int *y,bool *prd);
+
+bool normalize_nat_pos_revdes_INIT(int *x, int *y,bool *prd);
+bool normalize_nat_pos_revdes_CLASSIC(int *x, int *y,bool *prd);
+bool normalize_nat_pos_revdes_TORUS(int *x, int *y,bool *prd);
+bool normalize_nat_pos_revdes_FLAT(int *x, int *y,bool *prd);
+bool normalize_nat_pos_revdes_MOBIUS(int *x, int *y,bool *prd);
+bool normalize_nat_pos_revdes_QUINCUNCIAL_SQ(int *x, int *y,bool *prd);
+bool normalize_nat_pos_revdes_QUINCUNCIAL(int *x, int *y,bool *prd);
+bool normalize_nat_pos_revdes_SPIN(int *x, int *y,bool *prd);
+
+void map_distance_vector_INIT(int *dx, int *dy,
+                             int x0, int y0, int x1, int y1);
+void map_distance_vector_FLAT(int *dx, int *dy,
+                           int x0, int y0, int x1, int y1);
+void map_distance_vector_CLASSIC(int *dx, int *dy,
+                           int x0, int y0, int x1, int y1);
+void map_distance_vector_TORUS(int *dx, int *dy,
+                           int x0, int y0, int x1, int y1);
+void map_distance_vector_MOBIUS(int *dx, int *dy,
+                           int x0, int y0, int x1, int y1);
+void map_distance_vector_QUINCUNCIAL_SQ(int *dx, int *dy,
+                           int x0, int y0, int x1, int y1);
+void map_distance_vector_QUINCUNCIAL(int *dx, int *dy,
+                           int x0, int y0, int x1, int y1);
+void map_distance_vector_SPIN(int *dx, int *dy,
+                           int x0, int y0, int x1, int y1);
+
 /***************************************************************
 ...
 ***************************************************************/
@@ -171,14 +216,121 @@
   return !map.tiles;
 }
 
+/********************************************************************
+ refreshmapratio(),setmapratio(int ratio)
+ and ,setmapratio2(int Xratio, int Yratio)
+ choice of legal xsize and ysize with the selected ratio,
+ odd xsize and ysize are not allowed
+ all ratio must be exact 
+ the size of map is unchanged if map.size=0
+ or base in map.size new xsize*ysize = 2000*map.size
+ where size get numbers from 1 to 10 
+             1  for a map of  2,000 tiles
+             10 for a map of 20,000 tiles
+this limit is based assuming ratio is less than 2:1 
+           and MAP_MAX_WIDTHandHEIGHT=200
+                                                              [mburda]
+*********************************************************************/ 
+static void setmapratio2(int Xratio, int Yratio)
+{
+  bool odd_ratio = ((Xratio % 2) != 0) || ((Yratio % 2) != 0);
+  int size_max = MAP_MAX_WIDTHandHEIGHT / MAX(Xratio, Yratio);
+  int size_min = MAP_MIN_WIDTHandHEIGHT / MIN(Xratio, Yratio);
+  int size = floor(0.49 + sqrt(2000.0 * map.size / (Xratio * Yratio)));
+  if (map.size > 0) {
+    if (odd_ratio && ((size % 2) != 0)) {
+      size_max = 0.5 * MAP_MAX_WIDTHandHEIGHT / MAX(Xratio, Yratio);
+      size_min = 0.5 * MAP_MIN_WIDTHandHEIGHT / MIN(Xratio, Yratio);
+      size = floor(0.49 + sqrt(500.0 * map.size / (Xratio * Yratio)));
+      assert(size_min <= size_max);
+      if (size < size_min)
+       size = size_min;
+      if (size > size_max)
+        size = size_max;
+      map.xsize = 2 * Xratio * size;
+      map.ysize = 2 * Yratio * size;
+    } else {
+      assert(size_min <= size_max);
+      if (size < size_min)
+        size = size_min;
+      if (size > size_max)
+        size = size_max;
+      map.xsize = Xratio * size;
+      map.ysize = Yratio * size;
+    }
+  }
+}
+
+
+static void setmapratio(int ratio)
+{
+  assert(ratio >= 11 && ratio <= 100);
+  if (ratio != 100)
+    setmapratio2(ratio / 10, ratio % 10);
+}
+
+static void refreshmapratio()
+{
+  assert(map.ratio >= 11 && map.ratio <= 100);
+  if (map.ratio != 100)
+      setmapratio2(map.ratio / 10, map.ratio % 10);
+}
+
+
+/*************************************************************************** 
+   WARNING: set topology_id this way or at last call it:
+       map_init_topology(map.topology_id) 
+
+   Alow set xsize and ysize freely if size = 0 
+                                                                [mburda]
+*************************************************************************/
+#define INIT_TOPOLOGIE_CASE(TOPO,DEFAULTRATIO,XWRAPT,YWRAPT,POLES)          \
+ case TOPO:                                                                 \
+       if( map.ratio == 100){                                               \
+         setmapratio(DEFAULTRATIO);                                         \
+         map.ratio=100;                                                     \
+       }                                                                    \
+       refreshmapratio();                                                   \
+       map.xwrap_type=XWRAPT; map.ywrap_type = YWRAPT;                      \
+       if (POLES >= 0){                                                     \
+        map.separatepoles = POLES;                                          \
+       }                                                                    \
+       break;
+
+void map_init_topology(int topology_id)
+{
+  map.topology_id = topology_id;
+  switch (topology_id & TF_MASK) {
+    INIT_TOPOLOGIE_CASE(TF_FLAT, DEFAULTRATIO_FLAT, WT_NONE, WT_NONE, 0);
+    INIT_TOPOLOGIE_CASE(TF_CLASSIC, DEFAULTRATIO_CLASSIC, WT_SIMPLEST,
+                       WT_NONE, -1);
+    INIT_TOPOLOGIE_CASE(TF_TORUS, DEFAULTRATIO_TORUS, WT_SIMPLEST,
+                       WT_SIMPLEST, 0);
+    INIT_TOPOLOGIE_CASE(TF_MOBIUS, DEFAULTRATIO_MOBIUS, WT_SIMPLEST,
+                       WT_OFFSET, 0);
+    INIT_TOPOLOGIE_CASE(TF_QUINCUNCIAL_SQ, DEFAULTRATIO_QUINCUNCIAL_SQ,
+                       WT_REVERSED, WT_REVERSED, 0);
+    INIT_TOPOLOGIE_CASE(TF_QUINCUNCIAL, DEFAULTRATIO_QUINCUNCIAL,
+                       WT_SIMPLEST, WT_REVERSED, 0);
+    INIT_TOPOLOGIE_CASE(TF_SPIN, DEFAULTRATIO_SPIN, WT_REVERSED, WT_NONE,
+                       0);
+  };
+  normalize_map_pos = normalize_map_pos_INIT;
+  normalize_map_pos_revdes = normalize_map_pos_revdes_INIT;
+  normalize_nat_pos_revdes = normalize_nat_pos_revdes_INIT;
+  map_distance_vector = map_distance_vector_INIT;
+ 
+}
+
 /***************************************************************
  put some sensible values into the map structure
 ***************************************************************/
 void map_init(void)
 {
-  map.topology_id = MAP_DEFAULT_TOPO;
   map.xsize                 = MAP_DEFAULT_WIDTH;
   map.ysize                 = MAP_DEFAULT_HEIGHT;
+  map.size                  = MAP_DEFAULT_SIZE;
+  map.ratio                 = MAP_DEFAULT_RATIO;
   map.seed                  = MAP_DEFAULT_SEED;
   map.riches                = MAP_DEFAULT_RICHES;
   map.is_earth              = FALSE;
@@ -200,6 +352,7 @@
   map.have_specials         = FALSE;
   map.have_rivers_overlay   = FALSE;
   map.have_huts             = FALSE;
+  map_init_topology(MAP_DEFAULT_TOPO); /*at last place [mburda]*/
 }
 
 /***************************************************************
@@ -1040,7 +1193,7 @@
     return SINGLE_MOVE;
   if (tile_has_special(t1, S_RAILROAD) && tile_has_special(t2, S_RAILROAD))
     return MOVE_COST_RAIL;
-/* return (unit_move_rate(punit)/RAIL_MAX) */
+  /* return (unit_move_rate(punit)/RAIL_MAX) */
   if (punit && unit_flag(punit, F_IGTER))
     return SINGLE_MOVE/3;
   if (tile_has_special(t1, S_ROAD) && tile_has_special(t2, S_ROAD))
@@ -1145,14 +1298,14 @@
   /* trying to move off the screen is the default */
   memset(tile0->move_cost, maxcost, sizeof(tile0->move_cost));
 
-  adjc_dir_iterate(x, y, x1, y1, dir) {
+  adjc_dir_iterate_full(x, y, x1, y1, dir, dir1, revdes) {
     tile1 = map_get_tile(x1, y1);
     tile0->move_cost[dir] = tile_move_cost_ai(tile0, tile1, x, y,
                                              x1, y1, maxcost);
     /* reverse: not at all obfuscated now --dwp */
-    tile1->move_cost[DIR_REVERSE(dir)] =
+    tile1->move_cost[DIR_REVERSE(dir1)] =
        tile_move_cost_ai(tile1, tile0, x1, y1, x, y, maxcost);
-  } adjc_dir_iterate_end;
+  } adjc_dir_iterate_full_end;
   debug_log_move_costs("Reset move costs for", x, y, tile0);
 }
 
@@ -1202,9 +1355,9 @@
 /***************************************************************
 ...
 ***************************************************************/
-struct tile *map_get_tile(int x, int y)
+struct tile *map_get_tile(int map_x, int map_y)
 {
-  return MAP_TILE(x, y);
+    return MAP_TILE(map_x, map_y);
 }
 
 /***************************************************************
@@ -1347,6 +1500,24 @@
   return normalize_map_pos(&x, &y);
 }
 
+/* ************************************************************
+ * retourn TRUE if a singularity is in a city radius 
+ * ************************************************************/
+bool near_singularity(int map_x, int map_y)
+{
+  int count = 0;
+  square_dxy_iterate(map_x, map_y, 2, x_itr, y_itr, dx_itr, dy_itr) {
+    if (abs(dx_itr) + abs(dy_itr) == 4) {
+      continue;
+    }
+    count++;
+  } square_dxy_iterate_end;
+  if ( count < 21 ) {
+    return TRUE;
+  }
+  return FALSE;
+}
+
 /**************************************************************************
 Returns TRUE iff the map position is normal. "Normal" here means that
 it is both a real/valid coordinate set and that the coordinates are in
@@ -1368,7 +1539,114 @@
   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.
 **************************************************************************/
-bool normalize_map_pos(int *x, int *y)
+bool normalize_map_pos_INIT(int *x, int *y)
+{
+  switch (map.topology_id & TF_MASK) {
+  case TF_FLAT:
+    normalize_map_pos = normalize_map_pos_FLAT;
+    break;
+  case TF_CLASSIC:
+    normalize_map_pos = normalize_map_pos_CLASSIC;
+    break;
+  case TF_TORUS:
+    normalize_map_pos = normalize_map_pos_TORUS;
+    break;
+  case TF_MOBIUS:
+    normalize_map_pos = normalize_map_pos_MOBIUS;
+    break;
+  case TF_QUINCUNCIAL_SQ:
+    normalize_map_pos = normalize_map_pos_QUINCUNCIAL_SQ;
+    break;
+  case TF_SPIN:
+    normalize_map_pos = normalize_map_pos_SPIN;
+    break;
+  case TF_QUINCUNCIAL:
+    normalize_map_pos = normalize_map_pos_QUINCUNCIAL;
+    break;
+  default:
+    assert(FALSE);
+  }
+  return normalize_map_pos(x, y);
+}
+
+bool normalize_map_pos_revdes_INIT(int *x, int *y,bool *prd)
+{
+  switch (map.topology_id & TF_MASK) {
+  case TF_FLAT:
+    normalize_map_pos_revdes = normalize_map_pos_revdes_FLAT;
+    break;
+  case TF_CLASSIC:
+    normalize_map_pos_revdes = normalize_map_pos_revdes_CLASSIC;
+    break;
+  case TF_TORUS:
+    normalize_map_pos_revdes = normalize_map_pos_revdes_TORUS;
+    break;
+  case TF_MOBIUS:
+    normalize_map_pos_revdes = normalize_map_pos_revdes_MOBIUS;
+    break;
+  case TF_QUINCUNCIAL_SQ:
+    normalize_map_pos_revdes = normalize_map_pos_revdes_QUINCUNCIAL_SQ;
+    break;
+  case TF_SPIN:
+    normalize_map_pos_revdes = normalize_map_pos_revdes_SPIN;
+    break;
+  case TF_QUINCUNCIAL:
+    normalize_map_pos_revdes = normalize_map_pos_revdes_QUINCUNCIAL;
+    break;
+  default:
+    assert(FALSE);
+  }
+  return normalize_map_pos_revdes(x, y, prd);
+}
+
+bool normalize_nat_pos_revdes_INIT(int *x, int *y,bool *prd)
+{
+  switch (map.topology_id & TF_MASK) {
+  case TF_FLAT:
+    normalize_nat_pos_revdes = normalize_nat_pos_revdes_FLAT;
+    break;
+  case TF_CLASSIC:
+    normalize_nat_pos_revdes = normalize_nat_pos_revdes_CLASSIC;
+    break;
+  case TF_TORUS:
+    normalize_nat_pos_revdes = normalize_nat_pos_revdes_TORUS;
+    break;
+  case TF_MOBIUS:
+    normalize_nat_pos_revdes = normalize_nat_pos_revdes_MOBIUS;
+    break;
+  case TF_QUINCUNCIAL_SQ:
+    normalize_nat_pos_revdes = normalize_nat_pos_revdes_QUINCUNCIAL_SQ;
+    break;
+  case TF_SPIN:
+    normalize_nat_pos_revdes = normalize_nat_pos_revdes_SPIN;
+    break;
+  case TF_QUINCUNCIAL:
+    normalize_nat_pos_revdes = normalize_nat_pos_revdes_QUINCUNCIAL;
+    break;
+  default:
+    assert(FALSE);
+  }
+  return normalize_nat_pos_revdes(x, y, prd);
+}
+
+bool normalize_map_pos_FLAT(int *x, int *y)
+{
+  int nat_x, nat_y;
+
+  /* Normalization is best done in native coordinatees. */
+  map_to_native_pos(&nat_x, &nat_y, *x, *y);
+
+  /* If the position is out of range in a non-wrapping direction, it is
+   * unreal. */
+  if (!((nat_x >= 0 && nat_x < map.xsize)
+       &&  (nat_y >= 0 && nat_y < map.ysize))) {
+    return FALSE;
+  }
+
+  return TRUE;
+}
+
+bool normalize_map_pos_revdes_FLAT(int *x, int *y, bool *rd)
 {
   int nat_x, nat_y;
 
@@ -1377,24 +1655,414 @@
 
   /* 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 (!((nat_x >= 0 && nat_x < map.xsize)
+       &&  (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);
+  *rd = FALSE;
+  return TRUE;
+}
+
+bool normalize_nat_pos_revdes_FLAT(int *pnat_x, int *pnat_y, bool *rd)
+{
+  /* If the position is out of range in a non-wrapping direction, it is
+   * unreal. */
+  if (!((*pnat_x >= 0 && *pnat_x < map.xsize)
+       &&  (*pnat_y >= 0 && *pnat_y < map.ysize))) {
+    return FALSE;
   }
-  if (topo_has_flag(TF_WRAPY)) {
-    nat_y = FC_WRAP(nat_y, map.ysize);
+
+  *rd = FALSE;
+  return TRUE;
+}
+
+bool normalize_map_pos_CLASSIC(int *x, int *y)
+{
+  int nat_x, nat_y;
+
+  /* Normalization is best done in native coordinatees. */
+  map_to_native_pos(&nat_x, &nat_y, *x, *y);
+
+  /* If the position is out of range in a non-wrapping direction, it is
+   * unreal. */
+  if (! (nat_y >= 0 && nat_y < map.ysize)) {
+    return FALSE;
+  }
+
+  /* Wrap in X  direction */
+   nat_x = FC_WRAP(nat_x, map.xsize);
+
+  /* Now transform things back to map coordinates. */
+  native_to_map_pos(x, y, nat_x, nat_y);
+  return TRUE;
+}
+
+bool normalize_map_pos_revdes_CLASSIC(int *x, int *y,bool *prd)
+{
+  int nat_x, nat_y;
+
+  /* Normalization is best done in native coordinatees. */
+  map_to_native_pos(&nat_x, &nat_y, *x, *y);
+
+  /* If the position is out of range in a non-wrapping direction, it is
+   * unreal. */
+  if (! (nat_y >= 0 && nat_y < map.ysize)) {
+    return FALSE;
+  }
+
+  /* Wrap in X  direction */
+   nat_x = FC_WRAP(nat_x, map.xsize);
+
+  /* Now transform things back to map coordinates. */
+  native_to_map_pos(x, y, nat_x, nat_y);
+
+  *prd = FALSE;
+  return TRUE;
+}
+
+bool normalize_nat_pos_revdes_CLASSIC(int *pnat_x, int *pnat_y,bool *prd)
+{
+  /* If the position is out of range in a non-wrapping direction, it is
+   * unreal. */
+  if (! (*pnat_y >= 0 && *pnat_y < map.ysize)) {
+    return FALSE;
   }
 
+  /* Wrap in X  direction */
+  *pnat_x = FC_WRAP(*pnat_x, map.xsize);
+
+  *prd = FALSE;
+  return TRUE;
+}
+
+bool normalize_map_pos_TORUS(int *x, int *y)
+{
+  int nat_x, nat_y;
+
+  /* Normalization is best done in native coordinatees. */
+  map_to_native_pos(&nat_x, &nat_y, *x, *y);
+
+  /* Wrap in X and Y directions */
+  
+  nat_x = FC_WRAP(nat_x, map.xsize);
+  nat_y = FC_WRAP(nat_y, map.ysize);
+ 
   /* Now transform things back to map coordinates. */
   native_to_map_pos(x, y, nat_x, nat_y);
   return TRUE;
 }
 
+bool normalize_map_pos_revdes_TORUS(int *x, int *y, bool *prd)
+{
+  int nat_x, nat_y;
+
+  /* Normalization is best done in native coordinatees. */
+  map_to_native_pos(&nat_x, &nat_y, *x, *y);
+
+  /* Wrap in X and Y directions */
+  
+  nat_x = FC_WRAP(nat_x, map.xsize);
+  nat_y = FC_WRAP(nat_y, map.ysize);
+ 
+  /* Now transform things back to map coordinates. */
+  native_to_map_pos(x, y, nat_x, nat_y);
+
+  *prd = FALSE;
+  return TRUE;
+}
+
+bool normalize_nat_pos_revdes_TORUS(int *pnat_x, int *pnat_y, bool *prd)
+{
+  /* Wrap in X and Y directions */
+  *pnat_x = FC_WRAP(*pnat_x, map.xsize);
+  *pnat_y = FC_WRAP(*pnat_y, map.ysize);
+
+  *prd = FALSE;
+  return TRUE;
+}
+
+
+bool normalize_map_pos_MOBIUS(int *px, int *py)
+{
+  int nat_x, nat_y;
+
+  /* Normalization is best done in native coordinatees. */
+  map_to_native_pos(&nat_x, &nat_y, *px, *py);
+
+  /* Wrap in Y directions, as needed. */
+  while (nat_y < 0) {
+    nat_y += map.ysize;
+    nat_x += map.xsize / 2;
+  }
+  while (nat_y >= map.ysize) {
+    nat_y -= map.ysize;
+    nat_x -= map.xsize / 2;
+  }
+  /* Wrap in X directions */
+  nat_x = MODULO(nat_x, map.xsize);
+
+  native_to_map_pos(px, py, nat_x, nat_y);
+
+  return TRUE;
+}
+
+bool normalize_map_pos_revdes_MOBIUS(int *px, int *py, bool *prd)
+{
+  int nat_x, nat_y;
+
+  /* Normalization is best done in native coordinatees. */
+  map_to_native_pos(&nat_x, &nat_y, *px, *py);
+
+  /* Wrap in Y directions, as needed. */
+  while (nat_y < 0) {
+    nat_y += map.ysize;
+    nat_x += map.xsize / 2;
+  }
+  while (nat_y >= map.ysize) {
+    nat_y -= map.ysize;
+    nat_x -= map.xsize / 2;
+  }
+  /* Wrap in X directions */
+  nat_x = MODULO(nat_x, map.xsize);
+
+  native_to_map_pos(px, py, nat_x, nat_y);
+
+  *prd = FALSE;
+  return TRUE;
+}
+
+bool normalize_nat_pos_revdes_MOBIUS(int *pnat_x, int *pnat_y, bool *prd)
+{
+  /* Wrap in Y directions, as needed. */
+  while (*pnat_y < 0) {
+    *pnat_y += map.ysize;
+    *pnat_x += map.xsize / 2;
+  }
+  while (*pnat_y >= map.ysize) {
+    *pnat_y -= map.ysize;
+    *pnat_x -= map.xsize / 2;
+  }
+  /* Wrap in X directions */
+  *pnat_x = MODULO(*pnat_x, map.xsize);
+
+  *prd = FALSE;
+  return TRUE;
+}
+
+bool normalize_map_pos_QUINCUNCIAL_SQ(int *px, int *py)
+{
+  int nat_x, nat_y;
+
+  /* Normalization is best done in native coordinatees. */
+  map_to_native_pos(&nat_x, &nat_y, *px, *py);
+
+ /* Wrap in X and Y directions and rotate, as needed. */
+  nat_x = MODULO(nat_x, 2 * map.xsize);
+  nat_y = MODULO(nat_y, 2 * map.ysize);
+
+  if ((nat_x < map.xsize) != (nat_y < map.ysize)) {
+    nat_x = (2 * map.xsize - nat_x - 1) % map.xsize;
+    nat_y = (2 * map.ysize - nat_y - 1) % map.ysize;
+  } else {
+    nat_x = nat_x % map.xsize;
+    nat_y = nat_y % map.ysize;
+  }
+
+  native_to_map_pos(px, py, nat_x, nat_y);
+  return TRUE;
+}
+
+bool normalize_map_pos_revdes_QUINCUNCIAL_SQ(int *px, int *py, bool *prd)
+{
+  int nat_x, nat_y;
+
+  /* Normalization is best done in native coordinatees. */
+  map_to_native_pos(&nat_x, &nat_y, *px, *py);
+
+ /* Wrap in X and Y directions and rotate, as needed. */
+  nat_x = MODULO(nat_x, 2 * map.xsize);
+  nat_y = MODULO(nat_y, 2 * map.ysize);
+
+  if ((nat_x < map.xsize) != (nat_y < map.ysize)) {
+    nat_x = (2 * map.xsize - nat_x - 1) % map.xsize;
+    nat_y = (2 * map.ysize - nat_y - 1) % map.ysize;
+    *prd = TRUE;
+  } else {
+    nat_x = nat_x % map.xsize;
+    nat_y = nat_y % map.ysize;
+    *prd = FALSE;
+  }
+
+  native_to_map_pos(px, py, nat_x, nat_y);
+  return TRUE;
+}
+
+bool normalize_nat_pos_revdes_QUINCUNCIAL_SQ(int *pnat_x, int *pnat_y, bool 
*prd)
+{
+ /* Wrap in X and Y directions and rotate, as needed. */
+  *pnat_x = MODULO(*pnat_x, 2 * map.xsize);
+  *pnat_y = MODULO(*pnat_y, 2 * map.ysize);
+
+  if ((*pnat_x < map.xsize) != (*pnat_y < map.ysize)) {
+    *pnat_x = (2 * map.xsize - *pnat_x - 1) % map.xsize;
+    *pnat_y = (2 * map.ysize - *pnat_y - 1) % map.ysize;
+    *prd = TRUE;
+  } else {
+    *pnat_x = *pnat_x % map.xsize;
+    *pnat_y = *pnat_y % map.ysize;
+    *prd = FALSE;
+  }
+
+  return TRUE;
+}
+
+bool normalize_map_pos_SPIN(int *px, int *py)
+{
+  int nat_x, nat_y;
+
+  /* this code is for a X reverse wrapping spin topology */ 
+  assert(XWRAP_TYPE_IS(WT_REVERSED) && YWRAP_TYPE_IS(WT_NONE));
+
+  /* Normalization is best done in native coordinatees. */
+  map_to_native_pos(&nat_x, &nat_y, *px, *py);
+
+  /* If the position is out of range it is unreal. */
+  if (nat_y < 0 || nat_y >= map.ysize) {
+    return FALSE;
+  }
+
+  /* Wrap in X directions and rotate, as needed. */
+  nat_x = MODULO(nat_x, 2 * map.xsize);
+  if(nat_x >= map.xsize) {
+    nat_x = 2 * map.xsize - nat_x - 1;
+    nat_y =     map.ysize - nat_y - 1;
+  } 
+
+  native_to_map_pos(px, py, nat_x, nat_y);
+  return TRUE;
+}
+
+bool normalize_map_pos_revdes_SPIN(int *px, int *py, bool *prd)
+{
+  int nat_x, nat_y;
+
+  /* this code is for a X reverse wrapping spin topology */ 
+  assert(XWRAP_TYPE_IS(WT_REVERSED) && YWRAP_TYPE_IS(WT_NONE));
+
+  /* Normalization is best done in native coordinatees. */
+  map_to_native_pos(&nat_x, &nat_y, *px, *py);
+
+  /* If the position is out of range it is unreal. */
+  if (nat_y < 0 || nat_y >= map.ysize) {
+    return FALSE;
+  }
+
+  /* Wrap in X directions and rotate, as needed. */
+  nat_x = MODULO(nat_x, 2 * map.xsize);
+  if(nat_x >= map.xsize) {
+      nat_x = 2 * map.xsize - nat_x - 1;
+      nat_y =     map.ysize - nat_y - 1;
+   
+    *prd = TRUE;
+  } else {
+    *prd = FALSE;
+  }
+
+  native_to_map_pos(px, py, nat_x, nat_y);
+  return TRUE;
+}
+
+bool normalize_nat_pos_revdes_SPIN(int *pnat_x, int *pnat_y, bool *prd)
+{
+  /* this code is for a X reverse wrapping spin topology */ 
+  assert(XWRAP_TYPE_IS(WT_REVERSED) && YWRAP_TYPE_IS(WT_NONE));
+
+  /* If the position is out of range it is unreal. */
+  if (*pnat_y < 0 || *pnat_y >= map.ysize) {
+    return FALSE;
+  }
+
+  /* Wrap in X directions and rotate, as needed. */
+  *pnat_x = MODULO(*pnat_x, 2 * map.xsize);
+  if(*pnat_x >= map.xsize) {
+    *pnat_x = 2 * map.xsize - *pnat_x - 1;
+    *pnat_y =     map.ysize - *pnat_y - 1;
+    *prd = TRUE;
+  } else {
+    *prd = FALSE;
+  }
+
+  return TRUE;
+}
+
+bool normalize_map_pos_QUINCUNCIAL(int *px, int *py)
+{
+  int nat_x, nat_y;
+
+  /* this code is for a Y reverse wraping Quincuncial topology */
+  assert(XWRAP_TYPE_IS(WT_SIMPLEST) && YWRAP_TYPE_IS(WT_REVERSED));
+
+  /* Normalization is best done in native coordinatees. */
+  map_to_native_pos(&nat_x, &nat_y, *px, *py);
+
+  /* Wrap in X and Y directions and rotate, as needed. */
+  nat_x = MODULO(nat_x,     map.xsize);
+  nat_y = MODULO(nat_y, 2 * map.ysize);
+  if ( nat_y >= map.ysize) {
+    nat_x =     map.xsize - nat_x - 1;
+    nat_y = 2 * map.ysize - nat_y - 1;
+  }
+
+  native_to_map_pos(px, py, nat_x, nat_y);
+  return TRUE;
+}
+
+bool normalize_map_pos_revdes_QUINCUNCIAL(int *px, int *py,bool *prd)
+{
+  int nat_x, nat_y;
+
+  /* this code is for a Y reverse wraping Quincuncial topology */
+  assert(XWRAP_TYPE_IS(WT_SIMPLEST) && YWRAP_TYPE_IS(WT_REVERSED));
+
+  /* Normalization is best done in native coordinatees. */
+  map_to_native_pos(&nat_x, &nat_y, *px, *py);
+
+  /* Wrap in X and Y directions and rotate, as needed. */
+  nat_x = MODULO(nat_x,     map.xsize);
+  nat_y = MODULO(nat_y, 2 * map.ysize);
+  if ( nat_y >= map.ysize) {
+    nat_x =     map.xsize - nat_x - 1;
+    nat_y = 2 * map.ysize - nat_y - 1;
+    *prd = TRUE;
+  } else {
+    *prd = FALSE;
+  }
+
+  native_to_map_pos(px, py, nat_x, nat_y);
+  return TRUE;
+}
+
+bool normalize_nat_pos_revdes_QUINCUNCIAL(int *pnat_x, int *pnat_y,bool *prd)
+{
+  /* this code is for a Y reverse wraping Quincuncial topology */
+  assert(XWRAP_TYPE_IS(WT_SIMPLEST) && YWRAP_TYPE_IS(WT_REVERSED));
+
+  /* Wrap in X and Y directions and rotate, as needed. */
+  *pnat_x = MODULO(*pnat_x,     map.xsize);
+  *pnat_y = MODULO(*pnat_y, 2 * map.ysize);
+  if ( *pnat_y >= map.ysize) {
+    *pnat_x =     map.xsize - *pnat_x - 1;
+    *pnat_y = 2 * map.ysize - *pnat_y - 1;
+    *prd = TRUE;
+  } else {
+    *prd = FALSE;
+  }
+
+  return TRUE;
+}
+
+
 /**************************************************************************
 Twiddle *x and *y to point the the nearest real tile, and ensure that the
 position is normalized.
@@ -1404,10 +2072,10 @@
   int nat_x, nat_y;
 
   map_to_native_pos(&nat_x, &nat_y, *x, *y);
-  if (!topo_has_flag(TF_WRAPX)) {
+  if (XWRAP_TYPE_IS(WT_NONE)) {
     nat_x = CLIP(0, nat_x, map.xsize - 1);
   }
-  if (!topo_has_flag(TF_WRAPY)) {
+  if (YWRAP_TYPE_IS(WT_NONE)) {
     nat_y = CLIP(0, nat_y, map.ysize - 1);
   }
   native_to_map_pos(x, y, nat_x, nat_y);
@@ -1425,6 +2093,33 @@
   return map.xsize * map.ysize;
 }
 
+/**************************************************************************
+ *return the reverse desciptor of a map pos
+ * allow the 9 topology xwrap_type-ywrap_type with the WT_REVERSED,WT_SIMPLEST,
+ * WT_NONE 
+ * and the 10th topology XRAP=WT_SIMPLEST ,  YWRAP=WT_OFFSET    
+ *                                                                 [mburda]
+ **************************************************************************/
+REVERSE_DESCRIPTOR_TYPE revdes_map_pos(int x, int y)
+{
+  int nat_x, nat_y;
+
+  /* Normalization is best done in native coordinatees. */
+  map_to_native_pos(&nat_x, &nat_y, x, y);
+  return revdes_nat_pos(nat_x, nat_y);
+}
+
+REVERSE_DESCRIPTOR_TYPE revdes_nat_pos(int nat_x, int nat_y)
+{
+  int xfactor, yfactor;
+
+  xfactor = XWRAP_TYPE_IS(WT_REVERSED) ? 2 : 1;
+  yfactor = YWRAP_TYPE_IS(WT_REVERSED) ? 2 : 1;
+  return ((MODULO(nat_x, xfactor * map.xsize) < map.xsize)
+         != (MODULO(nat_y, yfactor * map.ysize) < map.ysize)
+      );
+}
+
 /****************************************************************************
   Topology function to find the vector which has the minimum "real"
   distance between the map positions (x0, y0) and (x1, y1).  If there is
@@ -1438,41 +2133,400 @@
   (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
-    -map.ysize   <  dy <  map.ysize
+    -map.xsize  < dx < map.xsize
+    -map.ysize  < dy < map.ysize
+
+  after all change of topologie initialize :
+  map_distance_vector = map_distance_vector_INIT;
 ****************************************************************************/
-void map_distance_vector(int *dx, int *dy, int x0, int y0, int x1, int y1)
+void map_distance_vector_INIT(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. */
-    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;
-    }
-    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;
-    }
-
-    /* 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);
+  switch (map.topology_id & TF_MASK) {
+  case TF_FLAT:
+    map_distance_vector = map_distance_vector_FLAT;
+    break;
+  case TF_CLASSIC:
+    map_distance_vector = map_distance_vector_CLASSIC;
+    break;
+  case TF_TORUS:
+    map_distance_vector = map_distance_vector_TORUS;
+    break;
+  case TF_MOBIUS:
+    map_distance_vector = map_distance_vector_MOBIUS;
+    break;
+  case TF_QUINCUNCIAL_SQ:
+    map_distance_vector = map_distance_vector_QUINCUNCIAL_SQ;
+    break;
+  case TF_QUINCUNCIAL:
+    map_distance_vector = map_distance_vector_QUINCUNCIAL;
+    break;
+  case TF_SPIN:
+    map_distance_vector = map_distance_vector_SPIN;
+    break;
+  default:
+    assert(FALSE);
   }
 
+  map_distance_vector(dx, dy, x0, y0, x1, y1);
+}
+
+
+void map_distance_vector_FLAT(int *dx, int *dy, int x0, int y0, int x1, int y1)
+{
+  *dx = x1 - x0;
+  *dy = y1 - y0;
+}
+
+void map_distance_vector_CLASSIC(int *dx, int *dy,
+                                int x0, int y0, int x1, int y1)
+{
+
+  /* Wrapping 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;
+
+  /* Wrap dx to be in [-map.xsize/2, map.xsize/2). */
+  *dx = FC_WRAP(*dx + map.xsize / 2, map.xsize) - map.xsize / 2;
+
+
+  /* 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;
   *dy = y1 - y0;
 }
 
+void map_distance_vector_TORUS(int *dx, int *dy,
+                                int x0, int y0, int x1, int y1)
+{
+
+  /* Wrapping 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;
+
+  /* Wrap dx to be in [-map.xsize/2, map.xsize/2). */
+  *dx = FC_WRAP(*dx + map.xsize / 2, map.xsize) - map.xsize / 2;
+  /* Wrap dy to be in [-map.ysize/2, map.ysize/2). */
+  *dy = FC_WRAP(*dy + map.ysize / 2, map.ysize) - map.ysize / 2;
+
+  /* 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;
+  *dy = y1 - y0;
+}
+
+void map_distance_vector_MOBIUS(int *dx, int *dy, int x0, int y0, int x1,
+                               int y1)
+{
+  int _dx, _dy;
+
+  assert(YWRAP_TYPE_IS(WT_OFFSET) && XWRAP_TYPE_IS(WT_SIMPLEST));
+  /* Work is done in native coordinates. */
+  map_to_native_pos(&x0, &y0, x0, y0);
+  map_to_native_pos(&x1, &y1, x1, y1);
+  _dx = x1 - x0;
+  _dy = y1 - y0;
+
+  /* offset wrap */
+  while (_dy > map.ysize / 2) {
+    _dy -= map.ysize;
+    _dx -= map.xsize / 2;
+  }
+  while (_dy <= -map.ysize / 2) {
+    _dy += map.ysize;
+    _dx += map.xsize / 2;
+  }
+  /* simplest wraps */
+  while (_dx > map.xsize / 2)
+    _dx -= map.xsize;
+  while (_dx <= -map.xsize / 2)
+    _dx += map.xsize;
+
+  /* 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;
+  *dy = y1 - y0;
+}
+
+void map_distance_vector_QUINCUNCIAL_SQ(int *dx, int *dy, int x0, int y0,
+                                       int x1, int y1)
+{
+  int Dist, _Dist, _dx, _dy;
+  /* Work is done in native coordinates. */
+  map_to_native_pos(&x0, &y0, x0, y0);
+  map_to_native_pos(&x1, &y1, x1, y1);
+  *dx = x1 - x0;
+  *dy = y1 - y0;
+
+  Dist = MAX(abs(*dx), abs(*dy));
+  /* reversed toologies : */
+
+  /* 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;
+  }
+
+  /* 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;
+  *dy = y1 - y0;
+}
+
+void map_distance_vector_QUINCUNCIAL(int *dx, int *dy, int x0, int y0,
+                                    int x1, int y1)
+{
+  int Dist, _Dist, Dx, Dy;
+
+  assert (XWRAP_TYPE_IS(WT_SIMPLEST) && YWRAP_TYPE_IS(WT_REVERSED));
+  /* Work is done in native coordinates. */
+  map_to_native_pos(&x0, &y0, x0, y0);
+  map_to_native_pos(&x1, &y1, x1, y1);
+  *dx = x1 - x0;
+  *dy = y1 - y0;
+
+  /* simplest wraps */
+  if (XWRAP_TYPE_IS(WT_SIMPLEST)) {
+    while (*dx > map.xsize / 2)
+      *dx -= map.xsize;
+    while (*dx <= -map.xsize / 2)
+      *dx += map.xsize;
+  }
+
+  Dist = MAX(abs(*dx), abs(*dy));
+  /* reversed toologies : */
+  // 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;
+  }
+
+  /* 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;
+  *dy = y1 - y0;
+}
+
+
+void map_distance_vector_SPIN(int *dx, int *dy, int x0, int y0,
+                             int x1, int y1)
+{
+  int Dist, _Dist, Dx, Dy;
+
+  assert(XWRAP_TYPE_IS(WT_REVERSED) && YWRAP_TYPE_IS(WT_NONE));
+  /* Work is done in native coordinates. */
+  map_to_native_pos(&x0, &y0, x0, y0);
+  map_to_native_pos(&x1, &y1, x1, y1);
+  *dx = x1 - x0;
+  *dy = y1 - y0;
+
+  Dist = MAX(abs(*dx), abs(*dy));
+  /* reversed toologies : */
+
+  // 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;
+  *dy = y1 - y0;
+}
+
+
+/*************************************************************************
+Return begin in px, py, all the cordiantes of one tile, 
+normalized and near non normalized ones
+the return value are the number of this (0 to 9)
+the first one is the normalized if exist
+                                                                 [mburda]
+*************************************************************************/
+int map_near_orbit(int x, int y, int *px, int *py)
+{
+  int n = 1, i;
+
+  if (!normalize_map_pos(&x, &y)) {
+    return 0;
+  }
+
+  map_to_native_pos(px, py, x, y);
+
+  if (XWRAP_TYPE_IS(WT_REVERSED)) {
+    // central symetry 
+    *(px + n) = -1 - x;
+    *(py + n) = map.ysize - y - 1;
+    n++;
+    *(px + n) = 2 * map.xsize - 1 - x;
+    *(py + n) = map.ysize - y - 1;
+    n++;
+  } else if (XWRAP_TYPE_IS(WT_SIMPLEST)) {
+    int i, ni = n;
+    for (i = 0; i < ni; i++) {
+      *(py + n) = *(py + i);
+      *(px + n) = *(px + i) + map.xsize;
+      n++;
+      *(py + n) = *(py + i);
+      *(px + n) = *(px + i) - map.xsize;
+      n++;
+    }
+  }
+
+  if (YWRAP_TYPE_IS(WT_REVERSED)) {
+    int i, ni = n;
+    for (i = 0; i < ni; i++) {
+      *(py + n) = -1 - *(py + i);
+      *(px + n) = map.xsize - *(px + i) - 1;
+      n++;
+      *(py + n) = 2 * map.ysize - 1 - *(py + i);
+      *(px + n) = map.xsize - *(px + i) - 1;
+      n++;
+    }
+  } else if (YWRAP_TYPE_IS(WT_SIMPLEST)) {
+    int i, ni = n;
+    for (i = 0; i < ni; i++) {
+      *(py + n) = *(py + i) + map.ysize;
+      *(px + n) = *(px + i);
+      n++;
+      *(py + n) = *(py + i) - map.ysize;
+      *(px + n) = *(px + i);
+      n++;
+    }
+  } else if (YWRAP_TYPE_IS(WT_OFFSET)) {
+    int i, ni = n;
+    for (i = 0; i < ni; i++) {
+      *(py + n) = *(py + i) + map.ysize;
+      *(px + n) = *(px + i) + map.xsize / 2;
+      n++;
+      *(py + n) = *(py + i) - map.ysize;
+      *(px + n) = *(px + i) - map.xsize / 2;
+      n++;
+    }
+  }
+  for (i = 0; i < n; i++) {
+    native_to_map_pos(px, py, *px, *py);
+  }
+  return n;
+}
+
 /**************************************************************************
 Random neighbouring square.
 **************************************************************************/
@@ -1667,10 +2721,11 @@
 {
   int diff_x, diff_y;
 
-  assert(is_tiles_adjacent(start_x, start_y, end_x, end_y));
+  assert(is_tiles_adjacent(start_x, start_y, end_x, end_y) ||
+        (start_x == end_x && start_y == end_y));
 
   map_distance_vector(&diff_x, &diff_y, start_x, start_y, end_x, end_y);
-  return (diff_x == 0) || (diff_y == 0);
+  return (diff_x == 0) != (diff_y == 0);
 }
 
 /**************************************************************************
diff -ruN -Xdiff_ignore freeciv-cvs-Jan-08/common/map.h freeciv/common/map.h
--- freeciv-cvs-Jan-08/common/map.h     2003-11-29 07:05:26.000000000 +0100
+++ freeciv/common/map.h        2004-01-10 15:19:24.000000000 +0100
@@ -136,8 +136,12 @@
 };
 
 struct civ_map { 
-  int topology_id;
-  int xsize, ysize; /* native dimensions */
+  int topology_id;             /*index of topologies and some flags */
+  int xwrap_type;
+  int ywrap_type;
+  int size;    /* size of map in log units for 0 to 14, -1 for manual sizes */
+  int ratio;     /* xsize-ysize ratio form 11 to 99  or 100 for auto ratio */
+  int xsize, ysize;    /* native dimensions, determined form size and ratio */
   int seed;
   int riches;
   bool is_earth;
@@ -165,18 +169,82 @@
 };
 
 enum topo_flag {
-  /* Bit-values. */
-  TF_WRAPX = 1,
-  TF_WRAPY = 2,
-  TF_ISO = 4
+  /* Bit-values(deprecated). and topos index  
+   * For Users
+   * cartographics topologies 
+   */
+  TF_FLAT = 0,    /* xwrap_type = 0 , ywrap_type = 0 */
+  TF_CLASSIC,   /* xwrap_type = 1 , ywrap_type = 0 */  
+  TF_QUINCUNCIAL_SQ,   /* xwrap_type = 2 , ywrap_type = 2 */
+  /* scfi topologies */
+  TF_TORUS,     /* xwrap_type = 1 , ywrap_type = 1 */ 
+  TF_MOBIUS,    /* xwrap_type = 1 , ywrap_type = 3 */
+  TF_SPIN,      /* xwrap_type = 2 , ywrap_type = 0 */
+  /*
+   * variants vor developpers
+   */
+  TF_QUINCUNCIAL,      /* xwrap_type = 1 , ywrap_type = 2 */
+
+  /* index_mask */
+  TF_MASK = 15,
+  /* Bit-value, non deprecated flag */
+  TF_ISO = 16,
+  /* Bit-values(deprecated) */
+  TF_WRAPX = 32,  
+  TF_WRAPY = 64,  
 };
 
+enum topo_wrap_type {
+    WT_NONE,
+    WT_SIMPLEST,
+    WT_REVERSED,
+    WT_OFFSET         /* this wrap only combine with SIMPLEST */
+ };
+
+/*
+ *
+ * TF_WRAPX and TF_WRAPY are deprecated. i precerve its fontionality for 
+ * the simplest topologies until clean up
+ * 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 = WT_OFFSET :   wrap and size/2 offset
+ *                                                                (mburda)
+*/
+
 #define CURRENT_TOPOLOGY (map.topology_id)
 
-#define topo_has_flag(flag) ((CURRENT_TOPOLOGY & (flag)) != 0)
+/* when deprecated bit diapear we can simplify this                   */
+
+#define topo_has_flag(flag) ((((flag) & (TF_WRAPX | TF_WRAPY)) == 0)       \
+                 ? ((CURRENT_TOPOLOGY & (flag)) != 0)                      \
+                 : ((flag) == TF_WRAPX                                     \
+                 ? XWRAP_TYPE_IS(WT_SIMPLEST)                              \
+                   : YWRAP_TYPE_IS(WT_SIMPLEST)))
+
+
+#define XWRAP_TYPE_IS(WTYPE) (map.xwrap_type==(WTYPE))
+
+#define YWRAP_TYPE_IS(WTYPE) (map.ywrap_type==(WTYPE))
+
+/* Actuealy a bool is ok for determine revertion type, full reverse or not */
+
+#define REVERSE_DESCRIPTOR_TYPE bool
+#define REVERSE_NONE FALSE
+
+#define COMBINE_DESCRIPTOR(REVERSE1,REVERSE2) ((REVERSE1)!=(REVERSE2))
+
+#define NORMALIZE_DIR(DIR, REVERSE) \
+      ((REVERSE)?DIR_REVERSE(DIR):(DIR))
+
+bool near_singularity(int map_x, int map_y);
+ 
 
 bool map_is_empty(void);
 void map_init(void);
+void map_init_topology(int);
 void map_allocate(void);
 void map_free(void);
 
@@ -258,11 +326,26 @@
  *    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_REVDES(dest_x, dest_y, src_x, src_y, dir, rev_des) \
+(    (dest_x) = (src_x) + DIR_DX[(dir)],                          \
+     (dest_y) = (src_y) + DIR_DY[(dir)],                          \
+     normalize_map_pos_revdes(&(dest_x), &(dest_y),&(rev_des)))
+
+#define MAPSTEP_FULL(dest_x, dest_y, src_x, src_y, dir, ndir, rev_des)       \
+(    (dest_x) = (src_x) + DIR_DX[(dir)],                                    \
+     (dest_y) = (src_y) + DIR_DY[(dir)],                                    \
+     normalize_map_pos_revdes(&(dest_x), &(dest_y), &(rev_des)))             \
+     (ndir) = NORMALIZE_DIR(dir, rev_des)
+
+
 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);
@@ -298,9 +381,18 @@
    || (x) < (dist) || (x) >= map.xsize - (dist)               \
    || (y) < (dist) || (y) >= map.ysize - (dist))
 
-bool normalize_map_pos(int *x, int *y);
+int map_near_orbit(int x, int y, int *px, int *py);
+REVERSE_DESCRIPTOR_TYPE revdes_map_pos(int x, int y);
+REVERSE_DESCRIPTOR_TYPE revdes_nat_pos(int x, int y);
+bool (*normalize_nat_pos_revdes)(int *pnat_x, int *pnat_y, bool *prd); 
+
+bool (*normalize_map_pos_revdes)(int *x, int *y,
+                             REVERSE_DESCRIPTOR_TYPE *prd);
+
+bool (*normalize_map_pos)(int *x, int *y);
 void nearest_real_pos(int *x, int *y);
-void map_distance_vector(int *dx, int *dy, int x0, int y0, int x1, int y1);
+void (*map_distance_vector)(int *dx, int *dy,
+                           int x0, int y0, int x1, int y1);
 int map_num_tiles(void);
 
 void rand_neighbour(int x0, int y0, int *x, int *y);
@@ -379,54 +471,65 @@
    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).
 */
-#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;                                                   \
-  int MACRO_max_dx = map.xsize/2;                                             \
-  int MACRO_min_dx = -MACRO_max_dx - 1 + (map.xsize % 2);                     \
-  bool MACRO_xcycle = TRUE;                                                   \
-  bool MACRO_positive = FALSE;                                                \
-  bool MACRO_is_border = IS_BORDER_MAP_POS(ARG_start_x, ARG_start_y,          \
-                                           ARG_max_dist);                     \
-  int MACRO_dxy = 0, MACRO_do_xy;                                             \
-  CHECK_MAP_POS(ARG_start_x, ARG_start_y);                                    \
-  while(MACRO_dxy <= (ARG_max_dist)) {                                        \
-    for (MACRO_do_xy = -MACRO_dxy; MACRO_do_xy <= MACRO_dxy; MACRO_do_xy++) { \
-      if (MACRO_xcycle) {                                                     \
-       ARG_x_itr = (ARG_start_x) + MACRO_do_xy;                              \
-       if (MACRO_positive)                                                   \
-         ARG_y_itr = (ARG_start_y) + MACRO_dxy;                              \
-       else                                                                  \
-         ARG_y_itr = (ARG_start_y) - MACRO_dxy;                              \
-      } else { /* ! MACRO_xcycle */                                           \
-        if (MACRO_dxy == MACRO_do_xy || MACRO_dxy == -MACRO_do_xy)            \
-          continue;                                                           \
-       ARG_y_itr = (ARG_start_y) + MACRO_do_xy;                              \
-       if (MACRO_positive)                                                   \
-         ARG_x_itr = (ARG_start_x) + MACRO_dxy;                              \
-       else                                                                  \
-         ARG_x_itr = (ARG_start_x) - MACRO_dxy;                              \
-      }                                                                       \
-      {                                                                       \
-       int MACRO_dx = (ARG_start_x) - ARG_x_itr;                             \
-       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)) {    \
-       continue;                                                             \
-      }
-
-#define iterate_outward_end                                                   \
-    }                                                                         \
-    if (!MACRO_positive) {                                                    \
-      if (!MACRO_xcycle)                                                      \
-       MACRO_dxy++;                                                          \
-      MACRO_xcycle = !MACRO_xcycle;                                           \
-    }                                                                         \
-    MACRO_positive = !MACRO_positive;                                         \
-  }                                                                           \
+/* 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;                                                  \
+  int MACRO_max_dx = map.xsize/2;                                            \
+  int MACRO_min_dx = -MACRO_max_dx - 1 + (map.xsize % 2);                    \
+  bool MACRO_xcycle = TRUE;                                                  \
+  bool MACRO_positive = FALSE;                                               \
+  bool MACRO_is_border = IS_BORDER_MAP_POS(ARG_start_x, ARG_start_y,         \
+                                           ARG_max_dist);                    \
+  bool MACRO_revdes_out=0;                                                   \
+  int MACRO_dxy = 0, MACRO_do_xy;                                            \
+  CHECK_MAP_POS(ARG_start_x, ARG_start_y);                                   \
+  while(MACRO_dxy <= (ARG_max_dist)) {                                       \
+    for (MACRO_do_xy = -MACRO_dxy; MACRO_do_xy <= MACRO_dxy; MACRO_do_xy++) {\
+      if (MACRO_xcycle) {                                                    \
+       ARG_x_itr = (ARG_start_x) + MACRO_do_xy;                             \
+       if (MACRO_positive)                                                  \
+         ARG_y_itr = (ARG_start_y) + MACRO_dxy;                             \
+       else                                                                 \
+         ARG_y_itr = (ARG_start_y) - MACRO_dxy;                             \
+      } else { /* ! MACRO_xcycle */                                          \
+        if (MACRO_dxy == MACRO_do_xy || MACRO_dxy == -MACRO_do_xy)           \
+          continue;                                                          \
+       ARG_y_itr = (ARG_start_y) + MACRO_do_xy;                             \
+       if (MACRO_positive)                                                  \
+         ARG_x_itr = (ARG_start_x) + MACRO_dxy;                             \
+       else                                                                 \
+         ARG_x_itr = (ARG_start_x) - MACRO_dxy;                             \
+      }                                                                      \
+      {                                                                      \
+       int MACRO_dx = (ARG_start_x) - ARG_x_itr;                            \
+       if (MACRO_dx > MACRO_max_dx || MACRO_dx < MACRO_min_dx)              \
+         continue;                                                          \
+      }                                                                      \
+      if (MACRO_is_border && !normalize_map_pos_revdes(&ARG_x_itr,           \
+          &ARG_y_itr,&MACRO_revdes_out)) {                                   \
+       continue;                                                            \
+      }                                                                      \
+      ONETIME((ARG_start_x),(ARG_start_y),(ARG_x_itr),(ARG_y_itr),           \
+                                   (ARG_max_dist),(MACRO_revdes_out))
+
+/* end iterate if more than one time in reversed topologies */
+#define ONETIME(XC,YC,X,Y,D,rev_des)                                         \
+      if( (rev_des) && (MAX(abs((XC)-(X)),abs((YC)-(Y)))<=(D))) {            \
+         continue;                                                           \
+       }
+
+#define iterate_outward_end                                                  \
+    }                                                                        \
+    if (!MACRO_positive) {                                                   \
+      if (!MACRO_xcycle)                                                     \
+       MACRO_dxy++;                                                         \
+      MACRO_xcycle = !MACRO_xcycle;                                          \
+    }                                                                        \
+    MACRO_positive = !MACRO_positive;                                        \
+  }                                                                          \
 }
-
 #define rectangle_iterate(map_x0, map_y0, map_width, map_height,            \
                           x_itr, y_itr)                                     \
 {                                                                           \
@@ -450,18 +553,26 @@
  * 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;                                                         \
+  REVERSE_DESCRIPTOR_TYPE macro_revdes=REVERSE_NONE;                          \
   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_revdes(&(x_itr), &(y_itr),&macro_revdes)) {    \
         continue;                                                             \
-      }
+      }                                                                       \
+      ONETIME((center_x), (center_y),(x_itr), (y_itr), (radius),macro_revdes)
+ 
 
 #define square_dxy_iterate_end                                                \
     }                                                                         \
@@ -473,12 +584,12 @@
  * Positions returned will have adjusted x, and positions with illegal
  * y will be automatically discarded.
  */
-#define square_iterate(center_x, center_y, radius, x_itr, y_itr)              \
-{                                                                             \
-  square_dxy_iterate(center_x, center_y, radius, x_itr, y_itr,                \
-                     _dummy_x, _dummy_y);
+#define square_iterate(center_x, center_y, radius, x_itr, y_itr)             \
+{                                                                            \
+  square_dxy_iterate(center_x, center_y, radius, x_itr, y_itr,               \
+                     _dummy_x, _dummy_y)
 
-#define square_iterate_end  square_dxy_iterate_end                            \
+#define square_iterate_end  square_dxy_iterate_end                           \
 }
 
 /* 
@@ -486,50 +597,96 @@
  * radius.  Positions returned will have adjusted (x, y); unreal
  * positions will be automatically discarded. 
  */
-#define circle_iterate(center_x, center_y, sq_radius, x_itr, y_itr)           \
-{                                                                             \
-  int _cr_radius = (int)sqrt((double)(sq_radius));                            \
-  square_dxy_iterate(center_x, center_y, _cr_radius,                          \
-                    x_itr, y_itr, _dx, _dy) {                                \
+#define circle_iterate(center_x, center_y, sq_radius, x_itr, y_itr)          \
+{                                                                            \
+  int _cr_radius = (int)sqrt((double)(sq_radius));                           \
+  square_dxy_iterate(center_x, center_y, _cr_radius,                         \
+                    x_itr, y_itr, _dx, _dy) {                               \
     if (_dy * _dy + _dx * _dx <= (sq_radius)) {
 
-#define circle_iterate_end                                                    \
-    }                                                                         \
-  } square_dxy_iterate_end;                                                   \
+#define circle_iterate_end                                                   \
+    }                                                                        \
+  } square_dxy_iterate_end;                                                  \
 }                                                                             
 
 /* Iterate through all tiles adjacent to a tile */
-#define adjc_iterate(RI_center_x, RI_center_y, RI_x_itr, RI_y_itr)            \
-{                                                                             \
-  square_iterate(RI_center_x, RI_center_y, 1, RI_x_itr, RI_y_itr) {           \
-    if (RI_x_itr == RI_center_x && RI_y_itr == RI_center_y) {                 \
-      continue;                                                               \
+#define adjc_iterate(RI_center_x, RI_center_y, RI_x_itr, RI_y_itr)           \
+{                                                                            \
+  square_iterate(RI_center_x, RI_center_y, 1, RI_x_itr, RI_y_itr) {          \
+    if (RI_x_itr == RI_center_x && RI_y_itr == RI_center_y) {                \
+      continue;                                                              \
     }
 
-#define adjc_iterate_end                                                      \
-  } square_iterate_end;                                                       \
+#define adjc_iterate_end                                                     \
+  } square_iterate_end;                                                      \
 }
 
 /* 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_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(&x_itr, &y_itr)) {                 \
-       continue;                                                             \
+
+#define adjc_dir_iterate(center_x, center_y, x_itr, y_itr, dir_itr)          \
+{                                                                            \
+  int x_itr, y_itr, dir_itr;                                                 \
+  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(&x_itr, &y_itr)) {                \
+       continue;                                                            \
+    } 
+   
+#define adjc_dir_iterate_revdes(center_x, center_y, x_itr, y_itr, dir_itr,   \
+                                                                    revdes ) \
+{                                                                            \
+  int x_itr, y_itr, dir_itr;                                                 \
+  REVERSE_DESCRIPTOR_TYPE revdes= REVERSE_NONE;                              \
+  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,        \
+        &revdes)) {                                                          \
+       continue;                                                            \
     }
 
-#define adjc_dir_iterate_end                                                  \
-  }                                                                           \
+#define adjc_dir_iterate_full(center_x, center_y, x_itr, y_itr,              \
+                                    dir_itr,ndir_itr, revdes )               \
+{                                                                            \
+  int x_itr, y_itr, dir_itr,ndir_itr;                                        \
+  REVERSE_DESCRIPTOR_TYPE revdes= REVERSE_NONE;                              \
+  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_revdes(&x_itr, &y_itr,            \
+        &revdes)) {                                                          \
+       continue;                                                            \
+    }                                                                        \
+    ndir_itr = NORMALIZE_DIR(dir_itr, revdes);
+    
+#define adjc_dir_iterate_end                                                 \
+  }                                                                          \
+}
+
+#define adjc_dir_iterate_revdes_end                                          \
+  }                                                                          \
+}
+
+#define adjc_dir_iterate_full_end                                            \
+  }                                                                          \
 }
 
 /* Iterate over all positions on the globe. */
@@ -546,6 +703,22 @@
   }                                                                         \
 }
 
+/* Iterate: normal pos, then near no normal images of the provaides pos */
+#define near_orbit_iterate(map_x, map_y, itr_x, itr_y)                      \
+{  int MACRO_NO_xvec[9], MACRO_NO_yvec[9], MACRO_NO_i=0, MACRO_NO_ni;       \
+   int itr_x, itr_y;                                                        \
+   MACRO_NO_ni =                                                            \
+              map_near_orbit((map_x),(map_y), MACRO_NO_xvec, MACRO_NO_yvec);\
+   while( MACRO_NO_i < MACRO_NO_ni) {                                       \
+       itr_x = MACRO_NO_xvec[MACRO_NO_i];                                   \
+       itr_y = MACRO_NO_yvec[MACRO_NO_i];                                   \
+       MACRO_NO_i++;                                                        \
+        {
+
+#define near_orbit_iterate_end  \
+        }                       \
+    }                           \
+}
 /*
 used to compute neighboring tiles:
 using
@@ -602,15 +775,18 @@
 {                                                                             \
   int IAC_i;                                                                  \
   int IAC_x, IAC_y;                                                           \
-  bool _is_border = IS_BORDER_MAP_POS(x, y, 1);                               \
+  bool car_revdes=FALSE, _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_revdes(&IAC_x, &IAC_y, &car_revdes)) {                 \
       continue;                                                               \
-    }
+    }                                                                         \
+   ONETIME((x),( y), IAC_x, IAC_y,1 ,car_revdes);
+
 
 #define cartesian_adjacent_iterate_end                                        \
   }                                                                           \
@@ -623,18 +799,42 @@
 #define MAP_MIN_HUTS             0
 #define MAP_MAX_HUTS             500
 
+#define MAP_DEFAULT_SIZE         2
+#define MAP_MIN_SIZE             0
+#define MAP_MAX_SIZE             10
+
+#define MAP_MIN_WIDTHandHEIGHT   20
+#define MAP_MAX_WIDTHandHEIGHT   200
+
+/* map_init_topology() modifiy it by the x-y ratios */
 #define MAP_DEFAULT_WIDTH        80
-#define MAP_MIN_WIDTH            40
-#define MAP_MAX_WIDTH            200
+#define MAP_MIN_WIDTH            MAP_MIN_WIDTHandHEIGHT
+#define MAP_MAX_WIDTH            MAP_MAX_WIDTHandHEIGHT
 
 #define MAP_DEFAULT_HEIGHT       50
-#define MAP_MIN_HEIGHT           25
-#define MAP_MAX_HEIGHT           100
+#define MAP_MIN_HEIGHT           MAP_MIN_WIDTHandHEIGHT
+#define MAP_MAX_HEIGHT           MAP_MAX_WIDTHandHEIGHT   
+
+#define MAP_DEFAULT_RATIO         100  
+#define MAP_MIN_RATIO             11    /* the 1:1 ratio */
+#define MAP_MAX_RATIO             100   /* 100 for default ratio */
+
+/* get DEFAULT RATIO facto Xratio*Yratio as litle as posible
+ * this is best for litrles map sizes                        
+ * get DEFAULT RATIO < 2:1 or 1:2                              
+ */
+#define DEFAULTRATIO_CLASSIC        74 /* 85 is too big 8*5=40, 7*4=28 best*/
+#define DEFAULTRATIO_FLAT           11
+#define DEFAULTRATIO_TORUS          11
+#define DEFAULTRATIO_MOBIUS         21
+#define DEFAULTRATIO_SPIN           23
+#define DEFAULTRATIO_QUINCUNCIAL_SQ 11
+#define DEFAULTRATIO_QUINCUNCIAL    21
 
-#define MAP_ORIGINAL_TOPO        TF_WRAPX
-#define MAP_DEFAULT_TOPO         TF_WRAPX
+#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             6
 
 #define MAP_DEFAULT_SEED         0
 #define MAP_MIN_SEED             0
diff -ruN -Xdiff_ignore freeciv-cvs-Jan-08/common/shared.h 
freeciv/common/shared.h
--- freeciv-cvs-Jan-08/common/shared.h  2003-11-29 07:05:27.000000000 +0100
+++ freeciv/common/shared.h     2004-01-09 20:49:33.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 -ruN -Xdiff_ignore freeciv-cvs-Jan-08/data/isotrident/terrain1.spec 
freeciv/data/isotrident/terrain1.spec
--- freeciv-cvs-Jan-08/data/isotrident/terrain1.spec    2002-05-02 
07:46:59.000000000 +0200
+++ freeciv/data/isotrident/terrain1.spec       2004-01-09 20:49:33.000000000 
+0100
@@ -135,6 +135,7 @@
   0, 3, "t.coast_color"
 
   0, 4, "user.attention"
+  0, 1, "tx.lfog"
 }
 
 
diff -ruN -Xdiff_ignore 
freeciv-cvs-Jan-08/data/scenario/WorldQuincuncial_100xx2_mburda_v0.41.sav 
freeciv/data/scenario/WorldQuincuncial_100xx2_mburda_v0.41.sav
--- freeciv-cvs-Jan-08/data/scenario/WorldQuincuncial_100xx2_mburda_v0.41.sav   
1970-01-01 01:00:00.000000000 +0100
+++ freeciv/data/scenario/WorldQuincuncial_100xx2_mburda_v0.41.sav      
2004-01-09 20:49:33.000000000 +0100
@@ -0,0 +1,559 @@
+[game]
+version=11300
+server_state=2
+metastring="BigWrldQuincuncial V0.41 mburda@xxxxxxxxx"
+metaserver="meta.freeciv.org"
+gold=0
+tech=0
+skill_level=0
+timeout=0
+timeoutint=0
+timeoutintinc=0
+timeoutinc=0
+timeoutincmult=1
+timeoutcounter=1
+end_year=3000
+year=-5000
+turn=0
+researchcost=8
+min_players=1
+max_players=32
+nplayers=0
+globalwarming=0
+warminglevel=8
+nuclearwinter=0
+coolinglevel=8
+notradesize=0
+fulltradesize=1
+unhappysize=4
+angrycitizen=0
+cityfactor=14
+citymindist=0
+civilwarsize=10
+contactturns=20
+rapturedelay=1
+diplcost=0
+freecost=0
+conquercost=0
+foodbox=10
+techpenalty=80
+razechance=20
+civstyle=2
+save_nturns=20
+save_name="civgame_WQ41"
+aifill=10
+scorelog=0
+fogofwar=1
+spacerace=1
+auto_ai_toggle=1
+diplchance=80
+aqueductloss=0
+killcitizen=1
+turnblock=0
+savepalace=1
+fixedlength=0
+barbarians=3
+onsetbarbs=-3500
+occupychance=0
+demography="NASRLPEMOqrb"
+borders=7
+diplomacy=0
+watchtower_vision=2
+watchtower_extra_vision=0
+settlers=3
+explorer=2
+dispersion=3
+randseed=0
+save_random=0
+rulesetdir="default"
+save_starts=1
+save_known=0
+save_players=0
+
+[savefile]
+options="startoptions spacerace2 rulesets diplchance_percent worklists2 
map_editor known32fix turn attributes watchtower rulesetdir client_worklists 
startpos specials"
+
+[map]
+topology_id=2
+width=100
+height=100
+seed=0
+landpercent=60
+riches=0
+swampsize=2
+deserts=10
+riverlength=0
+mountains=10
+forestsize=0
+huts=100
+generator=0
+spesials=200
+have_huts=1
+is_earth=1
+fixed_start_positions=1
+r0sx=86
+r0sy=88
+r1sx=87
+r1sy=78
+r2sx=79
+r2sy=85
+r3sx=83
+r3sy=69
+r4sx=77
+r4sy=70
+r5sx=71
+r5sy=77
+r6sx=63
+r6sy=82
+r7sx=60
+r7sy=86
+r8sx=54
+r8sy=78
+r9sx=62
+r9sy=71
+r10sx=70
+r10sy=68
+r11sx=64
+r11sy=64
+r12sx=56
+r12sy=66
+r13sx=55
+r13sy=62
+r14sx=50
+r14sy=61
+r15sx=62
+r15sy=53
+r16sx=71
+r16sy=60
+r17sx=75
+r17sy=53
+r18sx=72
+r18sy=47
+r19sx=71
+r19sy=39
+r20sx=64
+r20sy=34
+r21sx=59
+r21sy=39
+r22sx=75
+r22sy=13
+r23sx=71
+r23sy=8
+r24sx=76
+r24sy=3
+r25sx=85
+r25sy=13
+r26sx=68
+r26sy=10
+r27sx=48
+r27sy=60
+r28sx=36
+r28sy=65
+r29sx=32
+r29sy=59
+r30sx=28
+r30sy=63
+r31sx=24
+r31sy=53
+r32sx=30
+r32sy=73
+t000="aaaa         h                                                           
                      aaaaa"
+t001="aaaa      f  f                                                           
     ppg              aaaaa"
+t002="aaaa      fh                                                  f          
    fmmmmp            aaaaa"
+t003="aaa                                                         f  fh        
  pgppppfff            aaaa"
+t004="aaa                                                         h   h    j   
  jpppppfff ff        aaaaa"
+t005="           jh                                                   g  jj    
 fjpdppppff f          aaaa"
+t006="            jg                                                     g    
fpjjpddpphpf            aaa "
+t007="             hj                                               f   hj   
fpjjpddddphp              aa "
+t008="              jh                                                 jmh   
pjjppdddddph               a "
+t009="                                                                 gmm  
gfjpgpddddppp                 "
+t010="                                                                gjhmg    
 ffdppmppp                 "
+t011="                                                                jjhhj    
  fpmmpmdpp                "
+t012="        h    f                                                   jhmg    
jffpddddddpp               "
+t013="       ff   fh                                                    hmm    
gpppdddddddpp              "
+t014="            f                                                       g    
jggpdddddddppg             "
+t015="                                                                   j     
jgjfpdddddddpfg            "
+t016="                                                                   jg    
  jfgfpdddddp              "
+t017="                                                                    j    
    fg pdddpp              "
+t018="                                                                    g    
        ppp                "
+t019="             ff                                                      g  
h                           "
+t020="              hh                                                         
ph                         "
+t021="               f                                                         
 ph                        "
+t022="                                                                    p pp 
  fh                       "
+t023="                                                                         
     h                     "
+t024="                                                                    fh   
     fh                    "
+t025="                                                                     f  
fffff  ff                   "
+t026="                                                                        
hhhfh   h                   "
+t027="                                                                  hh    
hffff   h                   "
+t028="                ff                                                f    
fff     f                    "
+t029="                 f                                                f     
f      fh                   "
+t030="                                                                  h      
      fh                   "
+t031="                                                                         
      fh                   "
+t032="                          f                               h      j       
h     fh                   "
+t033="                          f                            fgh     gffjjj   
hjj  h fh                   "
+t034="                        ff                            fhmm     fgffhhj  
jjj jh f                    "
+t035="                                                     h      g  
gfgffjhjjhjjjj                       "
+t036="                                                    fm      hh 
gfffffhhjhjj                         "
+t037="                                                   m f      hh  
gffgfghjjjjjj                       "
+t038="                                                     m    ghhp 
ghffffgfhjjjj                        "
+t039="                                                 a   
mmffhggmpphhfggfffpppj                         "
+t040="                                                aa    
mmfhhpppdddhhmmmggjjj                         "
+t041="                                                a      
tffhhppddddmmfmmpgggg                        "
+t042="                                               aaaaaa  
ttffghppdddmfpfmgfjffjg    fff               "
+t043="                                         t    aaa a aaa 
tffmghppddmfpfmmffhjjfjjf   ff              "
+t044="                                        fmt  aa       
aattfmfhhmpddmmfpmffhhfffjjfj                 "
+t045="                                        fmmmaa  a aa 
aaattffffhhmpddmffmpfhhffjfhffj                "
+t046="                                        fmfta    a   a 
attfggffhhhpdmmpmpphpjjhhhjf                 "
+t047="                                        mmftaaa a aaa 
aattffffffhhfddmmmpddppjjff                   "
+t048="                                       fmftta a  a  
aaaattffffgffgfpdmmpppddpp       f f f          "
+t049="                             g   ff fffmmttaa aa   a  
aattffgffffffppmmfpppddpj                     "
+t050="                            phgpfffffffmftaaaa  aa  a a 
atmmmmmmffggpphhfppppg                      "
+t051="                          pphmmmmmmmmmmmttaa   a aa   aaatffmmgmmg  
ghhhhhfpp                       "
+t052="                          phmmmmmhhhhtmtaaaaa   a  a 
aaaatffgfgfgfgddhppphhh                        "
+t053="                        pghmmmhhhfghghttaaaa a a a a    atffgggggf 
gghpdpppp                        "
+t054="                      ghmmmmmhhffffffhtttaaaa        aaaatffgfgfgf   
hppdddp                        "
+t055="                      p mmmmhhgpgpfgfgtttta    a aa aa   tfffggggg    
hpdppp                        "
+t056="                       gmmmhhgpppgphhft  aaaaaaaaaaaaa ffffffgffgfgm  
hpppp                         "
+t057="                      gdmmgggpgpgpgfht    aaa  maah    hff 
ffgggggmmghhmmmp  pd                     "
+t058="                     dhmmdghgpgffpppht     aa mmmht    mf  ffgfg   gmmmm 
    pdd                    "
+t059="                    gdmmdpdgfpfpppp  t     ta hmht    hmf   ffg    mmmmm 
    pdd                    "
+t060="                    dhmdpppfppppppgf f  th  t thp h   mhff  ffg    
gggggg ppppdd                    "
+t061="                    hmmp   fppppgf  fg  hhm  ttp  p   mf g  ffhg  
ggggdddddddddd                    "
+t062="                    hmdp   pppppgfgf gtthmm   p        g   ffmmh 
gggggdddddddddh  gd                "
+t063="                    jhj     ppppffhg fg fght             ffffggh  gg  
dddddhdhdh  dgd               "
+t064="                     hjj     jjghhhpfgfg  g          pf fffmmgggg    g 
pppppppdd  ggd               "
+t065="                     h       jjpgpg gfgf ff         h h ghhmhhhhgh g   
gg         ggdg              "
+t066="                     hjfff  jj           g          g  gshgmgh    g    
gddd     g gggd              "
+t067="                     jhj                               fgfg  ghgg      
ppdddddhgggdggg              "
+t068="                     hhjf  pj                           mm h    g     
gppppdddhhgfgddd              "
+t069="                     jhjf  ff                         ghpp     h     
gpdddppddhmhgdgfg              "
+t070="                     hf     h                         gdg             
pddddpppghmhfgdf              "
+t071="                     hj    g m                         h      pp     
pdddddddpgghmggfg              "
+t072="                     hjm    pjf                              
pppppppdpdddddddggfgghgdg              "
+t073="                      mggg    p                          
fffpddddddddddddddddgfgg  hgf        j     "
+t074="                      mjjjj    h                        
ffpppdddddddddddddddpgfgj  gfg       gh     "
+t075="                  jhhmmjjjjj  p                         
fppdddddddddddddddppgfgjj  hggj      fj     "
+t076="                 jhmmffjjjjs                           
ffpdddddddddddddddppfgjjjjgghhgjj    gfh     "
+t077="                 hmmffjjjjjjjj                        
ffpddddddddddddddpppfgjjjjjjgfghhjj   fghj    "
+t078="                jmmfjjjjhhmjjj                        
ppdddddddddddddphppfgjjjjjjjfgghhgjj   fhj    "
+t079="                hmhfjjjjjjhjjj                        
pdddddddddddddphhggfjfjjjjjgggffghjj   fhj    "
+t080="               jmmhfjjjjjjjhjj                        
ddddddddddppppghggfgjjjjjjjgfpppfghj   gjj    "
+t081="               hmmmfjjj sjjjjjj                       
dddddddddpppggfgffggjjjjjggppddgfgfj    j     "
+t082="               hm mffjjj jjjhjjj                       pddddddpppggfgfg 
gfjjjggpdddddgggfgj         "
+t083="               hm mfjjjjs sjjhjj                       pddddppppgggg     
jjjjgpddddddddhfgf         "
+t084="                mmmfjffjjj jjjjj                       pddpppppgggfj     
    gddddddddhgmhg         "
+t085="                dmffffffjjj  jjs                       pppppppggjgj      
     ddhddddddhmhf         "
+t086="              ddmmffffhfjjjjs                            pppppgfj        
      ddddddhdhhhg         "
+t087="             dmmmmgffffffjjjjjsj                          p ppgg         
       dddhdddpppf         "
+t088="           fmmmmggffgghfffjjjjjj                                         
         ddppppppg         "
+t089="          hmmmpgggggggffffjjjjjjj                                        
             gpfg          "
+t090="         ffmpppggggggfghfffjjhjjj                                        
              gf           "
+t091="        tmmfdppgggggggghhffhjhjjjj                                       
                           "
+t092="      mmmmfpdpgggggggfgfggffhjhjjj                                       
                           "
+t093="      mfffpppgggg ffhhffgfhhjjhjjj                                       
                           "
+t094="      mtttp phgg gfhhghghhhgjjjjhj                                       
                           "
+t095="     m t        ggf ggghhhghgjjjhhj                                      
                           "
+t096="     gt              gg ggggggggjh                                       
                           "
+t097="                     gg        gg                                        
                           "
+t098="    t                                                                    
                          a"
+t099="aaatt   ht                                                               
                          a"
+l000="0000000000000000000000000000000000000000000000000000000001000000000000000010000000000000000010000000"
+l001="0000000001101100100000000000000000000000000000000000000000000000001001000000000000011000000000000000"
+l002="0000000010000000000000000000000000000000000000000000000000010000000000001000000010000000000000000000"
+l003="0000000000000010000000000000000000000000000000000000000000000000010000000000010000000000000000000000"
+l004="0000000000000000000000000000000000000000000000000000000000101010100000100001000000100100000001000000"
+l005="0000000001000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000"
+l006="0000000000000100100000000000000000000000000000000000000000000100000010000000000000000000000000000000"
+l007="0000000000000100000000000000000000000000000000000000000000010010000101001000000000000001000000000000"
+l008="0000000000001000000000000000000000000000000000000000000000000000000000000000000000000100000000000000"
+l009="0000001010000010110000000000000000000000000000000000000000000001000000010100000000100000000000000000"
+l010="0000000000000000000000000000000000000000000000000000000000000101010000000000000000000010000000001000"
+l011="0000010000000001000000000000000000000000000000000000000000000000000001000000000000000000000000000000"
+l012="0000000000000000000000000000000000000000000000000000000000000000000100010000000000000000000000000000"
+l013="0000001011011000000000000000000000000000000000000000000000000001000000000010000000000001010000000000"
+l014="0000000000000010100000000000000000000000000000000000000000000000000001000000000000000110000000000000"
+l015="0000000000000000000000000000000000000000000000000000000000000000010000000001000000000000000000000000"
+l016="0000000010010001000000000000000000000000000000000000000000000000100010010000000000000000000000000000"
+l017="0000000000000000000000000000000000000000000000000000000000000000000000000000001000000000001000000000"
+l018="0000000000000100100000000000000000000000000000000000000000000000000000000000000000100000000000000000"
+l019="0000000000010000000000000000000000000000000000000000000000000000010010000000000000010001000000000000"
+l020="0000000000000101000000000000000000000000000000000000000000000000000000000000001000000000000000000000"
+l021="0000000000000000010000000000000000000000000000000000000000000000000000000000010000001000000000000000"
+l022="0000000000000100000000000000000000000000000000000000000000000000011000100000100000000000000000000000"
+l023="0000000000000001000000000000000000000000000000000000000000000000000001001001000010100000000000000000"
+l024="0000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000"
+l025="0000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000"
+l026="0000000000000000001000000000000000000000000000000000000000000000000000000000001001000000000000000000"
+l027="0000000000000000000000000000000000000000000000000000000000000000000000100001000010010000000000000000"
+l028="0000000000000100100000000000000000000000000000000000000000000001000010000000000000000000000000000000"
+l029="0000000000000000001010000010000000000000000000000000000000010000001000000000000001000000000000000000"
+l030="0000000000000001000000000000000000000000000000000000000010000010000101000100000000010000000000000000"
+l031="0000000000000000000100000100000000000000000000000000100001010000000000000000001100000000000000000000"
+l032="0000000000000000010000000000000000000000000000000000010100100000000000000000000000000000000000000000"
+l033="0000000000000000000000001000100000000000000000000001000000000100000000100000000000010000000000000000"
+l034="0000000000000000000001000000000000000000000000000000000010000010000010000000000000000000000000000000"
+l035="0000000000000000000000001010000000000000000000000101000000000000000000000000000010000000000000000000"
+l036="0000000000000000000000010000010000000000000000000000010100010000000000000100010001000000000000000000"
+l037="0000000000000000000000000001000000000000000000000000000000000000001000000000000100000000000000000000"
+l038="0000000000000000000000000000000000000000000000000000000010100000000000000000001000000000000000000000"
+l039="0000000000000000000000000000000000000000000000000000000000000000000000000000000001001000000000000000"
+l040="0000000000000000000000000000000000000010010000000000000010000000000100000000100100000000000000000000"
+l041="0000000000000000000000000000000000000000000000000000000000000000001001000000000000001001000000000000"
+l042="0000000000000000000000000000000000000100000000000000000010000000000000000000000001000000000000000000"
+l043="0000000000000000000000000000000000000001000100000000000000010000000000000000100000000001000000000000"
+l044="0000000000000000000000000000000000000000000000000000000000000000000001000100001000000000000000000000"
+l045="0000000000000000000000000000000000000100010000000000000000000100001000000000000010000000100000000000"
+l046="0000000000000000000000000000100010100000000000000000000000000000000000000000000000000000000100000000"
+l047="0000000000000000000000000000000000000000000000000000000001000010000000100000000000000001001000000000"
+l048="0000000000000000000000000100100010101000100000000000000000000000000000000000000001000000000000000000"
+l049="0000000000000000000000000000000000001000000000000000000000000000000000000000100000001000000000000000"
+l050="0000000000000000000000100000000000000000000000000000000000000000000000000000000101010000010010000000"
+l051="0000000000000000000000001001000000100000000000000000000001000000000100010000000000000101001000000000"
+l052="0000000000000000000010000000000000000000000000000000000000001000000000000010000100000000000000000000"
+l053="0000000000000000000001000000000000000000000000000000000000000000000000000000100000000000000000000000"
+l054="0000000000000000000100000100000000000000000000000000000001000000000000000000001000000000000000000000"
+l055="0000000000000000000000000000001000000001000000000000000000000000000100000000000000000000000000000000"
+l056="0000000000000000001001000100000100000000000000000010000000001000000000000010000001000000000000000000"
+l057="0000000000000000000000000000000001000100100010000101000100000000000000001001000000000000000000000000"
+l058="0000000000000000000100000000000011000000001101000000100010000000000000000000000000000000000000000000"
+l059="0000000000000000010000000000000000000101000000000001000010000000010000101000100000010000000000000000"
+l060="0000000000000000000000100000000000000000000001000000010000000000100000000000000010000000000000000000"
+l061="0000000000000000000100000000000100000000000000000000000000010000000100000000000000001000000000000000"
+l062="0000000000000000010000000000001000000001000011000100000000000000000000000000000000000010000000000000"
+l063="0000000000000000000000000000000000000000000000001000100000000000000000000000000000000000000000000000"
+l064="0000000000000000000010001001000000000000000000000000001000000000000000000000000000000010000000000000"
+l065="0000000000000000001001000000001000000000000101010101000000000000000010010001000010010000000000000000"
+l066="0000000000000000000000000000000000001000000100000000000000000000000000000000000000000000100000000000"
+l067="0000000000000000001000010000000010000001000101000001100000000000010000000000000010000001000000000000"
+l068="0000000000000000000010100000000000100100000000000000000000000000000100000000000000000000000000000000"
+l069="0000000000000000001000000100110100000000010100000001010000000100000000000000000000000000000000000000"
+l070="0000000000000000000010100000000000000000000000000000000000000000000010001010000000000000100000000000"
+l071="0000000000000000000000100000010100000000000000000000100000000000000010000010000100010000000011001000"
+l072="0000000000000000001000000100000001000000000000000000000000000000000000010000001000000000000000000000"
+l073="0000000000000000100010100000010010000000000000000000010000000000000000000000000000000000011000001000"
+l074="0000000000000010000000001000100000000000000000000000000100000010000000001000000001100000000100101100"
+l075="0000000000000000100010000000000010000000000000000000100000001000000001000000000100000000100001000000"
+l076="0000000000000000010000000000000001100000000000000000000000000101000000000100000000001000000010010000"
+l077="0000000000000100000000001000000000000000000000000000000000100000000000000000010000000010000000000010"
+l078="0000000000000001000000000000000010000000000000000001000000000000000000000000000000000000000000000000"
+l079="0000000000000100000001000000100000000000000000000000000000001000000000000000000000000000000000100100"
+l080="0000000000000000010001000000000010000000000000000000000010000000001000010000100000000010000100000010"
+l081="0000000000001000000000010000000000000000000000000001000000000000000000000001100000100000000000001000"
+l082="0000000000000000010011000000000010000000000000000000000000000000001000000000000000000000100001010000"
+l083="0000000000001010000000000100100000100000000000000000110000000000000000000000000000000000000000000100"
+l084="0000000000010000000000010000000000000000000000000000000000000100000000100000000000000001000000010000"
+l085="0000000000000000000000000001000000000000000000000000000000000100000000001000100000000000000001000000"
+l086="0000000001000100010000000000001010100000000000000000100000100000001000100001000000000100000010000000"
+l087="0000000100000001000000000000000000000000000000000000001100000000000000000001000000000001000000000000"
+l088="0000000000000000000001000100000000000000000000000000001000100001000010000000010000000000100001000000"
+l089="0000000010001100000000000000000000010000000000000000000001000000000000000000000000000000000100000000"
+l090="0000000110000000100010000000011000000000000000000000000000010000001000000000000010100000000010000000"
+l091="0000000000000000010000000000000000100000000000000000000000000001000000000000000000010000100000000000"
+l092="0000010001000000000000000010000000001000000000000000000000000000000000000000000000000100001000000000"
+l093="0000000000010100000000000001001000000000000000000000000000000000000000000000000000000000100000000000"
+l094="0000000001000000000000001000001000000000000000000000000000000000000000000000000000000000000000000000"
+l095="0000100001000000000000000000010000000100000000000000000000000000000000000000000000000000000000000000"
+l096="0000000011011000010100000000000000010000000000000000000000000000000000000000000000000000000000000000"
+l097="0000100000001000000000000010000000001000000000000000000000000000000000000000000000000000000000000000"
+l098="0000000010100010010000000000000010000000000000000000000000000000000000000000000000000000000000000000"
+l099="0000001010010000000000001000100000100000000000000000000000000000000000000000000000000000000000000000"
+u000="0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
+u001="0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
+u002="0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
+u003="0000000000000000000000000000000000000000000000000000000000000000000000000004000000040000000000000000"
+u004="0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
+u005="0000000000000000000000000000000000000000000000000000000000000000000000000004000000000400000000000000"
+u006="0000000000000000000000000000000000000000000000000000000000000000000400004000000000000000000000000000"
+u007="0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
+u008="0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
+u009="0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
+u010="0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
+u011="0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
+u012="0000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000"
+u013="0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
+u014="0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
+u015="0000000000000000000000000000000000000000000000000000000000000000000000000040000000000004000000000000"
+u016="0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
+u017="0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
+u018="0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
+u019="0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
+u020="0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
+u021="0000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000"
+u022="0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
+u023="0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
+u024="0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
+u025="0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
+u026="0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
+u027="0000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000"
+u028="0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
+u029="0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
+u030="0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
+u031="0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
+u032="0000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000"
+u033="0000000000000000000000000000000000000000000000000000000000000000400000000040000000000000000000000000"
+u034="0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
+u035="0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
+u036="0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
+u037="0000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000"
+u038="0000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000"
+u039="0000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000"
+u040="0000000000000000000000000000000000000000000000000000000400000400000000000000000000000000000000000000"
+u041="0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
+u042="0000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000"
+u043="0000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000"
+u044="0000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000"
+u045="0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
+u046="0000000000000000000000000000000000000000400000000000000000040000040000400000000000000000000000000000"
+u047="0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
+u048="0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
+u049="0000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000"
+u050="0000000000000000000000000000000400000040000000000000000000000000000000000000000000000000000000000000"
+u051="0000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000"
+u052="0000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000"
+u053="0000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000"
+u054="0000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000"
+u055="0000000000000000000000000000400000040000000000000000000000000000000000000000000000000000000000000000"
+u056="0000000000000000000000040000000000000000000000000000000000000000000000000040000000000000000000000000"
+u057="0000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000"
+u058="0000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000"
+u059="0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
+u060="0000000000000000000000000000000000000000000000000000000400000000000000004000000000000000000000000000"
+u061="0000000000000000000000000000000000000400000000000040000000000000000000000000000000000000000000000000"
+u062="0000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000"
+u063="0000000000000000000000000000000400000000040000000000000000000040000000000000000000000000000000000000"
+u064="0000000000000000000000000000000000000000000000000000000000400000000000040000000000000000000000000000"
+u065="0000000000000000000000000000000000000000000000000000400000000000040000000000000000000000000000000000"
+u066="0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
+u067="0000000000000000000000000000000000000000000000000000000400000040000000040000000000000000000000000000"
+u068="0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
+u069="0000000000000000000000000000000000000000000000000000000000000000000000000000400000000400000000000000"
+u070="0000000000000000000000400000000000000000000000000000004000000000000000000000000000000000000000000000"
+u071="0000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000"
+u072="0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
+u073="0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
+u074="0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
+u075="0000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000"
+u076="0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
+u077="0000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000"
+u078="0000000000000000000000000000000000000000000000000000000400000000000000000000000400000000000000000000"
+u079="0000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000"
+u080="0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040004000000"
+u081="0000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000"
+u082="0000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000"
+u083="0000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000"
+u084="0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
+u085="0000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000"
+u086="0000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000"
+u087="0000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000"
+u088="0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
+u089="0000000000000004000000000000000000000000000000000000000000000000000000000000000000000040000000000000"
+u090="0000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
+u091="0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
+u092="0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
+u093="0000000000400004000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
+u094="0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
+u095="0000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000"
+u096="0000004000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000"
+u097="0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
+u098="0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
+u099="0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
+n000="0000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
+n001="0000000000000000000000000000000000000000000000000000000000000000000000000000000010100000000000000000"
+n002="0000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
+n003="0000000000000000000000000000000000000000000000000000000000000000000000000002220202000000000000000000"
+n004="0000000000000000000000000000000000000000000000000000000000000000000000000000021222000001000000000000"
+n005="0000000000000000000000000000000000000000000000000000000000000000000000000000022112200000000000000000"
+n006="0000000000000010000000000000000000000000000000000000000000000000000000002000002220200000000000000000"
+n007="0000000000000010000000000000000000000000000000000000000000000000000000002222000020200000000000000000"
+n008="0000000000010000000000000000000000000000000000000000000000000000000000000010000000000000000000000000"
+n009="0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
+n010="0000000000010000000000000000000000000000000000000000000000000000000000000000001000100000000000000000"
+n011="0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
+n012="0001100010000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000"
+n013="0000000000000000000000000000000000000000000000000000000000000000000000000000100000001000000000000000"
+n014="0000000000001000000000000000000000000000000000000000000000000000000000000000000000000000100000000000"
+n015="0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
+n016="0000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
+n017="0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
+n018="0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
+n019="0000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
+n020="0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
+n021="0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
+n022="0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
+n023="0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
+n024="0000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
+n025="0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
+n026="0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
+n027="0000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000"
+n028="0000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000"
+n029="0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
+n030="0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
+n031="0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
+n032="0000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000"
+n033="0000000000000000000000000000000000000000000000000000000000000002200000000220000000000000000000000000"
+n034="0000000000000000000000000100000000000000000000000000000000000000220000000200000000000000000000000000"
+n035="0000000000000000000000000000000000000000000000000000000000000000022200020200000000000000000000000000"
+n036="0000000000000000000000000000000000000000000000000000000000000000000230020000000000000000000000000000"
+n037="0000000000000000000000000000000000000000000000000001000000000000220022002232200000000000000000000000"
+n038="0000000000000000000000000000000000000000000000000000000000200000022202000000000000000000000000000000"
+n039="0000000000000000000000000000000000000000000000000000010000222000020200222200000000000000000000000000"
+n040="0000000000000000000000000000000000000000000000000000000000002200022002200220000000000000000000000000"
+n041="0000000000000000000000000000000000000000000000000000000222101001000000001220000000000000000000000000"
+n042="0000000000000000000000000000000000000000000000000000000000000000000000000200000000100000000000000000"
+n043="0000000000000000000000000000000000000000000000000000000010000220000000000200002000000000000000000000"
+n044="0000000000000000000000000000000000000000000000000000000000002200000000000220002022000000000000000000"
+n045="0000000000000000000000000000000000000000000000000000000001002000000000000200202020000000000000000000"
+n046="0000000000000000000000000000000000000000000000000000000022222000220000000000220000000000000000000000"
+n047="0000000000000000000000000000000000000000000100000000000000000002200110202001020000000000000000000000"
+n048="0000000000000000000000000000000000000000000000000000000022221222000000222000020000000001000000000000"
+n049="0000000000000000000000000000000000000000000000000000000001022201000000002200000000000000000000000000"
+n050="0000000000000000000000000000000000000000010000000000000000000000000000001222000000000000000000000000"
+n051="0000000000000000000000000000000000000000010000000000000000000120000000000002200000000000000000000000"
+n052="0000000000000000000000000000000100000000000000000000000000000020000010000000000000000000000000000000"
+n053="0000000000000000000000000000000000000000000000000000000001012232200000000000000000000000000000000000"
+n054="0000000000000000000000000000000000000000000000000000000000022000220000001000000000000000000000000000"
+n055="0000000000000000000000000001000000000000010000000000000000020022000000000000000000000000000000000000"
+n056="0000000000000000000000000000002000000000000000000000000000000002000000000000000000000000000000000000"
+n057="0000000000000000000000000002202000000000000000000000000001000002200001000000000000000000000000000000"
+n058="0000000000000000000000000000202000100000000000000000000000000220000000000000000000000000000000000000"
+n059="0000000000000000000000010000202022000000000100000000010000001020000020000000001000000000000000000000"
+n060="0000000000000000000000000000202230000000000000000001000000000000000022222000000000000000000000000000"
+n061="0000000000000000000000000000322000000000000001000000000000000000000020000000100000000000000000000000"
+n062="0000000000000000000000000000200000000000000000001000001000022000000000000000000000000000000000000000"
+n063="0000000000000000000000000000200000000000000000010000000000012000000000011000000000010000000000000000"
+n064="0000000000000000000000000000000000000000000010000000000000000222200000000000000000000000000000000000"
+n065="0000000000000000000000000000000000000000000000000000002000200000000000000000000000000000000000000000"
+n066="0000000000000000000000000000100000100000000000000000000220202000000000000000000000010000000000000000"
+n067="0000000000000000000000000000000000000010001000000000000000200000000000022100000000000000000000000000"
+n068="0000000000000000000000000000000000000000000000000000000000000000000000233230000000220000000000000000"
+n069="0000000000000000000000000000000000000000000000000000000022000000000000000022200010222200000000000000"
+n070="0000000000000000000000000000100000000000000000000000002200000000000000000000320000000000000000000000"
+n071="0000000000000000000000000000000000000000000000000000000000000010000000000000022000000000000000000000"
+n072="0000000000000000000000000000000000000000000000000000000000000000000000000000022200000000000000000000"
+n073="0000000000000000000000000000000000000000000000000000000000100000000000000000020220000000000000000000"
+n074="0000000000000000000000000100000000000000000000000000000000000000000000000000220200000000000000000000"
+n075="0000000000000000000000000000000000000000000000000000000001000000000000000000200220001000000000001000"
+n076="0000000000000000000000000002000000000000000000000000000000000000000000000000200022000000000000001000"
+n077="0000000000000000000002002220000000000000000000000000000000000000000000222200000012200200000000010000"
+n078="0000000000000000010002000000000000000000000000000000000000000000000000000220000000220222100001000000"
+n079="0000000000000000000022020000000000000000000000000000001000000000000000000000000000000002200000000000"
+n080="0000000000000000002220320200220000000000000000000000000000000000002222000000000000000002220000000000"
+n081="0000000000000000000000000202200000000000000000000000000000000000222002200000000000000022000000000000"
+n082="0000000000000000000002220200001000000000000000000000000000000022200010200000000000002220000000000000"
+n083="0000000000000000001222200000000000000000000000000000000000000020022200000000020000000000100000000000"
+n084="0000000000000000010000000000000000000000000000000000000100001020200200000000002200100000000000000000"
+n085="0000000000000000000022202320000000000000000000000000000001000020220000000000000200000000000000000000"
+n086="0000000000000000000020022000200000000000000000000000000000002200000000000000000220000000201000000000"
+n087="0000000000000000000220020000200000000000000000000000000000002000000000000000000020000002200010000000"
+n088="0000000000000010002200000003200000000000000000000000000000000000000000000000000000000022000000000000"
+n089="0000010000000000002000000022000000000000000000000000000000000000000000000000000000000021000000000000"
+n090="0000000000000010012000000220000000000000000000000000000000000000000000000000000000000000000000000000"
+n091="0000000001000201002000200000000000000000000000000000000000000000000000000000000000000010000000000000"
+n092="0001000000002200022222200000000000000000000000000000000000000000000000000000000000000000000000000000"
+n093="0000000000022000000010000000000000000000000000000000000000000000000000000000000000000000000000000000"
+n094="1000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
+n095="0000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000"
+n096="0000000000100010000001000000000000000000000000000000000000000000000000000000000000000000011000001000"
+n097="0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000110000001000"
+n098="0000001100000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000"
+n099="0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100"
diff -ruN -Xdiff_ignore freeciv-cvs-Jan-08/data/trident/tiles.spec 
freeciv/data/trident/tiles.spec
--- freeciv-cvs-Jan-08/data/trident/tiles.spec  2003-11-21 07:05:57.000000000 
+0100
+++ freeciv/data/trident/tiles.spec     2004-01-09 20:49:33.000000000 +0100
@@ -370,6 +370,7 @@
   7, 18, "ts.silk"
   7, 19, "ts.wine"
 
+  12, 6, "tx.lfog"
 ; Terrain improvements and similar:
 
  12,  7, "tx.farmland"
diff -ruN -Xdiff_ignore freeciv-cvs-Jan-08/doc/HACKING freeciv/doc/HACKING
--- freeciv-cvs-Jan-08/doc/HACKING      2004-01-09 07:16:00.000000000 +0100
+++ freeciv/doc/HACKING 2004-01-09 20:49:33.000000000 +0100
@@ -384,47 +384,61 @@
 be used.
 
 =========================================================================
-Different types of map topology
+Different types of topologies
 =========================================================================
 
+    Historically in FreeCiv the word Topologies was used for 2 different
+thinks, one is the way of the map is placed in memory and indexed; we call
+it Map Indexing (eventually Map Inedxing Topology)
+    The other is related to the way of tiles see the neighbor tiles and 
+paths over the map, this is related to the wrapping of edges; We call it
+Wrapping Topology (or Topology as in math).
+
+see Map Indexing, Wrapping, Wrapping Topology
+    and Cartographicals Projections later
+=========================================================================
+Map Indexing
+=========================================================================
 Originally Freeciv supports only a simple rectangular map.  For instance
 a 5x3 map would be conceptualized as
 
-  <- XXXXX ->
-  <- XXXXX ->
-  <- XXXXX ->
+  - XXXXX -
+  - XXXXX -
+  - XXXXX -
 
 and it looks just like that under "overhead" (non-isometric) view (the
-arrows represent an east-west wrapping).  But under an isometric-view
-client, the same map will look like
+minus represent an east-west simplest wrapping).  But under an 
+isometric-view client, the same map will look like
 
-     X
-    X X
+    \
+   \ X
+  \ X X
    X X X
     X X X
      X X X
-      X X
-       x
+      X X \
+       X \
+        \  
 
 where "north" is to the upper-right and "south" to the lower-left.  This
-makes for a mediocre interface.
+makes for a mediocre interface in this calssic wraping topology.
 
 An isometric-view client will behave better with an isometric map.  This is
 what Civ2, SMAC, Civ3, etc. all use.  A rectangular isometric map can be
 conceptualized as
 
-  <- X X X X X  ->
-  <-  X X X X X ->
-  <- X X X X X  ->
-  <-  X X X X X ->
+  - X X X X X  -
+  -  X X X X X -
+  - X X X X X  -
+  -  X X X X X -
 
 (north is up) and it will look just like that under an isometric-view client.
 Of course under an overhead-view client it will again turn out badly.
 
 Both types of maps can easily wrap in either direction: north-south or
-east-west.  Thus there are four types of wrapping: flat-earth, vertical
-cylinder, horizontal cylinder, and torus.  Traditionally Freeciv only wraps
-in the east-west direction.
+east-west. 
+
+see Wrapping, Wrapping Topology  and Cartographicals Projections later
 
 =========================================================================
 Different coordinate systems
@@ -575,6 +589,283 @@
 map_pos_to_native_x, and map_pos_to_native_y that are defined in map.h.
 
 =========================================================================
+Wrapping (neighbor topologie at edges)
+=========================================================================
+No Wrap Wrapping:
+================
+    The tiles at edge the tiles are no neighbor, this is a topological 
+singularity.
+
+sample map 6x4
+
+  ABCDEF
+  GHIJKL
+  MNOPQR
+  STUVWX
+
+the O tiles as 8 neighbor, the M only 5 and the S tile 3 neighbor. 
+  
+
+Simplest Wrapping:
+=================
+    The tiles at edge the tiles are as neighbor the tiles of 
+the oposites edges. The edges are wrapped 2 at some time.
+
+map 6x4, E-W simplest Wrapping and N and S non wrapping
+(cylinder topology)
+
+f-ABCDEF-a
+l-GHIJKL-g
+r-MNOPQR-m
+x-STUVWX-s
+
+the O tiles as 8  neighbor. The M too: 5 normal neighbor ( G, H, N, T, S)
+and 3 wrapped images ( x, r, l).
+The S tile 5 neighbor: 3 normal (M, N, T) and 2 wrapped images (x, r)
+ ( this is a topological singularity related to the no wrap wrapping)
+
+
+Offset Wrapping:
+===============
+this is a variation of simplest wrapping: which a wrap in the X direction
+is accompanied by a shift in the Y direction: 
+
+r-ABCDEF-m
+x-GHIJKL-s
+f-MNOPQR-a
+l-STUVWX-g
+
+The tile M as 8  neighors: 5 normal neighbor ( G, H, N, T, S)
+and 3 wrapped images ( l, f, x).
+The S tile 5 neighbor: 3 normal (M, N, T) and 2 wrapped images (l, f)
+ ( this is a topological singularity related to the no wrap wrapping)
+
+
+Reversed Wrapping:
+=================
+The tiles at edge the tiles are as neighbor one tiles of 
+the some edges turned 180°. The edges can wrapped 1 at time.
+
+this map i am a reversed wrapping at South edge.
+
+ABCDEF  The tile T as 8 neighors: 5 normal neighbor (S, M, N, O, U)
+GHIJKL  and 3 wrapped images ( v, w, x)
+MNOPQR
+STUVWX  The tile S as 5  neighors: 3 normal neighbor (M, N, T)
+||||||   and 3 wrapped images (w, x) ( this is a topological singularity
+xwvuts  related to the no wrap wrapping)
+rqponm
+
+But: The tile U as neighors in 8 direction but only 6 different: 5 normal
+neighbor (T, N, O, P, V) and and 3 wrapped images (u, v, w), Were u a image
+of itself and v a image of a normal neighbor
+(this is a new topological singularity) we call it a Central Singularity
+                                                     -------------------
+Rem: all images tiles are 180°
+
+this wrapping is complex but this is very intersting see Cartographicals
+Projections.
+
+see Wrapping Topologies and Cartographicals Projections
+
+=========================================================================
+Wrapping Topologies (Topologies make by choice of wrapping)
+=========================================================================
+combining wrapping edges we make different Topologie  where neighors of
+a tiles but path over the map ave different bevaiator
+
+Some this topology is related to a Cartographical projection!
+ (we can make a more or less nice map of Earth)
+List of Cartographicals topologies: 
+----------------------------------
+FLAT(only partial map), Cylinder(classic global maps), Conical (half Earth nice
+map), Quincuncial and Quincuncial_sq (nice gloabal maps)
+see  Cartographicals Projections and Poles
+
+FLAT*:
+=====
+no wrap wrapping
+
+all edges are singularities
+
+Cylinder*:
+=========
+
+simplest Wrap E-W, no wrap N and S or
+simplest Wrap N-S, no wrap E and W
+
+See simplest Wrapping doc and ascii art
+
+the first form is the classic topologie of Civilization (c)
+the second form is a 90° rotated image of the first form
+topologicaly (math) there are the somme.
+
+no-wrap edges are singularities
+
+see cylindrical projections
+
+TORUS:
+=====
+simplest wrap E-W and S-N
+
+x-stuvwx-s
+| |||||| |
+f-ABCDEF-a
+l-GHIJKL-g
+r-MNOPQR-m
+x-STUVWX-s
+| |||||| |
+f-abcdef-a
+
+This is one of more simplest topologies, no singularities
+
+
+Mobius Strip:
+============
+combining a offset wrapping over N-S edge and a simplest wraping
+over E-W edge.
+
+c-defabc-d
+| |||||| | 
+f-ABCDEF-a
+l-GHIJKL-g
+r-MNOPQR-m
+g-STUVWX-s
+| |||||| |
+u-vwxstu-v
+
+this is a interesting topology, no singularities
+
+CONICAL*:
+========
+one reversed wraping over the S edge, no wrap on N,E and W edge
+
+See the reversed wrapping doc and ascii art
+
+this topologie are not actually allowed, E and W use the some type of
+wraping and S and N too in actual freeciv.
+
+interesting to undestand the quincuncial topologie
+
+See the Conical projection doc
+
+QUINCUNCIAL*: 
+============
+simplest wrappin over E-W edge reversed Wrappin in S and N edges
+
+a-fedcba-f
+| |||||| | 
+f-ABCDEF-a
+l-GHIJKL-g
+r-MNOPQR-m
+g-STUVWX-s
+| |||||| |
+s-xwvuts-g
+
+in this topologie there are 4 central singularities in corners and in the
+midle of N and S edges
+
+best sphere like topologie if Xsize=2*Ysize
+See Pierce-Quincuncial Projection doc
+
+QUINCUNCIAL_SQ*:(the best)
+===============
+reversed wrapping on all edges
+
+x-fedcba-s
+| |||||| | 
+s-ABCDEF-x
+m-GHIJKL-r
+g-MNOPQR-l
+a-STUVWX-f
+| |||||| |
+f-xwvuts-a
+
+in this topologie there are 4 central singularities in midle of all edges
+
+completly simetric is the best way to map the Earth on a flat  square map
+best sphere like topologie if Xsize=Ysize
+See Pierce-Quincuncial Projection doc
+
+SPIN:
+====
+reversed wrapping on E, W edges
+
+s-ABCDEF-x
+m-GHIJKL-r
+g-MNOPQR-l
+a-STUVWX-f
+
+in this topologie there are 2 central singularities in midle of reversed
+wrapping edges
+
+=========================================================================
+Cartogrphicals Projections
+=========================================================================
+Cylindrical Projections
+=======================
+http://www.mapleapps.com/categories/data_analysis_stats/maplemaps/html/cylinder1.html
+
+Conical Projection
+==================
+http://www.mapleapps.com/categories/data_analysis_stats/maplemaps/html/images/maps/maps13.gif
+
+Pierce-Quincuncial Projection
+=============================
+http://www.mapleapps.com/categories/data_analysis_stats/maplemaps/html/pierce1.html
+
+see this page too:
+------------------
+http://www.mapleapps.com/categories/data_analysis_stats/maplemaps/html/distortion1.html
+
+=========================================================================
+Poles
+=========================================================================
+mapgen place poles this way
+
+/* ********************************************************************
+ * if clima_choice == 1 ( random choice! if -1)
+ *
+ * TOPO QUINCUNCIAL
+ *  2 half poles at North(the some)  and 2 half poles at South
+ * 
+ *     1     1
+ *
+ *     2     2
+ *
+ * TOPO QUINCUNCIAL_SQ
+ *  One Pole at center North and one at center South
+ * 
+ * if clima_choice != 1 
+ * TOPO QUINCUNCIAL
+ *  1 poles at center North and 1 poles at corners South
+ * TOPO QUINCUNCIAL_SQ
+ *  One Pole at center of map  and  pole one other in 4 corners
+ *
+ * others topologies not see clima_choice value
+ *
+ * TOPO FLAT
+ * one strip pole at north
+ *
+ * TOPO CLASSIC
+ * one strip pole at north and one other at south
+ * 
+ * TOPO Torus
+ *  One Pole at center of map and one other pole in 4 corners
+ *
+ * TOPO MOBIUS (1 pole ) or (2 poles)
+ * (1 pole) some strip poles at North   and  South ( not implemented )
+ *  2 half poles at North(the some)  and 2 half poles at South
+ * 
+ *     1     2
+ *
+ *     2     1
+ *
+ * TOPO ELECTRON (1 pole)
+ * strip pole at center of map
+ * **************************************************************/
+
+=========================================================================
 Unknown tiles and Fog of War
 =========================================================================
 
diff -ruN -Xdiff_ignore freeciv-cvs-Jan-08/server/citytools.c 
freeciv/server/citytools.c
--- freeciv-cvs-Jan-08/server/citytools.c       2003-12-07 07:08:47.000000000 
+0100
+++ freeciv/server/citytools.c  2004-01-09 20:49:33.000000000 +0100
@@ -1917,7 +1917,8 @@
   int map_x, map_y;
   struct tile *ptile;
 
-  if (!city_map_to_map(&map_x, &map_y, pcity, city_x, city_y)) {
+  if (!normal_city_map_to_map(&map_x, &map_y, pcity->x, pcity->y,
+                             city_x, city_y)) {
     return FALSE;
   }
   
diff -ruN -Xdiff_ignore freeciv-cvs-Jan-08/server/gotohand.c 
freeciv/server/gotohand.c
--- freeciv-cvs-Jan-08/server/gotohand.c        2003-10-22 06:59:52.000000000 
+0200
+++ freeciv/server/gotohand.c   2004-01-09 20:49:33.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_full(x, y, x1, y1, dir, dir1, rev_des) {
       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[DIR_REVERSE(dir1)]; 
           move_cost = (ptile->move_cost[dir] + tmp +
                       (ptile->move_cost[dir] > tmp ? 1 : 0))/2;
         }
@@ -333,7 +333,6 @@
         }
        break;
 
-
       case SEA_MOVING:
         move_cost = SINGLE_MOVE;
         move_cost += cost;
@@ -351,7 +350,7 @@
        move_cost = 0; /* silence compiler warning */
        die("Bad/unimplemented move_type in really_generate_warmap().");
       }
-    } adjc_dir_iterate_end;
+    } adjc_dir_iterate_full_end;
   }
 
   freelog(LOG_DEBUG, "Generated warmap for (%d,%d).",
@@ -485,7 +484,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 +628,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_full(x, y, x1, y1, dir, dir1, rev_des) {
       if ((restriction == GOTO_MOVE_CARDINAL_ONLY)
          && !DIR_IS_CARDINAL(dir)) continue;
 
@@ -788,12 +787,13 @@
          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),DIR_REVERSE(dir1));
+                                            
          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), DIR_REVERSE(dir1));
          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 +805,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_full_end;
   }
 
   freelog(LOG_DEBUG, "GOTO: (%d, %d) -> (%d, %d), cost = %d", 
@@ -826,7 +826,7 @@
     if (!get_from_mapqueue(&x, &y))
       break;
 
-    adjc_dir_iterate(x, y, x1, y1, dir) {
+    adjc_dir_iterate_full(x, y, x1, y1, dir, dir1 ,rev_des) {
       if ((restriction == GOTO_MOVE_CARDINAL_ONLY)
          && !DIR_IS_CARDINAL(dir)) continue;
 
@@ -837,12 +837,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 << DIR_REVERSE(dir1) ;
+                                       
        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( DIR_REVERSE(dir1)), x1, y1, x, y);
       }
-    } adjc_dir_iterate_end;
+    } adjc_dir_iterate_full_end;
   }
 
   return TRUE;
diff -ruN -Xdiff_ignore freeciv-cvs-Jan-08/server/mapgen.c 
freeciv/server/mapgen.c
--- freeciv-cvs-Jan-08/server/mapgen.c  2004-01-09 07:16:06.000000000 +0100
+++ freeciv/server/mapgen.c     2004-01-09 20:49:33.000000000 +0100
@@ -36,6 +36,7 @@
 #define hmap(x, y) (height_map[map_pos_to_index(x, y)])
 #define rmap(x, y) (river_map[map_pos_to_index(x, y)])
 
+int map_clima(int map_x, int map_y);
 static void make_huts(int number);
 static void add_specials(int prob);
 static void mapgenerator1(void);
@@ -70,6 +71,119 @@
 /* this is used for generator>1 */
 #define MAP_NCONT 255
 
+/* **********************************************************************
+ * return 0 for the coolest map_x,map_y tile of the map
+ * and 100 for the hotest one, this is proportional to area climatic zones
+ * allow the 9 topology xwrap_type-ywrap_type with the WT_REVERSED,WT_SIMPLEST,
+ * WT_NONE and the 10th topology XRAP=WT_SIMPLEST ,  YWRAP=WT_OFFSET    
+ * see doc/HACKING#Poles                                            [mburda]
+ *************************************************************************/ 
+
+int clima_choice = -1;
+int map_clima(int map_x, int map_y)
+{
+  int nat_x, nat_y, x_2, y_2;
+  double x, y, m;
+
+  /* this determine the way for place the poles  */
+  if (clima_choice == -1) {
+    if ( map.generator == 2 && XWRAP_TYPE_IS(WT_REVERSED)
+        && YWRAP_TYPE_IS(WT_REVERSED)) {
+       clima_choice = 1; /* best to place the big continent */
+    } else {
+       clima_choice = myrand(20)<10 ? 1 : 0;
+    }
+  }
+  normalize_map_pos(&map_x, &map_y);
+  map_to_native_pos(&nat_x, &nat_y, map_x, map_y);
+  assert(nat_x >= 0);
+  assert(nat_y >= 0);
+  assert(nat_x < map.xsize);
+  assert(nat_y < map.ysize);
+  /* is a partial map */
+
+  if (XWRAP_TYPE_IS(WT_NONE) && YWRAP_TYPE_IS(WT_NONE)) {
+    return 100 * nat_y / (map.ysize - 1);
+  }
+
+  /* is a global map, get symeties */
+  x_2 = map.xsize / 2 - 1 + map.xsize % 2;
+  y_2 = map.ysize / 2 - 1 + map.ysize % 2;
+
+  /* poles are not placed in some way in Quincuncial_H and quincunail_V */
+  /* the 2 ways are good ones Quincuncial_H */
+
+  if ((clima_choice == 1) &&
+      (XWRAP_TYPE_IS(WT_SIMPLEST) && YWRAP_TYPE_IS(WT_REVERSED))) {
+    y_2 = map.ysize - 1;
+  }
+
+  if ((clima_choice == 1) &&
+      (XWRAP_TYPE_IS(WT_REVERSED) && YWRAP_TYPE_IS(WT_REVERSED))) {
+    x_2 = map.xsize - 1;
+  }
+
+  /* poles are not placed in some way in Quincuncial_H and quincunail_V */
+  /* the 2 ways are good ones */
+  if (nat_x > x_2) {
+    nat_x = map.xsize - 1 - nat_x;
+  }
+  if (nat_y > y_2) {
+    nat_y = map.ysize - 1 - nat_y;
+  }
+  x = (double) nat_x / (double) x_2;
+  y = (double) nat_y / (double) y_2;
+  if ((XWRAP_TYPE_IS(WT_SIMPLEST) && YWRAP_TYPE_IS(WT_NONE))) {
+    return 100 * y;
+  }
+  if ((XWRAP_TYPE_IS(WT_REVERSED) && YWRAP_TYPE_IS(WT_NONE))) {
+    return 100 - 100 * y;
+  }
+  if (XWRAP_TYPE_IS(WT_NONE) && YWRAP_TYPE_IS(WT_SIMPLEST)) {
+    return 100 * x;
+  }
+  if (XWRAP_TYPE_IS(WT_NONE) && YWRAP_TYPE_IS(WT_REVERSED)) {
+    return 100 - 100 * x;
+  }
+
+  if ((XWRAP_TYPE_IS(WT_SIMPLEST) && YWRAP_TYPE_IS(WT_SIMPLEST))
+      || (XWRAP_TYPE_IS(WT_REVERSED) && YWRAP_TYPE_IS(WT_REVERSED)
+         && clima_choice != 1)
+      || (XWRAP_TYPE_IS(WT_SIMPLEST) && YWRAP_TYPE_IS(WT_REVERSED)
+         && clima_choice == 1)) {
+
+    if (x + y > 1) {
+      x = 1 - x;
+      y = 1 - y;
+    }
+    return 150 * (x * x * y + x * y * y) - 50 * (x * x * x + y * y * y) +
+       150 * (x * x + y * y);
+
+  }
+  if (((XWRAP_TYPE_IS(WT_SIMPLEST) && YWRAP_TYPE_IS(WT_OFFSET))
+       || ((XWRAP_TYPE_IS(WT_REVERSED) && YWRAP_TYPE_IS(WT_REVERSED)
+           && clima_choice == 1))
+       || ((XWRAP_TYPE_IS(WT_SIMPLEST) && YWRAP_TYPE_IS(WT_REVERSED)
+           && clima_choice != 1)))) {
+    x = x > 0.5 ? 2 * x - 1 : 1 - 2 * x;
+  } else {
+    y = y > 0.5 ? 2 * y - 1 : 1 - 2 * y;
+  }
+  m = MAX(x, y);
+  return 75 * (x * x + y * y) * (1 - m) + 100 * m * m * m;
+}
+
+static void clean_singularities(void)
+{
+  whole_map_iterate(x, y) {
+    if (!is_ocean(map_get_terrain(x, y))
+       && map_get_terrain(x, y) != T_ARCTIC)
+      if (near_singularity(x, y)) {
+       map_set_terrain(x, y, T_OCEAN);
+       map_set_continent(x, y, 0);
+      }
+  } whole_map_iterate_end;
+}
 /**************************************************************************
   make_mountains() will convert all squares that are higher than thill to
   mountains and hills. Notice that thill will be adjusted according to
@@ -105,48 +219,37 @@
 
 /**************************************************************************
  add arctic and tundra squares in the arctic zone. 
- (that is the top 10%, and low 10% of the map)
+ (that is the coolest 10% of the map)
+ if make_polar(TRUE) we add some tundra
 **************************************************************************/
-static void make_polar(void)
+static void make_polar(bool addtundra)
 {
-  int y,x;
+  int T;
+  struct tile *ptile;
 
-  for (y=0;y<map.ysize/10;y++) {
-    for (x=0;x<map.xsize;x++) {
-      if ((hmap(x, y)+(map.ysize/10-y*25)>myrand(maxval) &&
-          map_get_terrain(x,y)==T_GRASSLAND) || y==0) { 
-       if (y<2)
-         map_set_terrain(x, y, T_ARCTIC);
-       else
-         map_set_terrain(x, y, T_TUNDRA);
-         
-      } 
-    }
-  }
-  for (y=map.ysize*9/10;y<map.ysize;y++) {
-    for (x=0;x<map.xsize;x++) {
-      if ((hmap(x, y)+(map.ysize/10-(map.ysize-y)*25)>myrand(maxval) &&
-          map_get_terrain(x, y)==T_GRASSLAND) || y==map.ysize-1) {
-       if (y>map.ysize-3)
-         map_set_terrain(x, y, T_ARCTIC);
-       else
-         map_set_terrain(x, y, T_TUNDRA);
+  whole_map_iterate(map_x, map_y) {
+    T = map_clima(map_x, map_y);       /* temperature parameter */
+    ptile = map_get_tile(map_x, map_y);
+    if (T < 5) {               /* get the 10% coolest part of the map */
+      ptile->terrain = T_ARCTIC;
+    } else if (T <= 8) {
+      if (ptile->terrain == T_OCEAN) {
+       ptile->terrain = T_ARCTIC;
+      } else {
+       ptile->terrain = T_TUNDRA;
+      }
+    } else if (T <= 10) {
+      if (ptile->terrain == T_OCEAN) {
+       if (myrand(10) > 5) {
+           ptile->terrain = T_ARCTIC;
+       } else if (addtundra && myrand(10) > 4) {
+         ptile->terrain = T_TUNDRA;
+       }
+      } else if ( myrand(10) > 5) {
+       ptile->terrain = T_TUNDRA;
       }
     }
-  }
-
-  /* only arctic and tundra allowed at the poles (first and last two lines,
-     as defined in make_passable() ), to be consistent with generator>1. 
-     turn every land tile on the second lines that is not arctic into tundra,
-     since the first lines has already been set to all arctic above. */
-  for (x=0;x<map.xsize;x++) {
-    if (map_get_terrain(x, 1)!=T_ARCTIC &&
-       !is_ocean(map_get_terrain(x, 1)))
-      map_set_terrain(x, 1, T_TUNDRA);
-    if (map_get_terrain(x, map.ysize-2)!=T_ARCTIC && 
-       !is_ocean(map_get_terrain(x, map.ysize-2)))
-      map_set_terrain(x, map.ysize-2, T_TUNDRA);
-  }
+  } whole_map_iterate_end;
 }
 
 /**************************************************************************
@@ -543,7 +646,9 @@
 
     /* Test if the river is done. */
     if (adjacent_river_tiles4(x, y) != 0||
-       adjacent_ocean_tiles4(x, y) != 0) {
+       adjacent_ocean_tiles4(x, y) != 0||
+        (map_get_terrain(x, y) == T_ARCTIC 
+        && map_clima(x, y) < 8)) { /*rivers end at poles */
       freelog(LOG_DEBUG,
              "The river ended at (%d, %d).\n", x, y);
       return TRUE;
@@ -658,11 +763,11 @@
      * river code was written when map.riverlength had a maximum value of 
      * 1000 rather than the current 100 */
     10 *
-    /* The size of the map (poles don't count). */
-    (map_num_tiles() - 2 * map.xsize) *
-    /* Rivers need to be on land only. */
-    map.landpercent /
-    /* Adjustment value. Tested by me. Gives no rivers with 'set
+     /* The size of the map (poles don't count). */
+     (map_num_tiles() * 0.9 ) *
+     /* Rivers need to be on land only. */
+     map.landpercent /
+     /* Adjustment value. Tested by me. Gives no rivers with 'set
        rivers 0', gives a reasonable amount of rivers with default
        settings and as many rivers as possible with 'set rivers 100'. */
     0xD000; /* (= 53248 in decimal) */
@@ -686,7 +791,7 @@
     /* Don't start any rivers at the poles. */
     do {
       rand_map_pos(&x, &y);
-    } while (y == 0 || y == map.ysize-1);
+    } while (map_clima(x, y) < 9);
 
     /* Check if it is suitable to start a river on the current tile.
      */
@@ -858,16 +963,17 @@
       tres*=9;
     tres/=10;
   } while (abs(total-count)> maxval/40);
-  if (map.separatepoles && has_poles) {
-    make_passable();
-  }
+  
   make_mountains(maxval*8/10);
   make_forests();
   make_swamps();
   make_deserts();
   make_plains();
   if (has_poles) {
-    make_polar();
+    make_polar(FALSE);
+  }
+  if (map.separatepoles && has_poles) {
+    make_passable();
   }
   make_fair();
   make_rivers();
@@ -927,6 +1033,88 @@
 }
 
 /**************************************************************************
+ Assign continent numbers to Poles in gen 2,3 or 4. and clean its!
+ (poles are separates island)
+ Numbers 1 and 2 are reserved for polar continents if
+ map.generator != 0; otherwise are not special.
+ Also sets map.num_continents (note 0 is ocean)
+ See the doc/HACKING#Poles
+**************************************************************************/
+void assign_poles_numbers(void)
+{
+ /* Default poles, cylinder topology */
+  int x1 = 0,             y1 = 0,
+      x2 = map.ysize - 1, y2 = map.ysize - 1;
+
+  map.num_continents= 2;
+  
+  /* FLAT TOPOLOGIE */
+  if(XWRAP_TYPE_IS(WT_NONE) && YWRAP_TYPE_IS(WT_NONE)) {    
+    map.num_continents= 1;
+  }
+
+  if (XWRAP_TYPE_IS(WT_REVERSED) && YWRAP_TYPE_IS(WT_REVERSED)) {
+    /* QUINCUNCIAL_SQ TOPOLOGY */
+    if (clima_choice == 1) {
+      x1 = map.xsize / 2;
+      x2 = x1;
+    } else {
+      x2 = map.xsize / 2;
+      y2 = map.ysize / 2;
+    }
+  } else if (XWRAP_TYPE_IS(WT_REVERSED) ||  YWRAP_TYPE_IS(WT_REVERSED)) {
+    /* Spin topologies */
+    x1 = map.xsize / 2;
+    y1 = map.ysize / 2;
+    map.num_continents= 1;
+  }
+
+ if (XWRAP_TYPE_IS(WT_SIMPLEST)  && YWRAP_TYPE_IS(WT_OFFSET)) {
+    /* Mobius Topology*/
+    x1 = map.xsize / 4;
+    y1 = 0;
+    x2 = x1;
+    y2 = map.ysize - 1;
+  }
+
+  /* QUINCUNCIAL (horizontal) topology */
+ if (XWRAP_TYPE_IS(WT_SIMPLEST) && YWRAP_TYPE_IS(WT_REVERSED)) {
+    if (clima_choice == 1) {
+      x1 = map.xsize / 4;
+      y1 = 0;
+      x2 = x1;
+      y2 = map.ysize - 1;
+    } else {
+      x1 = map.xsize / 2;
+      y1 = 0;
+      x2 = 0;
+      y2 = map.ysize - 1;
+    }
+    map.num_continents = 2;
+  }
+
+ if (XWRAP_TYPE_IS(WT_SIMPLEST) && YWRAP_TYPE_IS(WT_SIMPLEST)) {
+  /* TORUS TOPOLOGY */
+  x2 = map.xsize / 2;
+  y2 = map.ysize / 2;
+ }
+
+/* set the poles */
+  if (map.generator != 0 && has_poles) {
+    assign_continent_flood(x1, y1, 1);
+    if (map.num_continents == 2) {
+      assign_continent_flood(x2, y2, 2);
+    }
+  }
+
+/* clean no in poles continent island */
+  whole_map_iterate(x, y) {
+    if (map_get_continent(x, y) == 0 && !is_ocean(map_get_terrain(x, y))) {
+      map_set_terrain(x, y, T_OCEAN);
+    }
+  } whole_map_iterate_end;
+}
+/**************************************************************************
  Assign continent numbers to all tiles.
  Numbers 1 and 2 are reserved for polar continents if
  map.generator != 0; otherwise are not special.
@@ -1166,7 +1354,8 @@
    * needs to control the temperature gradient between "poles" and
    * "equator"; e.g., if there are no poles desert and tundra should be
    * equally likely at either end. */
-  has_poles = !topo_has_flag(TF_WRAPY);
+  /* map_clima is a fix of it [mburda] */
+  has_poles = TRUE;
 
   /* don't generate tiles with mapgen==0 as we've loaded them from file */
   /* also, don't delete (the handcrafted!) tiny islands in a scenario */
@@ -1188,6 +1377,7 @@
     if (!map.tinyisles) {
       remove_tiny_islands();
     }
+    clean_singularities();
   }
 
   if(!map.have_specials) /* some scenarios already provide specials */
@@ -1238,6 +1428,9 @@
 static void adjust_map(int minval)
 {
   whole_map_iterate(x, y) {
+    if(near_singularity(x, y)) {
+      hmap(x, y) = 0;
+    }
     hmap(x, y) -= minval;
   } whole_map_iterate_end;
 }
@@ -1248,6 +1441,7 @@
 static void mapgenerator1(void)
 {
   int i;
+  int map_x, map_y;
   int minval=5000000;
   height_map=fc_malloc (sizeof(int)*map.xsize*map.ysize);
 
@@ -1259,12 +1453,16 @@
     int x, y;
 
     rand_map_pos(&x, &y);
-    hmap(x, y) += myrand(5000);
+    native_to_map_pos(&map_x, &map_y, x, y);
+    if(near_singularity(map_x, map_y)) { /* avoid land in singularities */
+      hmap(x, y) -= myrand(5000);
+    } else if (map_clima(map_x, map_y) > 6) { /* avoid height land at poles */
+      hmap(x, y) += myrand(5000);
+    }
     if ((i % 100) == 0) {
       smooth_map(); 
     }
   }
-
   smooth_map(); 
   smooth_map(); 
   smooth_map(); 
@@ -1276,7 +1474,7 @@
       minval = hmap(x, y);
   } whole_map_iterate_end;
 
-  maxval-=minval;
+  maxval -= minval;
   adjust_map(minval);
 
   make_land();
@@ -1382,7 +1580,7 @@
 };
 
 static bool is_cold(int x, int y){
-  return ( y * 5 < map.ysize || y * 5 > map.ysize * 4 );
+    return ( map_clima(x, y) <= 20 );
 }
 
 /**************************************************************************
@@ -1442,7 +1640,7 @@
 
   while (i > 0 && (failsafe--) > 0) {
     get_random_map_position_from_state(&x, &y, pstate);
-
+ 
     if (map_get_continent(x, y) == pstate->isleindex &&
        map_get_terrain(x, y) == T_GRASSLAND) {
 
@@ -1602,8 +1800,9 @@
   i = islemass - 1;
   while (i > 0 && tries-->0) {
     get_random_map_position_from_state(&x, &y, pstate);
-    if (hmap(x, y) == 0 && (hmap(x + 1, y) != 0 || hmap(x - 1, y) != 0 ||
-                           hmap(x, y + 1) != 0 || hmap(x, y - 1) != 0)) {
+    if ((!near_singularity(x, y) || myrand(50) < 25 ) && hmap(x, y) == 0
+       && (hmap(x + 1, y) != 0 || hmap(x - 1, y) != 0
+           || hmap(x, y + 1) != 0 || hmap(x, y - 1) != 0)) {
       hmap(x, y) = 1;
       i--;
       if (y >= pstate->s - 1 && pstate->s < map.ysize - 2) pstate->s++;
@@ -1784,24 +1983,10 @@
       map_clear_all_specials(x, y);
       map_set_owner(x, y, NULL);
     }
+
   if (has_poles) {
-    for (x = 0; x < map.xsize; x++) {
-      map_set_terrain(x, 0, myrand(9) > 0 ? T_ARCTIC : T_TUNDRA);
-      map_set_continent(x, 0, 1);
-      if (myrand(9) == 0) {
-       map_set_terrain(x, 1, myrand(9) > 0 ? T_TUNDRA : T_ARCTIC);
-       map_set_continent(x, 1, 1);
-      }
-      map_set_terrain(x, map.ysize - 1,
-                     myrand(9) > 0 ? T_ARCTIC : T_TUNDRA);
-      map_set_continent(x, map.ysize - 1, 2);
-      if (myrand(9) == 0) {
-       map_set_terrain(x, map.ysize - 2,
-                       myrand(9) > 0 ? T_TUNDRA : T_ARCTIC);
-       map_set_continent(x, map.ysize - 2, 2);
-      }
-    }
-    map.num_continents = 2;
+    make_polar(TRUE);
+    assign_poles_numbers();
   } else {
     map.num_continents = 0;
   }
@@ -2079,26 +2264,29 @@
 
   /* set midpoints of sides to avg of side's vertices plus a random factor */
   /* unset points are zero, don't reset if set */
-  if (hmap((x0 + x1)/2, y0) == 0) {
-    hmap((x0 + x1)/2, y0) = (val[0][0] + val[1][0])/2 + myrand(step) - step/2;
-  }
-  if (hmap((x0 + x1)/2, y1wrap) == 0) {
-    hmap((x0 + x1)/2, y1wrap) = (val[0][1] + val[1][1])/2 
-      + myrand(step)- step/2;
-  }
-  if (hmap(x0, (y0 + y1)/2) == 0) {
-    hmap(x0, (y0 + y1)/2) = (val[0][0] + val[0][1])/2 + myrand(step) - step/2;
-  }
-  if (hmap(x1wrap, (y0 + y1)/2) == 0) {
-    hmap(x1wrap, (y0 + y1)/2) = (val[1][0] + val[1][1])/2 
-      + myrand(step) - step/2;
-  }
+#define set_midpoints(X,Y,V)                                                \
+  { int map_x, map_y;                                                       \
+    native_to_map_pos(&map_x, &map_y, (X), (Y));                            \
+    if( !near_singularity( map_x, map_y) && hmap((X), (Y)) == 0 ) {         \
+      hmap((X), (Y)) = V;                                                   \
+  } }
 
+  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 */
-  if (hmap((x0 + x1)/2, (y0 + y1)/2) == 0) {
-    hmap((x0 + x1)/2, (y0 + y1)/2) = (val[0][0] + val[0][1] + val[1][0] 
-                                     + val[1][1])/4 + myrand(step) - step/2;
-  }
+  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);
 
   /* now call recursively on the four subrectangles */
   gen5rec(2 * step / 3, x0, y0, (x1 + x0) / 2, (y1 + y0) / 2);
@@ -2118,8 +2306,8 @@
 **************************************************************************/
 static void mapgenerator5(void)
 {
-  const bool xnowrap = !topo_has_flag(TF_WRAPX);
-  const bool ynowrap = !topo_has_flag(TF_WRAPY);
+  const bool xnowrap = XWRAP_TYPE_IS(WT_NONE);
+  const bool ynowrap = YWRAP_TYPE_IS(WT_NONE);
 
   /* 
    * How many blocks should the x and y directions be divided into
@@ -2134,6 +2322,9 @@
   int xmax = map.xsize - (xnowrap ? 1 : 0);
   int ymax = map.ysize - (ynowrap ? 1 : 0);
   int x, y, minval;
+  int map_x, map_y;
+  int T=0;
+
   /* just need something > log(max(xsize, ysize)) for the recursion */
   int step = map.xsize + map.ysize; 
   /* edges are avoided more strongly as this increases */
@@ -2149,34 +2340,22 @@
   /* set initial points */
   for (x = 0; x < xdiv2; x++) {
     for (y = 0; y < ydiv2; y++) {
-      hmap(x * xmax / xdiv, y * ymax / ydiv) =  myrand(2*step) - (2*step)/2;
-    }
-  }
-
-  /* if we aren't wrapping stay away from edges to some extent, try
-     even harder to avoid the edges naturally if separatepoles is true */
-  if (xnowrap) {
-    for (y = 0; y < ydiv2; y++) {
-      hmap(0, y * ymax / ydiv) -= avoidedge;
-      hmap(xmax, y * ymax / ydiv) -= avoidedge;
-      if (map.separatepoles && has_poles) {
-       hmap(2, y * ymax / ydiv) = hmap(0, y * ymax / ydiv) 
-                                                       - myrand(3*avoidedge);
-       hmap(xmax - 2, y * ymax / ydiv) 
-                         = hmap(xmax, y * ymax / ydiv) - myrand(3*avoidedge);
-      }
-    }
-  }
-
-  if (ynowrap) {
-    for (x = 0; x < xdiv2; x++) {
-      hmap(x * xmax / xdiv, 0) -= avoidedge;
-      hmap(x * xmax / xdiv, ymax) -= avoidedge;
-      if (map.separatepoles && has_poles) {
-       hmap(x * xmax / xdiv, 2) = hmap(x * xmax / xdiv, 0) 
-                                                       - myrand(3*avoidedge);
-       hmap(x * xmax / xdiv, ymax - 2) 
-                         = hmap(x * xmax / xdiv, ymax) - myrand(3*avoidedge);
+      native_to_map_pos(&map_x, &map_y, (x * xmax / xdiv), (y * ymax / ydiv));
+      
+     /* set initial points */
+      hmap(x * xmax / xdiv, y * ymax / ydiv) =  myrand(2*step) - (2*step)/2;/* 
set initial points */
+      
+      /* avoid edges (simplest topologicals singularities), and central 
simetries singularities */
+      if (near_singularity(map_x,map_y))
+         hmap(x * xmax / xdiv, y * ymax / ydiv) -= avoidedge;
+
+      if ( has_poles ) {
+       T = map_clima(map_x,map_y);
+       if (T <= 8) {
+           hmap(x * xmax / xdiv, y * ymax / ydiv) -= myrand(avoidedge); /* 
avoid too higth poles */ 
+       } else if (map.separatepoles && T <= 11 ) {
+           hmap(x * xmax / xdiv, y * ymax / ydiv) -= myrand(3*avoidedge); /* 
separate poles */
+       }
       }
     }
   }
diff -ruN -Xdiff_ignore freeciv-cvs-Jan-08/server/mapgen.h 
freeciv/server/mapgen.h
--- freeciv-cvs-Jan-08/server/mapgen.h  2003-08-29 07:08:58.000000000 +0200
+++ freeciv/server/mapgen.h     2004-01-09 20:49:33.000000000 +0100
@@ -16,5 +16,6 @@
 void assign_continent_numbers(void);
 void map_fractal_generate(void);
 void create_start_positions(void);
+void assign_poles_numbers(void);
 
 #endif  /* FC__MAPGEN_H */
diff -ruN -Xdiff_ignore freeciv-cvs-Jan-08/server/sanitycheck.c 
freeciv/server/sanitycheck.c
--- freeciv-cvs-Jan-08/server/sanitycheck.c     2003-11-20 07:02:30.000000000 
+0100
+++ freeciv/server/sanitycheck.c        2004-01-09 20:49:33.000000000 +0100
@@ -153,7 +153,7 @@
   city_map_iterate(x, y) {
     int map_x, map_y;
 
-    if (city_map_to_map(&map_x, &map_y, pcity, x, y)) {
+    if (normal_city_map_to_map(&map_x, &map_y, pcity->x, pcity->y, x, y)) {
       struct tile *ptile = map_get_tile(map_x, map_y);
       struct player *owner = map_get_owner(map_x, map_y);
 
diff -ruN -Xdiff_ignore freeciv-cvs-Jan-08/server/savegame.c 
freeciv/server/savegame.c
--- freeciv-cvs-Jan-08/server/savegame.c        2003-12-07 07:08:48.000000000 
+0100
+++ freeciv/server/savegame.c   2004-01-09 20:49:33.000000000 +0100
@@ -322,14 +322,14 @@
 ***************************************************************/
 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");
 
   /* In some cases we read these before, but not always, and
    * its safe to read them again:
    */
+  map.size = -1;
   map.xsize=secfile_lookup_int(file, "map.width");
   map.ysize=secfile_lookup_int(file, "map.height");
 
@@ -1531,7 +1531,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 -ruN -Xdiff_ignore freeciv-cvs-Jan-08/server/stdinhand.c 
freeciv/server/stdinhand.c
--- freeciv-cvs-Jan-08/server/stdinhand.c       2004-01-09 07:16:07.000000000 
+0100
+++ freeciv/server/stdinhand.c  2004-01-10 15:18:48.000000000 +0100
@@ -222,24 +222,55 @@
 
   /* These should be grouped by sclass */
   
-/* Map size parameters: adjustable if we don't yet have a map */  
+/* Map size parameters: adjustable if we don't yet have a map */
+   GEN_INT("size", map.size, SSET_MAP_SIZE, SSET_TO_CLIENT,
+         N_("Map size in (2,000 tiles) units"),
+         N_("This value is used to determine xsize and ysize if > 0  \n"
+             " size = 0 xsize and ysize can set by hand, never use it!\n"
+             " size = 2 is a litle map of  4,000 tiles (default)\n"
+             " size = 10 is a Huge map of 20,000 tiles"), NULL,
+         MAP_MIN_SIZE,MAP_MAX_SIZE , MAP_DEFAULT_SIZE)
+
+   GEN_INT("ratio", map.ratio, SSET_MAP_SIZE, SSET_TO_CLIENT,
+         N_("Map ratio in (xratio:yratio) form"),
+         N_("This value is used to determine xsize and ysize \n"
+            "use 100 all the time!\n"
+            " 11 is 1:1 ratio, 21 is a 2:1 ratio. \n"
+            " 100 is the default ratio determined by the topology"), NULL,
+         MAP_MIN_RATIO, MAP_MAX_RATIO , MAP_DEFAULT_RATIO)
+    
+/*Map size parameters: adjustable if we don't yet have a map and map.size=-1*/
   GEN_INT("xsize", map.xsize, SSET_MAP_SIZE, SSET_TO_CLIENT,
-         N_("Map width in squares"), "", NULL,
+         N_("Map width in squares"),
+         N_("This value is modified when setting topology_id,ratio or size\n"
+             "use size instead it!"), NULL,
          MAP_MIN_WIDTH, MAP_MAX_WIDTH, MAP_DEFAULT_WIDTH)
     
   GEN_INT("ysize", map.ysize, SSET_MAP_SIZE, SSET_TO_CLIENT,
-         N_("Map height in squares"), "", NULL,
+         N_("Map height in squares"),
+         N_("This value is modified when setting topology_id,ratio or size\n"
+             "use size instead it!"), NULL,
          MAP_MIN_HEIGHT, MAP_MAX_HEIGHT, MAP_DEFAULT_HEIGHT)
 
   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  (+16=Isometric map) : Name ( Wraps )      Notes \n"
+            "  Cartographic topologies:\n"
+        "  0 (16) : Flat Map         (unwrapped)            Partial map\n"
+            "  1 (17) : Cylindrical Earth(wraps E-W)            "
+                                               "Classic Civ2 global map\n"
+            "  2 (18) : Spherical Earth  (wraps E-E N-N W-W S-S)"
+                              "Best global map\n"
+            "  ScFi topologies:\n"     
+            "  3 (19) : Donut World      (wraps N-S, E-W)\n"
+            "  4 (20) : Mobius Strip     (wrap E-W, offset wrap N-S)\n"
+            "  5 (21) : Cyl. electron    (wraps E-E W-W)\n"
+            "  Variants for developpers usage only \n"
+            "  6 : TF_QUINCUNCIAL "
           ), NULL, 
          MAP_MIN_TOPO, MAP_MAX_TOPO, MAP_DEFAULT_TOPO)
 
@@ -3167,6 +3198,8 @@
   }
 
   if (do_update) {
+    /* update the topology parameters */
+    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]