Complete.Org: Mailing Lists: Archives: freeciv-dev: December 2004:
[Freeciv-Dev] (PR#8998) Small map meets large screen, they have problems
Home

[Freeciv-Dev] (PR#8998) Small map meets large screen, they have problems

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
To: vasc@xxxxxxxxxxxxxx
Subject: [Freeciv-Dev] (PR#8998) Small map meets large screen, they have problems together.
From: "Jason Short" <jdorje@xxxxxxxxxxxxxxxxxxxxx>
Date: Sat, 4 Dec 2004 01:08:28 -0800
Reply-to: rt@xxxxxxxxxxx

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

I believe this patch should fix the problem.  I've tested it, but only a
little bit.  It would be nice if someone could give it a heavy workout
with big mapview/small maps and lots of different topologies/views.

What should happen now is that when the mapview is made large than the
map, drawing will work but will become very slow.

-jason

Index: client/mapview_common.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/mapview_common.c,v
retrieving revision 1.151.2.10
diff -u -r1.151.2.10 mapview_common.c
--- client/mapview_common.c     1 Dec 2004 22:51:14 -0000       1.151.2.10
+++ client/mapview_common.c     4 Dec 2004 09:04:51 -0000
@@ -421,7 +421,8 @@
   common_y0 = MAX(old_gui_y0, gui_y0);
   common_y1 = MIN(old_gui_y0, gui_y0) + height;
 
-  if (common_x1 > common_x0 && common_y1 > common_y0) {
+  if (mapview_canvas.can_do_cached_drawing
+      && common_x1 > common_x0 && common_y1 > common_y0) {
     /* Do a partial redraw only.  This means the area of overlap (a
      * rectangle) is copied.  Then the remaining areas (two rectangles)
      * are updated through update_map_canvas. */
@@ -2447,6 +2448,79 @@
 }
 
 /**************************************************************************
+  Returns TRUE if cached drawing is possible.  If the mapview is too large
+  we have to turn it off.
+**************************************************************************/
+static bool can_do_cached_drawing(void)
+{
+  const int W = NORMAL_TILE_WIDTH, H = NORMAL_TILE_HEIGHT;
+  int w = mapview_canvas.store_width, h = mapview_canvas.store_height;
+
+  /* If the mapview window is too large, cached drawing is not possible.
+   *
+   * BACKGROUND: cached drawing occurrs when the mapview is scrolled just
+   * a short distance.  The majority of the mapview window can simply be
+   * copied while the newly visible areas must be drawn from scratch.  This
+   * speeds up drawing significantly, especially when using the scrollbars
+   * or mapview sliding.
+   *
+   * When the mapview is larger than the map, however, some tiles may become
+   * visible twice.  In this case one instance of the tile will be drawn
+   * while all others are drawn black.  When this happens the cached drawing
+   * system breaks since it assumes the mapview canvas is an "ideal" window
+   * over the map.  So black tiles may be scrolled from the edges of the
+   * mapview into the center, while drawn tiles may be scrolled from the
+   * center of the mapview out to the edges.  The result is very bad.
+   *
+   * There are a few different ways this could be solved.  One way is simply
+   * to turn off cached drawing, which is what we do now.  If the mapview
+   * window gets to be too large, the caching is disabled.  Another would
+   * be to prevent the window from getting too large in the first place -
+   * but because the window boundaries aren't at an even tile this would
+   * mean the entire map could never be shown.  Yet another way would be
+   * to draw tiles more than once if they are visible in multiple locations
+   * on the mapview.
+   *
+   * The logic below is complicated and determined in part by
+   * trial-and-error. */
+  if (!topo_has_flag(TF_WRAPX) && !topo_has_flag(TF_WRAPY)) {
+    /* An unwrapping map: no limitation.  On an unwrapping map no tile can
+     * be visible twice so there's no problem. */
+    return TRUE;
+  }
+  if (XOR(topo_has_flag(TF_ISO) || topo_has_flag(TF_HEX), is_isometric)) {
+    /* Non-matching.  In this case the mapview does not line up with the
+     * map's axis of wrapping.  This will give very bad results for the
+     * player!
+     * We can never show more than half of the map.
+     *
+     * We divide by 4 below because we have to divide by 2 twice.  The
+     * first division by 2 is because the square must be half the size
+     * of the (width+height).  The second division by two is because for
+     * an iso-map, NATURAL_XXX has a scale of 2, whereas for iso-view
+     * NORMAL_TILE_XXX has a scale of 2. */
+    return (w <= (NATURAL_WIDTH + NATURAL_HEIGHT) * W / 4
+           && h <= (NATURAL_WIDTH + NATURAL_HEIGHT) * H / 4);
+  } else {
+    /* Matching. */
+    const int isofactor = (is_isometric ? 2 : 1);
+    const int isodiff = (is_isometric ? 6 : 2);
+
+    /* Now we can use the full width and height, with the exception of a small
+     * area on each side. */
+    if (topo_has_flag(TF_WRAPX)
+       && w > (NATURAL_WIDTH - isodiff) * W / isofactor) {
+      return FALSE;
+    }
+    if (topo_has_flag(TF_WRAPY)
+       && h > (NATURAL_HEIGHT - isodiff) * H / isofactor) {
+      return FALSE;
+    }
+    return TRUE;
+  }
+}
+
+/**************************************************************************
   Called if the map size is know or changes.
 **************************************************************************/
 void set_overview_dimensions(int width, int height)
@@ -2475,6 +2549,8 @@
                       0, 0, overview.width, overview.height);
   update_map_canvas_scrollbars_size();
 
+  mapview_canvas.can_do_cached_drawing = can_do_cached_drawing();
+
   /* Call gui specific function. */
   map_size_changed();
 }
@@ -2540,6 +2616,8 @@
     }
   }
 
+  mapview_canvas.can_do_cached_drawing = can_do_cached_drawing();
+
   return redrawn;
 }
 
Index: client/mapview_common.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/mapview_common.h,v
retrieving revision 1.79.2.1
diff -u -r1.79.2.1 mapview_common.h
--- client/mapview_common.h     17 Oct 2004 15:47:51 -0000      1.79.2.1
+++ client/mapview_common.h     4 Dec 2004 09:04:51 -0000
@@ -30,6 +30,7 @@
   int width, height;           /* Size in pixels. */
   int tile_width, tile_height; /* Size in tiles. Rounded up. */
   int store_width, store_height;
+  bool can_do_cached_drawing; /* TRUE if cached drawing is possible. */
   struct canvas *store, *tmp_store;
 };
 

[Prev in Thread] Current Thread [Next in Thread]
  • [Freeciv-Dev] (PR#8998) Small map meets large screen, they have problems together., Jason Short <=