Complete.Org: Mailing Lists: Archives: freeciv-dev: May 2004:
[Freeciv-Dev] Re: (PR#8603) faster mapview scrolling
Home

[Freeciv-Dev] Re: (PR#8603) faster mapview scrolling

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
To: undisclosed-recipients: ;
Subject: [Freeciv-Dev] Re: (PR#8603) faster mapview scrolling
From: "Jason Short" <jdorje@xxxxxxxxxxxxxxxxxxxxx>
Date: Sun, 9 May 2004 14:44:17 -0700
Reply-to: rt@xxxxxxxxxxx

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

Jason Short wrote:

> There are several issues however:
> 
> - We copy_canvas from a canvas to itself.  The copy is likely to 
> overlap.  This works fine in gui-gtk-2.0 (to my surprise).  Likely in 
> other GUIs it does not work.  This can easily be solved by using a 
> second backing store and swapping between them.
> 
> - When the mapview wraps around in GUI coordinates, we end up doing a 
> full update even though it's not necessary.  This could be resolved 
> using a gui_distance_vector function to find the difference in positions 
> (except that this function doesn't exist yet).
> 
> - City descriptions must still be redrawn in full.  This is 
> unnecessarily slow since we obviously only need to redraw a few of them. 
>   It will also give bad results with anti-aliased fonts since these 
> cannot be drawn multiple times.  This can also be solved with a second 
> backing store.

This patch improves the behavior.

- A second backing store is used.  This fixes problems with GUIs that 
don't allow you to copy from a store to itself.  I had problems with 
this in gui-win32 under wine.

No doubt the extra copy slows things down a bit.  However scrolling is 
still visibly faster.

It is now possible to remove single_tile_pixmap.  However I leave this 
until a later patch.

- A full update is still done when the GUI coordinates wrap.

- City descriptions are still redrawn in full.

I believe it is now ready for inclusion.

jason

? eff
Index: client/mapview_common.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/mapview_common.c,v
retrieving revision 1.111
diff -u -r1.111 mapview_common.c
--- client/mapview_common.c     4 May 2004 17:40:26 -0000       1.111
+++ client/mapview_common.c     9 May 2004 21:43:31 -0000
@@ -390,13 +390,63 @@
   /* Then update everything. */
   if (mapview_canvas.gui_x0 != gui_x0 || mapview_canvas.gui_y0 != gui_y0) {
     int map_center_x, map_center_y;
+    int old_gui_x0 = mapview_canvas.gui_x0;
+    int old_gui_y0 = mapview_canvas.gui_y0;
+    const int width = mapview_canvas.width, height = mapview_canvas.height;
+    int common_x0, common_x1, common_y0, common_y1;
+    int update_x0, update_x1, update_y0, update_y1;
 
     mapview_canvas.gui_x0 = gui_x0;
     mapview_canvas.gui_y0 = gui_y0;
 
+    common_x0 = MAX(old_gui_x0, gui_x0);
+    common_x1 = MIN(old_gui_x0, gui_x0) + width;
+    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) {
+      /* Do a partial redraw only. */
+      struct canvas *target = mapview_canvas.tmp_store;
+
+      if (old_gui_x0 < gui_x0) {
+       update_x0 = MAX(old_gui_x0 + width, gui_x0);
+       update_x1 = gui_x0 + width;
+      } else {
+       update_x0 = gui_x0;
+       update_x1 = MIN(old_gui_x0, gui_x0 + width);
+      }
+      if (old_gui_y0 < gui_y0) {
+       update_y0 = MAX(old_gui_y0 + height, gui_y0);
+       update_y1 = gui_y0 + height;
+      } else {
+       update_y0 = gui_y0;
+       update_y1 = MIN(old_gui_y0, gui_y0 + height);
+      }
+
+      dirty_all();
+      canvas_copy(target, mapview_canvas.store,
+                 common_x0 - old_gui_x0,
+                 common_y0 - old_gui_y0,
+                 common_x0 - gui_x0, common_y0 - gui_y0,
+                 common_x1 - common_x0, common_y1 - common_y0);
+      mapview_canvas.tmp_store = mapview_canvas.store;
+      mapview_canvas.store = target;
+
+      if (update_y1 > update_y0) {
+       update_map_canvas(0, update_y0 - gui_y0,
+                         width, update_y1 - update_y0);
+      }
+      if (update_x1 > update_x0) {
+       update_map_canvas(update_x0 - gui_x0, common_y0 - gui_y0,
+                         update_x1 - update_x0, common_y1 - common_y0);
+      }
+      show_city_descriptions();
+    } else {
+      update_map_canvas_visible();
+    }
+
     get_center_tile_mapcanvas(&map_center_x, &map_center_y);
     center_tile_overviewcanvas(map_center_x, map_center_y);
-    update_map_canvas_visible();
     update_map_canvas_scrollbars();
     if (hover_state == HOVER_GOTO || hover_state == HOVER_PATROL) {
       create_line_at_mouse_pos();
@@ -2204,10 +2254,13 @@
   if (tile_size_changed) {
     if (mapview_canvas.store) {
       canvas_free(mapview_canvas.store);
+      canvas_free(mapview_canvas.tmp_store);
     }
     mapview_canvas.store = canvas_create(full_width, full_height);
     canvas_put_rectangle(mapview_canvas.store, COLOR_STD_BLACK, 0, 0,
                         full_width, full_height);
+
+    mapview_canvas.tmp_store = canvas_create(full_width, full_height);
   }
 
   if (map_exists() && can_client_change_view()) {
Index: client/mapview_common.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/mapview_common.h,v
retrieving revision 1.60
diff -u -r1.60 mapview_common.h
--- client/mapview_common.h     28 Apr 2004 00:54:24 -0000      1.60
+++ client/mapview_common.h     9 May 2004 21:43:31 -0000
@@ -28,7 +28,7 @@
   int width, height;           /* Size in pixels. */
   int tile_width, tile_height; /* Size in tiles. Rounded up. */
   int store_width, store_height;
-  struct canvas *store, *single_tile;
+  struct canvas *store, *tmp_store, *single_tile;
 };
 
 /* Holds all information about the overview aka minimap. */

[Prev in Thread] Current Thread [Next in Thread]
  • [Freeciv-Dev] Re: (PR#8603) faster mapview scrolling, Jason Short <=