Complete.Org: Mailing Lists: Archives: freeciv-dev: January 2003:
[Freeciv-Dev] (PR#2709) city descriptions are overwritten by local mapvi
Home

[Freeciv-Dev] (PR#2709) city descriptions are overwritten by local mapvi

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
Cc: freeciv-dev@xxxxxxxxxxx
Subject: [Freeciv-Dev] (PR#2709) city descriptions are overwritten by local mapview draws
From: "Jason Short via RT" <rt@xxxxxxxxxxxxxx>
Date: Mon, 20 Jan 2003 18:52:47 -0800
Reply-to: rt@xxxxxxxxxxxxxx

[jdorje - Fri Jan  3 10:25:28 2003]:

> A new ticket for an old bug...
> 
> When any mapview drawing other than update_map_canvas_visible is called,
> the city descriptions are overwritten.
> 
> This includes moving units, goto lines, etc.

Until just recently, the win32 client had a "fix" for this: any time
update_city_descriptions() was called, show_city_descriptions() was
calleed immediately afterwards.  This will indeed cause the desired
redraw, but at a *huge* cost in drawing time (a 10x increase in the
simplest, most common type of redraw - and a big loss even in
update_map_canvas_visible since you end up redrawing the descriptions
twice).

Another alternative is to redraw the city descriptions selectively when
we call update_map_canvas.  For instance in non-iso view the city
description almost always resides within the 3 tiles directly below the
city, so when updating a WxH rectangle of tiles we can redraw the city
descriptions for the (W+2)xH tiles that may have cities with overwritten
descriptions.  This math becomes more complicated in iso-mode, and the
method doesn't work well with update_map_canvas_visible either.

A simpler, yet still effective, variant is to only redraw the
descriptions when a single-tile update happens; i.e., when
refresh_tile_mapcanvas() is called.  This involves drawing the
descriptions for 3 different tiles in non-iso mode and 8 tiles in iso
mode (note that most of them won't have cities on them).  The drawing is
fast, so it generally avoids noticable flicker.  The attached patch does
this - it achieves a huge increase in drawing quality IMO.

However, this is still just a workaround.  In enforces the current
buffering methodology: that is, no buffering of city descriptions.  This
already happens in update_map_canvas_visible: the main buffer is flushed
to the display, and *then* the city descriptions are drawn.  AFAICT it
is fundamentally different from what would be used if the city
descriptions were buffered in any way. I can't see a set of common code
that will allow the clients to use any buffering system they want, so it
seems that all clients must use the same (or compatible) buffering
systems.  For the moment, this means no buffering of city descriptions.

The patch does solve a huge graphics bug in 90-99% of the cases.  So I
suggest this workaround should go in unless someone can come up with
something better.

jason

? client/gui-gtk/diff
Index: client/mapview_common.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/mapview_common.c,v
retrieving revision 1.24
diff -u -r1.24 mapview_common.c
--- client/mapview_common.c     2003/01/17 20:20:56     1.24
+++ client/mapview_common.c     2003/01/21 02:41:03
@@ -41,6 +41,51 @@
 
   if (tile_visible_mapcanvas(x, y)) {
     update_map_canvas(x, y, 1, 1, write_to_screen);
+
+    if (write_to_screen && (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. */
+      int iter, 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). */
+       square_iterate(x - 1, y - 1, 1, city_x, city_y) {
+         if ((pcity = map_get_city(city_x, city_y))) {
+           get_canvas_xy(city_x, city_y, &canvas_x, &canvas_y);
+           show_city_desc(pcity, canvas_x, canvas_y);
+         }
+       } square_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. */
+       for (iter = -1; iter <= 1; iter++) {
+         int city_x = x + iter, city_y = y - 1;
+
+         if (normalize_map_pos(&city_x, &city_y)
+             && (pcity = map_get_city(city_x, city_y))) {
+           get_canvas_xy(city_x, city_y, &canvas_x, &canvas_y);
+           show_city_desc(pcity, canvas_x, canvas_y);
+         }
+       }
+      }
+    }
   }
   overview_update_tile(x, y);
 }

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