Complete.Org: Mailing Lists: Archives: freeciv-dev: September 2005:
[Freeciv-Dev] (PR#13982) small map wrap around problems
Home

[Freeciv-Dev] (PR#13982) small map wrap around problems

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
To: chrisk@xxxxxxxxx
Subject: [Freeciv-Dev] (PR#13982) small map wrap around problems
From: "Jason Short" <jdorje@xxxxxxxxxxxxxxxxxxxxx>
Date: Thu, 29 Sep 2005 14:59:32 -0700
Reply-to: bugs@xxxxxxxxxxx

<URL: http://bugs.freeciv.org/Ticket/Display.html?id=13982 >

Here is a preliminary patch - it will work if the mapview and map align.
 This is the beginning of my Solution To All Mapview Wrapping Problems
patch which should also address various speed problems.

-jason

Index: client/mapview_common.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/mapview_common.c,v
retrieving revision 1.246
diff -p -u -r1.246 mapview_common.c
--- client/mapview_common.c     26 Sep 2005 22:34:47 -0000      1.246
+++ client/mapview_common.c     29 Sep 2005 21:58:28 -0000
@@ -499,15 +499,15 @@ static void base_set_mapview_origin(int 
 
     if (update_y1 > update_y0) {
       update_map_canvas(0, update_y0 - gui_y0,
-                       width, update_y1 - update_y0);
+                       width, update_y1 - update_y0, FALSE);
     }
     if (update_x1 > update_x0) {
       update_map_canvas(update_x0 - gui_x0, common_y0 - gui_y0,
-                       update_x1 - update_x0, common_y1 - common_y0);
+                       update_x1 - update_x0, common_y1 - common_y0, FALSE);
     }
   } else {
     dirty_all();
-    update_map_canvas(0, 0, mapview.store_width, mapview.store_height);
+    update_map_canvas(0, 0, mapview.store_width, mapview.store_height, FALSE);
   }
 
   center_tile_overviewcanvas();
@@ -1066,6 +1066,87 @@ static void put_one_tile(struct canvas *
   }
 }
 
+/****************************************************************************
+  This function copies areas of the mapview onto other areas to account
+  for wrapping.  E.g., if you update a certain area of the mapview, call
+  this function and it will copy the just-updated area onto any other
+  visible spot to account for duplicate tiles.
+****************************************************************************/
+static void copy_mapview_for_wrap(int canvas_x, int canvas_y,
+                                 int width, int height)
+{
+  /* FIXME: this function is colossaly overcomplicated. */
+  /* Canvas-coordinate vectors for a 1-map wrap in the X or Y directions. */
+  int xwrap_x, xwrap_y, ywrap_x, ywrap_y;
+  int i, j;
+  const bool tileset_is_iso = tileset_is_isometric(tileset);
+  const int W = tileset_tile_width(tileset), H = tileset_tile_height(tileset);
+
+  freelog(LOG_DEBUG, "Handling wrap - %d,%d x %d,%d.",
+         canvas_x, canvas_y, width, height);
+
+  if (MAP_IS_ISOMETRIC) {
+    if (tileset_is_iso) {
+      xwrap_x = map.xsize * W * 2;
+      ywrap_y = map.ysize * H;
+      xwrap_y = ywrap_x = 0; /* Wrapping is orthogonal */
+    } else {
+      /* TODO */
+      assert(0);
+    }
+  } else {
+    if (tileset_is_iso) {
+      /* TODO */
+      assert(0);
+    } else {
+      xwrap_x = map.xsize * W;
+      ywrap_y = map.ysize * H;
+      xwrap_y = ywrap_x = 0; /* Wrapping is orthogonal */
+    }
+  }
+
+  for (i = 0; ; i++) {
+    int xworking = 0;
+    for (j = 0; ; j++) {
+      int yworking = 0, k;
+
+      for (k = 0; k < 4; k++) {
+       if ((i == 0 && (k & 2))
+           || (j == 0 && (k & 1))
+           || (i > 0 && !topo_has_flag(TF_WRAPX))
+           || (j > 0 && !topo_has_flag(TF_WRAPY))) {
+         /* Nothing. */
+       } else {
+         const int mx = 1 - 2 * ((k & 2) != 0), my = 1 - 2 * ((k & 1) != 0);
+         int canvas_x2 = canvas_x + mx * i * xwrap_x + my * j * ywrap_x;
+         int canvas_y2 = canvas_y + mx * i * xwrap_y + my * j * ywrap_y;
+
+         freelog(LOG_DEBUG, "  Copying %d,%d - %d,%d",
+                 mx * i, my * j, canvas_x2, canvas_y2);
+         if (canvas_x2 < mapview.store_width 
+             && canvas_x2 + width > 0
+             && canvas_y2 < mapview.store_height
+             && canvas_y2 + height > 0) {
+           freelog(LOG_DEBUG, "    COPYING!");
+           canvas_copy(mapview.store, mapview.tmp_store,
+                       canvas_x, canvas_y, canvas_x2, canvas_y2,
+                       width, height);
+           dirty_rect(canvas_x2, canvas_y2, width, height);
+           xworking++;
+           yworking++;
+         }
+       }
+      }
+      if (yworking == 0) {
+       break;
+      }
+    }
+    if (xworking == 0) {
+      break;
+    }
+  }
+}
+
 /**************************************************************************
   Update (refresh) the map canvas starting at the given tile (in map
   coordinates) and with the given dimensions (also in map coordinates).
@@ -1081,7 +1162,8 @@ static void put_one_tile(struct canvas *
   x, y, width, and height are in map coordinates; they need not be
   normalized or even real.
 **************************************************************************/
