Complete.Org: Mailing Lists: Archives: freeciv-dev: June 2004:
[Freeciv-Dev] (PR#9027) mapview resizing bug
Home

[Freeciv-Dev] (PR#9027) mapview resizing bug

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
To: undisclosed-recipients: ;
Subject: [Freeciv-Dev] (PR#9027) mapview resizing bug
From: "Jason Short" <jdorje@xxxxxxxxxxxxxxxxxxxxx>
Date: Sat, 19 Jun 2004 03:42:20 -0700
Reply-to: rt@xxxxxxxxxxx

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

If you resize the mapview just right you'll get a mapview that's not 
fully drawn.  With the fast-scrolling method currently used and the 
spurious-resize bug this is actually a quite common and major bug.

It's caused because two pieces of code consider only the canvas width, 
not the store width.  This highlights a problem that we may see more of 
in the future (especially if we optimize even more).

The mapview canvas is a width (and height, but I'll just talk about 
width).  This is the width of the window/widget, mapview_canvas.width. 
It's important for some operations like 
tile_visible_and_not_on_border_mapcanvas and [get_]center_tile_mapcanvas.

The canvas also has a _store_ width.  This is the width of the backing 
store.  For efficiency the backing store is slightly larger than the 
canvas, and quantized.  Thus if you change the size of the canvas 
slightly the store won't _always_ need to be resized.  This could (but 
currently isn't) be made slightly larger and used as a cache to vastly 
speed up some drawing operations (Arnstein's done some work on this). 
The store width must be used in place of the canvas width anywhere we're 
deciding whether to draw a tile: because when a tile is updated we have 
to update the whole store - otherwise if the canvas is resized the 
un-updated parts of the store may be shown without being updated.  Thus 
this value is important in tile_visible_mapcanvas and 
update_map_canvas[_visible].

The current bug happens because two users (in update_map_canvas and 
update_map_canvas_visible) use the window width instead of the store 
width.  This patch fixes it.  I will apply it very soon.

jason

? gmon.out
? profile
? profile-o2
? profile-o3
Index: client/mapview_common.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/mapview_common.c,v
retrieving revision 1.127
diff -u -r1.127 mapview_common.c
--- client/mapview_common.c     17 Jun 2004 19:45:03 -0000      1.127
+++ client/mapview_common.c     19 Jun 2004 10:34:04 -0000
@@ -1395,14 +1395,14 @@
 
   canvas_x = MAX(canvas_x, 0);
   canvas_y = MAX(canvas_y, 0);
-  width = MIN(mapview_canvas.width - canvas_x, width);
-  height = MIN(mapview_canvas.height - canvas_y, height);
+  width = MIN(mapview_canvas.store_width - canvas_x, width);
+  height = MIN(mapview_canvas.store_height - canvas_y, height);
 
   gui_x0 = mapview_canvas.gui_x0 + canvas_x;
   gui_y0 = mapview_canvas.gui_y0 + canvas_y;
   full = (canvas_x == 0 && canvas_y == 0
-         && width == mapview_canvas.width
-         && height == mapview_canvas.height);
+         && width == mapview_canvas.store_width
+         && height == mapview_canvas.store_height);
 
   freelog(LOG_DEBUG,
          "update_map_canvas(pos=(%d,%d), size=(%d,%d))",
@@ -1510,7 +1510,8 @@
 void update_map_canvas_visible(void)
 {
   dirty_all();
-  update_map_canvas(0, 0, mapview_canvas.width, mapview_canvas.height);
+  update_map_canvas(0, 0, mapview_canvas.store_width,
+                   mapview_canvas.store_height);
 }
 
 /* The maximum city description width and height.  This gives the dimensions
@@ -2370,6 +2371,8 @@
     }
   }
 
+  dirty_all();
+
   return redrawn;
 }
 
Index: server/gotohand.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/gotohand.c,v
retrieving revision 1.179
diff -u -r1.179 gotohand.c
--- server/gotohand.c   19 May 2004 00:49:32 -0000      1.179
+++ server/gotohand.c   19 Jun 2004 10:34:11 -0000
@@ -300,18 +300,21 @@
 
     ptile = map_get_tile(x, y);
     adjc_dir_iterate(x, y, x1, y1, dir) {
+      struct tile *ptile1 = map_get_tile(x1, y1);
+
       switch (move_type) {
       case LAND_MOVING:
        if (WARMAP_COST(x1, y1) <= cost)
          continue; /* No need for all the calculations */
 
-        if (is_ocean(map_get_terrain(x1, y1))) {
+        if (is_ocean(ptile1->terrain)) {
           if (punit && ground_unit_transporter_capacity(x1, y1, pplayer) > 0)
            move_cost = SINGLE_MOVE;
           else
            continue;
        } else if (is_ocean(ptile->terrain)) {
-         int base_cost = get_tile_type(map_get_terrain(x1, y1))->movement_cost 
* SINGLE_MOVE;
+         int base_cost
+           = get_tile_type(ptile1->terrain)->movement_cost * SINGLE_MOVE;
          move_cost = igter ? MOVE_COST_ROAD : MIN(base_cost, 
unit_move_rate(punit));
         } else if (igter)
          /* NOT c = 1 (Syela) [why not? - Thue] */

[Prev in Thread] Current Thread [Next in Thread]
  • [Freeciv-Dev] (PR#9027) mapview resizing bug, Jason Short <=