-void update_map_canvas(int canvas_x, int canvas_y, int width, int height)
+void update_map_canvas(int canvas_x, int canvas_y, int width, int height,
+                      bool handle_wrapping)
 {
   int gui_x0, gui_y0;
   bool full;
@@ -1174,11 +1256,16 @@ void update_map_canvas(int canvas_x, int
     mapview.tmp_store = tmp;
 
     /* And copy store to tmp_store. */
-    canvas_copy(mapview.store, mapview.tmp_store,
-               canvas_x, canvas_y, canvas_x, canvas_y, width, height);
+    if (handle_wrapping) {
+      copy_mapview_for_wrap(canvas_x, canvas_y, width, height);
+    } else {
+      canvas_copy(mapview.store, mapview.tmp_store,
+                 canvas_x, canvas_y, canvas_x, canvas_y, width, height);
+      dirty_rect(canvas_x, canvas_y, width, height);
+    }
+  } else {
+    dirty_all();
   }
-
-  dirty_rect(canvas_x, canvas_y, width, height);
 }
 
 /**************************************************************************
@@ -2066,7 +2153,7 @@ void unqueue_mapview_updates(bool write_
        || (needed_updates & UPDATE_CITY_DESCRIPTIONS)) {
       dirty_all();
       update_map_canvas(0, 0, mapview.store_width,
-                       mapview.store_height);
+                       mapview.store_height, FALSE);
       /* Have to update the overview too, since some tiles may have changed. */
       refresh_overview_canvas();
     } else {
@@ -2103,7 +2190,7 @@ void unqueue_mapview_updates(bool write_
       }
 
       if (min_x < max_x && min_y < max_y) {
-       update_map_canvas(min_x, min_y, max_x - min_x, max_y - min_y);
+       update_map_canvas(min_x, min_y, max_x - min_x, max_y - min_y, TRUE);
       }
     }
   }
Index: client/mapview_common.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/mapview_common.h,v
retrieving revision 1.113
diff -p -u -r1.113 mapview_common.h
--- client/mapview_common.h     11 May 2005 20:54:30 -0000      1.113
+++ client/mapview_common.h     29 Sep 2005 21:58:30 -0000
@@ -261,7 +261,8 @@ void put_one_element(struct canvas *pcan
                     int canvas_x, int canvas_y,
                     const struct city *citymode);
 
-void update_map_canvas(int canvas_x, int canvas_y, int width, int height);
+void update_map_canvas(int canvas_x, int canvas_y, int width, int height,
+                      bool handle_wrap);
 void update_map_canvas_visible(void);
 void update_city_description(struct city *pcity);
 
Index: utility/shared.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/utility/shared.h,v
retrieving revision 1.146
diff -p -u -r1.146 shared.h
--- utility/shared.h    12 Jul 2005 23:57:53 -0000      1.146
+++ utility/shared.h    29 Sep 2005 21:58:31 -0000
@@ -88,6 +88,7 @@ typedef unsigned int fc_bool;
 
 #define BOOL_VAL(x) ((x) != 0)
 #define XOR(p, q) (!(p) != !(q))
+#define EQ(p, q) (!(p) == !(q))
 
 /*
  * DIVIDE() divides and rounds down, rather than just divides and

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