Complete.Org: Mailing Lists: Archives: freeciv-dev: February 2005:
[Freeciv-Dev] Re: (PR#12191) make all drawing queued
Home

[Freeciv-Dev] Re: (PR#12191) make all drawing queued

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
Subject: [Freeciv-Dev] Re: (PR#12191) make all drawing queued
From: "Jason Short" <jdorje@xxxxxxxxxxxxxxxxxxxxx>
Date: Wed, 9 Feb 2005 14:24:07 -0800
Reply-to: bugs@xxxxxxxxxxx

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

Oops.  A major bug caused a full redraw to be done instead of no redraw 
in unqueue_mapview_updates.

-jason


Index: client/clinet.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/clinet.c,v
retrieving revision 1.111
diff -u -r1.111 clinet.c
--- client/clinet.c     9 Feb 2005 19:45:44 -0000       1.111
+++ client/clinet.c     9 Feb 2005 22:23:06 -0000
@@ -347,8 +347,6 @@
   } else {
     close_socket_callback(&aconnection);
   }
-
-  unqueue_mapview_updates();
 }
 
 /**************************************************************************
@@ -391,7 +389,7 @@
          if (aconnection.client.last_processed_request_id_seen >=
              expected_request_id) {
            freelog(LOG_DEBUG, "ifstrgp: got it; returning");
-           goto out;
+           return;
          }
        }
       }
@@ -400,9 +398,6 @@
       break;
     }
   }
-
-out:
-  unqueue_mapview_updates();
 }
 
 #ifdef WIN32_NATIVE
Index: client/control.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/control.c,v
retrieving revision 1.155
diff -u -r1.155 control.c
--- client/control.c    9 Feb 2005 16:23:12 -0000       1.155
+++ client/control.c    9 Feb 2005 22:23:06 -0000
@@ -1113,7 +1113,7 @@
   }
 
   draw_city_outlines = !draw_city_outlines;
-  update_map_canvas_visible();
+  queue_mapview_update(UPDATE_MAP_CANVAS_VISIBLE);
 }
 
 /**************************************************************************
@@ -1126,7 +1126,7 @@
   }
 
   draw_map_grid^=1;
-  update_map_canvas_visible();
+  queue_mapview_update(UPDATE_MAP_CANVAS_VISIBLE);
 }
 
 /**************************************************************************
@@ -1139,7 +1139,7 @@
   }
 
   draw_borders ^= 1;
-  update_map_canvas_visible();
+  queue_mapview_update(UPDATE_MAP_CANVAS_VISIBLE);
 }
 
 /**************************************************************************
@@ -1152,7 +1152,7 @@
   }
 
   draw_city_names ^= 1;
-  update_map_canvas_visible();
+  queue_mapview_update(UPDATE_MAP_CANVAS_VISIBLE);
 }
  
  /**************************************************************************
@@ -1165,7 +1165,7 @@
   }
 
   draw_city_growth ^= 1;
-  update_map_canvas_visible();
+  queue_mapview_update(UPDATE_MAP_CANVAS_VISIBLE);
 }
 
 /**************************************************************************
@@ -1178,7 +1178,7 @@
   }
 
   draw_city_productions ^= 1;
-  update_map_canvas_visible();
+  queue_mapview_update(UPDATE_MAP_CANVAS_VISIBLE);
 }
 
 /**************************************************************************
@@ -1191,7 +1191,7 @@
   }
 
   draw_terrain ^= 1;
-  update_map_canvas_visible();
+  queue_mapview_update(UPDATE_MAP_CANVAS_VISIBLE);
 }
 
 /**************************************************************************
@@ -1204,7 +1204,7 @@
   }
 
   draw_coastline ^= 1;
-  update_map_canvas_visible();
+  queue_mapview_update(UPDATE_MAP_CANVAS_VISIBLE);
 }
 
 /**************************************************************************
@@ -1217,7 +1217,7 @@
   }
 
   draw_roads_rails ^= 1;
-  update_map_canvas_visible();
+  queue_mapview_update(UPDATE_MAP_CANVAS_VISIBLE);
 }
 
 /**************************************************************************
@@ -1230,7 +1230,7 @@
   }
 
   draw_irrigation ^= 1;
-  update_map_canvas_visible();
+  queue_mapview_update(UPDATE_MAP_CANVAS_VISIBLE);
 }
 
 /**************************************************************************
@@ -1243,7 +1243,7 @@
   }
 
   draw_mines ^= 1;
-  update_map_canvas_visible();
+  queue_mapview_update(UPDATE_MAP_CANVAS_VISIBLE);
 }
 
 /**************************************************************************
@@ -1256,7 +1256,7 @@
   }
 
   draw_fortress_airbase ^= 1;
-  update_map_canvas_visible();
+  queue_mapview_update(UPDATE_MAP_CANVAS_VISIBLE);
 }
 
 /**************************************************************************
@@ -1269,7 +1269,7 @@
   }
 
   draw_specials ^= 1;
-  update_map_canvas_visible();
+  queue_mapview_update(UPDATE_MAP_CANVAS_VISIBLE);
 }
 
 /**************************************************************************
@@ -1282,7 +1282,7 @@
   }
 
   draw_pollution ^= 1;
-  update_map_canvas_visible();
+  queue_mapview_update(UPDATE_MAP_CANVAS_VISIBLE);
 }
 
 /**************************************************************************
@@ -1295,7 +1295,7 @@
   }
 
   draw_cities ^= 1;
-  update_map_canvas_visible();
+  queue_mapview_update(UPDATE_MAP_CANVAS_VISIBLE);
 }
 
 /**************************************************************************
@@ -1308,7 +1308,7 @@
   }
 
   draw_units ^= 1;
-  update_map_canvas_visible();
+  queue_mapview_update(UPDATE_MAP_CANVAS_VISIBLE);
 }
 
 /**************************************************************************
@@ -1321,7 +1321,7 @@
   }
 
   draw_focus_unit ^= 1;
-  update_map_canvas_visible();
+  queue_mapview_update(UPDATE_MAP_CANVAS_VISIBLE);
 }
 
 /**************************************************************************
@@ -1334,7 +1334,7 @@
   }
 
   draw_fog_of_war ^= 1;
-  update_map_canvas_visible();
+  queue_mapview_update(UPDATE_MAP_CANVAS_VISIBLE);
   refresh_overview_canvas();
 }
 
Index: client/mapview_common.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/mapview_common.c,v
retrieving revision 1.182
diff -u -r1.182 mapview_common.c
--- client/mapview_common.c     9 Feb 2005 17:15:17 -0000       1.182
+++ client/mapview_common.c     9 Feb 2005 22:23:07 -0000
@@ -25,6 +25,7 @@
 #include "timing.h"
 
 #include "graphics_g.h"
+#include "gui_main_g.h"
 #include "mapctrl_g.h"
 #include "mapview_g.h"
 
@@ -64,23 +65,12 @@
 **************************************************************************/
 void refresh_tile_mapcanvas(struct tile *ptile, bool write_to_screen)
 {
-  int canvas_x, canvas_y;
-
-  if (tile_to_canvas_pos(&canvas_x, &canvas_y, ptile)) {
-    const int W = NORMAL_TILE_WIDTH, H = NORMAL_TILE_HEIGHT;
-
-    /* We draw an extra NORMAL_TILE_XXX / 2 on each side because with
-     * corner and edge sprites this much extra may need to be drawn.  This
-     * is only applicable when the underlying tile changes however.  There
-     * should probably be a refresh_unit_mapcanvas/refresh_city_mapcanvas
-     * functions that handle updates for those items more elegantly. */
-    update_map_canvas(canvas_x - W / 2, canvas_y - H / 2, 2 * W, 2 * H);
-
-    if (write_to_screen) {
-      flush_dirty();
-    }
+  queue_mapview_tile_update(ptile);
+  if (write_to_screen) {
+    unqueue_mapview_updates();
+    flush_dirty();
+    flush_dirty_overview();
   }
-  overview_update_tile(ptile);
 }
 
 /**************************************************************************
@@ -89,35 +79,12 @@
 void refresh_unit_mapcanvas(struct unit *punit, struct tile *ptile,
                            bool write_to_screen)
 {
-  if (unit_type_flag(punit->type, F_CITIES)) {
-    /* For settlers we (often) have to update the whole citymap area because
-     * of the 't' overlays or the citymap outlines.  The above check could
-     * be more rigorous so that no update is done unless it's needed...
-     *
-     * HACK: The addition below accounts for grid lines that may actually
-     * be on a tile outside of the city radius.  This is similar to what's
-     * done in refresh_tile_mapcanvas. */
-    int width = get_citydlg_canvas_width() + NORMAL_TILE_WIDTH;
-    int height = get_citydlg_canvas_height() + NORMAL_TILE_HEIGHT;
-    int canvas_x, canvas_y;
-
-    tile_to_canvas_pos(&canvas_x, &canvas_y, ptile);
-    update_map_canvas(canvas_x - (width - NORMAL_TILE_WIDTH) / 2,
-                     canvas_y - (height - NORMAL_TILE_HEIGHT) / 2,
-                     width, height);
-  } else {
-    int canvas_x, canvas_y;
-
-    if (tile_to_canvas_pos(&canvas_x, &canvas_y, ptile)) {
-      canvas_y += NORMAL_TILE_HEIGHT - UNIT_TILE_HEIGHT;
-      update_map_canvas(canvas_x, canvas_y,
-                       UNIT_TILE_WIDTH, UNIT_TILE_HEIGHT);
-    } 
-  }
+  queue_mapview_unit_update(punit, ptile);
   if (write_to_screen) {
+    unqueue_mapview_updates();
     flush_dirty();
+    flush_dirty_overview();
   }
-  overview_update_tile(ptile);
 }
 
 /**************************************************************************
@@ -129,37 +96,12 @@
 void refresh_city_mapcanvas(struct city *pcity, struct tile *ptile,
                            bool full_refresh, bool write_to_screen)
 {
-  if (full_refresh && (draw_map_grid || draw_borders)) {
-    /* We have to make sure we update any workers on the map grid, then
-     * redraw the city descriptions on top of them.  So we calculate the
-     * rectangle covered by the city's map, and update that.  Then we
-     * queue up a city description redraw for later.
-     *
-     * HACK: The addition below accounts for grid lines that may actually
-     * be on a tile outside of the city radius.  This is similar to what's
-     * done in refresh_tile_mapcanvas. */
-    int canvas_x, canvas_y;
-    int width = get_citydlg_canvas_width() + NORMAL_TILE_WIDTH;
-    int height = get_citydlg_canvas_height() + NORMAL_TILE_HEIGHT;
-
-    (void) tile_to_canvas_pos(&canvas_x, &canvas_y, pcity->tile);
-
-    update_map_canvas(canvas_x - (width - NORMAL_TILE_WIDTH) / 2,
-                     canvas_y - (height - NORMAL_TILE_HEIGHT) / 2,
-                     width, height);
-  } else {
-    int canvas_x, canvas_y;
-
-    if (tile_to_canvas_pos(&canvas_x, &canvas_y, ptile)) {
-      canvas_y += NORMAL_TILE_HEIGHT - UNIT_TILE_HEIGHT;
-      update_map_canvas(canvas_x, canvas_y,
-                       UNIT_TILE_WIDTH, UNIT_TILE_HEIGHT);
-    }
-  }
+  queue_mapview_city_update(pcity, ptile, full_refresh);
   if (write_to_screen) {
+    unqueue_mapview_updates();
     flush_dirty();
+    flush_dirty_overview();
   }
-  overview_update_tile(ptile);
 }
 
 /**************************************************************************
@@ -1119,16 +1061,8 @@
 ****************************************************************************/
 void toggle_city_color(struct city *pcity)
 {
-  int canvas_x, canvas_y;
-  int width = get_citydlg_canvas_width();
-  int height = get_citydlg_canvas_height();
-
   pcity->client.color = (pcity->client.color + 1) % NUM_CITY_COLORS;
-
-  tile_to_canvas_pos(&canvas_x, &canvas_y, pcity->tile);
-  update_map_canvas(canvas_x - (width - NORMAL_TILE_WIDTH) / 2,
-                   canvas_y - (height - NORMAL_TILE_HEIGHT) / 2,
-                   width, height);
+  refresh_city_mapcanvas(pcity, pcity->tile, TRUE, FALSE);
 }
 
 /****************************************************************************
@@ -1138,16 +1072,8 @@
 ****************************************************************************/
 void toggle_unit_color(struct unit *punit)
 {
-  int canvas_x, canvas_y;
-  int width = get_citydlg_canvas_width();
-  int height = get_citydlg_canvas_height();
-
   punit->client.color = (punit->client.color + 1) % NUM_CITY_COLORS;
-
-  tile_to_canvas_pos(&canvas_x, &canvas_y, punit->tile);
-  update_map_canvas(canvas_x - (width - NORMAL_TILE_WIDTH) / 2,
-                   canvas_y - (height - NORMAL_TILE_HEIGHT) / 2,
-                   width, height);
+  refresh_unit_mapcanvas(punit, punit->tile, FALSE);
 }
 
 /****************************************************************************
@@ -1350,6 +1276,7 @@
 
   /* Make sure everything is flushed and synced before proceeding. */
   unqueue_mapview_updates();
+  flush_dirty();
   gui_flush();
 
   myusleep(1000000);
@@ -1881,21 +1808,19 @@
 **************************************************************************/
 void undraw_segment(struct tile *src_tile, enum direction8 dir)
 {
-  int canvas_x, canvas_y, canvas_dx, canvas_dy;
-
-  assert(!is_drawn_line(src_tile, dir));
+  struct tile *dst_tile = mapstep(src_tile, dir);
 
+  if (is_drawn_line(src_tile, dir) || !dst_tile) {
+    assert(0);
+    return;
+  }
+  
   /* Note that if source and dest tiles are not adjacent (because the
    * mapview wraps around) this will not give the correct behavior.  This is
    * consistent with the current design which fails when the size of the
    * mapview approaches the size of the map. */
-  (void) tile_to_canvas_pos(&canvas_x, &canvas_y, src_tile);
-  map_to_gui_vector(&canvas_dx, &canvas_dy, DIR_DX[dir], DIR_DY[dir]);
-
-  update_map_canvas(MIN(canvas_x, canvas_x + canvas_dx),
-                   MIN(canvas_y, canvas_y + canvas_dy),
-                   ABS(canvas_dx) + NORMAL_TILE_WIDTH,
-                   ABS(canvas_dy) + NORMAL_TILE_HEIGHT);
+  refresh_tile_mapcanvas(src_tile, FALSE);
+  refresh_tile_mapcanvas(dst_tile, FALSE);
 }
 
 /****************************************************************************
@@ -1912,6 +1837,7 @@
   set_units_in_combat(punit0, punit1);
 
   unqueue_mapview_updates();
+  flush_dirty();
   while (punit0->hp > hp0 || punit1->hp > hp1) {
     const int diff0 = punit0->hp - hp0, diff1 = punit1->hp - hp1;
 
@@ -1925,6 +1851,7 @@
       refresh_unit_mapcanvas(punit1, punit1->tile, FALSE);
     }
 
+    unqueue_mapview_updates();
     flush_dirty();
     gui_flush();
 
@@ -2000,7 +1927,6 @@
     return;
   }
 
-  unqueue_mapview_updates();
   if (tile_visible_mapcanvas(src_tile)
       || tile_visible_mapcanvas(dest_tile)) {
     int start_x, start_y;
@@ -2018,6 +1944,8 @@
 
     /* Flush before we start animating. */
     flush_dirty();
+    unqueue_mapview_updates();
+    /* No flush_dirty here! */
     gui_flush();
 
     do {
@@ -2187,10 +2115,35 @@
 }
 
 static enum update_type needed_updates = UPDATE_NONE;
+static bool callback_queued = FALSE;
 struct tile_list *city_updates = NULL;
 struct tile_list *unit_updates = NULL;
 struct tile_list *tile_updates = NULL;
 
+/****************************************************************************
+  This callback is called during an idle moment to unqueue any pending
+  mapview updates.
+****************************************************************************/
+static void queue_callback(void *data)
+{
+  callback_queued = FALSE;
+  unqueue_mapview_updates();
+  flush_dirty();
+  flush_dirty_overview();
+}
+
+/****************************************************************************
+  When a mapview update is queued this function should be called to prepare
+  an idle-time callback to unqueue the updates.
+****************************************************************************/
+static void queue_add_callback(void)
+{
+  if (!callback_queued) {
+    callback_queued = TRUE;
+    add_idle_callback(queue_callback, NULL);
+  }
+}
+
 /**************************************************************************
   This function, along with unqueue_mapview_update(), helps in updating
   the mapview when a packet is received.  Previously, we just called
@@ -2211,6 +2164,17 @@
 void queue_mapview_update(enum update_type update)
 {
   needed_updates |= update;
+  queue_add_callback();
+}
+
+static struct tile_list *append_tile_to_list(struct tile *ptile,
+                                            struct tile_list *plist)
+{
+  if (!plist) {
+    plist = tile_list_new();
+  }
+  tile_list_append(plist, ptile);
+  return plist;
 }
 
 /**************************************************************************
@@ -2222,34 +2186,37 @@
 **************************************************************************/
 void queue_mapview_tile_update(struct tile *ptile)
 {
-  if (!tile_updates) {
-    tile_updates = tile_list_new();
-  }
-  tile_list_prepend(tile_updates, ptile);
+  tile_updates = append_tile_to_list(ptile, tile_updates);
+  queue_add_callback();
 }
 
 /**************************************************************************
   Queue this unit to be refreshed.  The refresh will be done some time
   soon thereafter, and grouped with other needed refreshes.
 **************************************************************************/
-void queue_mapview_unit_update(struct unit *punit)
+void queue_mapview_unit_update(struct unit *punit, struct tile *ptile)
 {
-  if (!unit_updates) {
-    unit_updates = tile_list_new();
+  if (unit_type_flag(punit->type, F_CITIES)) {
+    city_updates = append_tile_to_list(ptile, city_updates);
+  } else {
+    unit_updates = append_tile_to_list(ptile, unit_updates);
   }
-  tile_list_prepend(unit_updates, punit->tile);
+  queue_add_callback();
 }
 
 /**************************************************************************
   Queue this city to be refreshed.  The refresh will be done some time
   soon thereafter, and grouped with other needed refreshes.
 **************************************************************************/
-void queue_mapview_city_update(struct city *pcity)
+void queue_mapview_city_update(struct city *pcity, struct tile *ptile,
+                              bool full_refresh)
 {
-  if (!city_updates) {
-    city_updates = tile_list_new();
+  if (full_refresh && (draw_map_grid || draw_borders)) {
+    city_updates = append_tile_to_list(ptile, city_updates);
+  } else {
+    unit_updates = append_tile_to_list(ptile, unit_updates);
   }
-  tile_list_prepend(city_updates, pcity->tile);
+  queue_add_callback();
 }
 
 /**************************************************************************
@@ -2267,6 +2234,8 @@
     } else {
       int min_x = mapview_canvas.width, min_y = mapview_canvas.height;
       int max_x = 0, max_y = 0;
+      int min_ovr_x = NATIVE_WIDTH, min_ovr_y = NATIVE_HEIGHT;
+      int max_ovr_x = 0, max_ovr_y = 0;
 
       if (tile_updates) {
        tile_list_iterate(tile_updates, ptile) {
@@ -2283,10 +2252,10 @@
            max_y = MAX(max_y, y1);
          }
 
-         /* FIXME: These overview updates should be batched as well.  Right
-          * now they account for as much as 90% of the runtime of the
-          * unqueue. */
-         overview_update_tile(ptile);
+         min_ovr_x = MIN(ptile->nat_x, min_ovr_x);
+         min_ovr_y = MIN(ptile->nat_y, min_ovr_y);
+         max_ovr_x = MAX(ptile->nat_x + 1, max_ovr_x);
+         max_ovr_y = MAX(ptile->nat_y + 1, max_ovr_y);
        } unit_list_iterate_end;
       }
 
@@ -2304,35 +2273,45 @@
            max_y = MAX(max_y, y1);
          }
 
-         /* FIXME: These overview updates should be batched as well.  Right
-          * now they account for as much as 90% of the runtime of the
-          * unqueue. */
-         overview_update_tile(ptile);
+         min_ovr_x = MIN(ptile->nat_x, min_ovr_x);
+         min_ovr_y = MIN(ptile->nat_y, min_ovr_y);
+         max_ovr_x = MAX(ptile->nat_x + 1, max_ovr_x);
+         max_ovr_y = MAX(ptile->nat_y + 1, max_ovr_y);
        } tile_list_iterate_end;
       }
 
       if (city_updates) {
+       int width = get_citydlg_canvas_width() + NORMAL_TILE_WIDTH;
+       int height = get_citydlg_canvas_height() + NORMAL_TILE_HEIGHT;
+
        tile_list_iterate(city_updates, ptile) {
          int x0, y0, x1, y1;
 
          if (tile_to_canvas_pos(&x0, &y0, ptile)) {
-           y0 += NORMAL_TILE_HEIGHT - UNIT_TILE_HEIGHT;
-           x1 = x0 + UNIT_TILE_WIDTH;
-           y1 = y0 + UNIT_TILE_HEIGHT;
+           x0 -= (width - NORMAL_TILE_WIDTH) / 2;
+           y0 -= (height - NORMAL_TILE_HEIGHT) / 2;
+           x1 = x0 + width;
+           y1 = y0 + height;
            min_x = MIN(min_x, x0);
            min_y = MIN(min_y, y0);
            max_x = MAX(max_x, x1);
            max_y = MAX(max_y, y1);
          }
 
-         /* FIXME: These overview updates should be batched as well.  Right
-          * now they account for as much as 90% of the runtime of the
-          * unqueue. */
-         overview_update_tile(ptile);
+         min_ovr_x = MIN(ptile->nat_x, min_ovr_x);
+         min_ovr_y = MIN(ptile->nat_y, min_ovr_y);
+         max_ovr_x = MAX(ptile->nat_x + 1, max_ovr_x);
+         max_ovr_y = MAX(ptile->nat_y + 1, max_ovr_y);
        } tile_list_iterate_end;
       }
 
-      update_map_canvas(min_x, min_y, max_x - min_x, max_y - min_y);
+      if (max_x > min_x && max_y > min_y) {
+       update_map_canvas(min_x, min_y, max_x - min_x, max_y - min_y);
+      }
+      if (max_ovr_x > min_ovr_x && max_ovr_y > min_ovr_y) {
+       overview_update_area(min_ovr_x, min_ovr_y,
+                            max_ovr_x - min_ovr_x, max_ovr_y - min_ovr_y);
+      }
     }
   }
   if (tile_updates) {
@@ -2345,9 +2324,6 @@
     tile_list_unlink_all(city_updates);
   }
   needed_updates = UPDATE_NONE;
-
-  flush_dirty();
-  flush_dirty_overview();
 }
 
 /**************************************************************************
@@ -2617,36 +2593,51 @@
 **************************************************************************/
 void overview_update_tile(struct tile *ptile)
 {
-  /* Base overview positions are just like natural positions, but scaled to
-   * the overview tile dimensions. */
-  do_in_natural_pos(ntl_x, ntl_y, ptile->x, ptile->y) {
-    int overview_y = ntl_y * OVERVIEW_TILE_SIZE;
-    int overview_x = ntl_x * OVERVIEW_TILE_SIZE;
+  overview_update_area(ptile->nat_x, ptile->nat_y, 1, 1);
+}
 
-    if (MAP_IS_ISOMETRIC) {
-      if (topo_has_flag(TF_WRAPX)) {
-       if (overview_x > overview.width - OVERVIEW_TILE_WIDTH) {
-         /* This tile is shown half on the left and half on the right
-          * side of the overview.  So we have to draw it in two parts. */
-         canvas_put_rectangle(overview.store, 
-                              overview_tile_color(ptile),
-                              overview_x - overview.width, overview_y,
-                              OVERVIEW_TILE_WIDTH, OVERVIEW_TILE_HEIGHT); 
-       }     
-      } else {
-       /* Clip half tile left and right.
-        * See comment in map_to_overview_pos. */
-       overview_x -= OVERVIEW_TILE_SIZE;
-      }
-    } 
-    
-    canvas_put_rectangle(overview.store,
-                        overview_tile_color(ptile),
-                        overview_x, overview_y,
-                        OVERVIEW_TILE_WIDTH, OVERVIEW_TILE_HEIGHT);
+/**************************************************************************
+  Redraws a rectangular area of the overview canvas.
+**************************************************************************/
+void overview_update_area(int nat_x0, int nat_y0, int width, int height)
+{
+  int nat_x, nat_y;
+
+  for (nat_y = nat_y0; nat_y < nat_y0 + height; nat_y++) {
+    for (nat_x = nat_x0; nat_x < nat_x0 + width; nat_x++) {
+      /* Base overview positions are just like natural positions, but
+       * scaled to the overview tile dimensions. */
+      struct tile *ptile = native_pos_to_tile(nat_x, nat_y);
+
+      do_in_natural_pos(ntl_x, ntl_y, ptile->x, ptile->y) {
+       int overview_y = ntl_y * OVERVIEW_TILE_SIZE;
+       int overview_x = ntl_x * OVERVIEW_TILE_SIZE;
+
+       if (MAP_IS_ISOMETRIC) {
+         if (topo_has_flag(TF_WRAPX)) {
+           if (overview_x > overview.width - OVERVIEW_TILE_WIDTH) {
+             /* This tile is shown half on the left and half on the right
+              * side of the overview.  So we have to draw it in two parts. */
+             canvas_put_rectangle(overview.store, 
+                                  overview_tile_color(ptile),
+                                  overview_x - overview.width, overview_y,
+                                  OVERVIEW_TILE_WIDTH, OVERVIEW_TILE_HEIGHT); 
+           }
+         } else {
+           /* Clip half tile left and right.
+            * See comment in map_to_overview_pos. */
+           overview_x -= OVERVIEW_TILE_SIZE;
+         }
+       }
 
-    dirty_overview();
-  } do_in_natural_pos_end;
+       canvas_put_rectangle(overview.store,
+                            overview_tile_color(ptile),
+                            overview_x, overview_y,
+                            OVERVIEW_TILE_WIDTH, OVERVIEW_TILE_HEIGHT);
+      } do_in_natural_pos_end;
+    }
+  }
+  dirty_overview();
 }
 
 /**************************************************************************
Index: client/mapview_common.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/mapview_common.h,v
retrieving revision 1.90
diff -u -r1.90 mapview_common.h
--- client/mapview_common.h     9 Feb 2005 17:15:17 -0000       1.90
+++ client/mapview_common.h     9 Feb 2005 22:23:07 -0000
@@ -294,8 +294,9 @@
 
 void queue_mapview_update(enum update_type update);
 void queue_mapview_tile_update(struct tile *ptile);
-void queue_mapview_unit_update(struct unit *punit);
-void queue_mapview_city_update(struct city *pcity);
+void queue_mapview_unit_update(struct unit *punit, struct tile *ptile);
+void queue_mapview_city_update(struct city *pcity, struct tile *ptile,
+                              bool full_refresh);
 void unqueue_mapview_updates(void);
 
 void map_to_overview_pos(int *overview_x, int *overview_y,
@@ -305,6 +306,7 @@
 
 void refresh_overview_canvas(void);
 void overview_update_tile(struct tile *ptile);
+void overview_update_area(int nat_x0, int nat_y0, int width, int height);
 void set_overview_dimensions(int width, int height);
 
 void init_mapview_decorations(void);
Index: client/gui-gtk/gui_main.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-gtk/gui_main.c,v
retrieving revision 1.159
diff -u -r1.159 gui_main.c
--- client/gui-gtk/gui_main.c   22 Jan 2005 19:45:40 -0000      1.159
+++ client/gui-gtk/gui_main.c   9 Feb 2005 22:23:08 -0000
@@ -1197,3 +1197,17 @@
   gdk_input_remove(gdk_input_id);
   gdk_window_set_cursor(root_window, NULL);
 }
+
+/****************************************************************************
+  Enqueue a callback to be called during an idle moment.  The 'callback'
+  function should be called sometimes soon, and passed the 'data' pointer
+  as its data.
+****************************************************************************/
+void add_idle_callback(void (callback)(void *), void *data)
+{
+  /* PORTME */
+
+  /* This is a reasonable fallback if it's not ported. */
+  freelog(LOG_ERROR, "Unimplemented add_idle_callback.");
+  (callback)(data);
+}
Index: client/gui-gtk-2.0/gui_main.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-gtk-2.0/gui_main.c,v
retrieving revision 1.107
diff -u -r1.107 gui_main.c
--- client/gui-gtk-2.0/gui_main.c       5 Feb 2005 19:46:32 -0000       1.107
+++ client/gui-gtk-2.0/gui_main.c       9 Feb 2005 22:23:08 -0000
@@ -1535,3 +1535,33 @@
   return TRUE;
 }
 
+struct callback {
+  void (*callback)(void *data);
+  void *data;
+};
+
+/****************************************************************************
+  A wrapper for the callback called through add_idle_callback.
+****************************************************************************/
+static gint idle_callback_wrapper(gpointer data)
+{
+  struct callback *cb = data;
+
+  (cb->callback)(cb->data);
+  free(cb);
+  return 0;
+}
+
+/****************************************************************************
+  Enqueue a callback to be called during an idle moment.  The 'callback'
+  function should be called sometimes soon, and passed the 'data' pointer
+  as its data.
+****************************************************************************/
+void add_idle_callback(void (callback)(void *), void *data)
+{
+  struct callback *cb = fc_malloc(sizeof(*cb));
+
+  cb->callback = callback;
+  cb->data = data;
+  gtk_idle_add(idle_callback_wrapper, cb);
+}
Index: client/gui-gtk-2.0/mapctrl.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-gtk-2.0/mapctrl.c,v
retrieving revision 1.45
diff -u -r1.45 mapctrl.c
--- client/gui-gtk-2.0/mapctrl.c        1 Nov 2004 01:20:33 -0000       1.45
+++ client/gui-gtk-2.0/mapctrl.c        9 Feb 2005 22:23:08 -0000
@@ -167,7 +167,7 @@
   bool full = GPOINTER_TO_INT(data);
 
   if (full) {
-    update_map_canvas_visible();
+    queue_mapview_update(UPDATE_MAP_CANVAS_VISIBLE);
   } else {
     dirty_all();
   }
Index: client/gui-mui/gui_main.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-mui/gui_main.c,v
retrieving revision 1.88
diff -u -r1.88 gui_main.c
--- client/gui-mui/gui_main.c   22 Nov 2004 07:54:46 -0000      1.88
+++ client/gui-mui/gui_main.c   9 Feb 2005 22:23:11 -0000
@@ -1455,3 +1455,17 @@
 void set_unit_icons_more_arrow(bool onoff)
 {
 }
+
+/****************************************************************************
+  Enqueue a callback to be called during an idle moment.  The 'callback'
+  function should be called sometimes soon, and passed the 'data' pointer
+  as its data.
+****************************************************************************/
+void add_idle_callback(void (callback)(void *), void *data)
+{
+  /* PORTME */
+
+  /* This is a reasonable fallback if it's not ported. */
+  freelog(LOG_ERROR, "Unimplemented add_idle_callback.");
+  (callback)(data);
+}
Index: client/gui-sdl/gui_main.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-sdl/gui_main.c,v
retrieving revision 1.47
diff -u -r1.47 gui_main.c
--- client/gui-sdl/gui_main.c   20 Nov 2004 21:27:17 -0000      1.47
+++ client/gui-sdl/gui_main.c   9 Feb 2005 22:23:11 -0000
@@ -960,3 +960,17 @@
     pStoreAnimCursor = NULL;
   }
 }
+
+/****************************************************************************
+  Enqueue a callback to be called during an idle moment.  The 'callback'
+  function should be called sometimes soon, and passed the 'data' pointer
+  as its data.
+****************************************************************************/
+void add_idle_callback(void (callback)(void *), void *data)
+{
+  /* PORTME */
+
+  /* This is a reasonable fallback if it's not ported. */
+  freelog(LOG_ERROR, "Unimplemented add_idle_callback.");
+  (callback)(data);
+}
Index: client/gui-stub/gui_main.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-stub/gui_main.c,v
retrieving revision 1.14
diff -u -r1.14 gui_main.c
--- client/gui-stub/gui_main.c  5 Dec 2004 04:23:19 -0000       1.14
+++ client/gui-stub/gui_main.c  9 Feb 2005 22:23:11 -0000
@@ -107,3 +107,17 @@
 {
   /* PORTME */
 }
+
+/****************************************************************************
+  Enqueue a callback to be called during an idle moment.  The 'callback'
+  function should be called sometimes soon, and passed the 'data' pointer
+  as its data.
+****************************************************************************/
+void add_idle_callback(void (callback)(void *), void *data)
+{
+  /* PORTME */
+
+  /* This is a reasonable fallback if it's not ported. */
+  freelog(LOG_ERROR, "Unimplemented add_idle_callback.");
+  (callback)(data);
+}
Index: client/gui-win32/gui_main.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-win32/gui_main.c,v
retrieving revision 1.37
diff -u -r1.37 gui_main.c
--- client/gui-win32/gui_main.c 21 Jan 2005 02:14:08 -0000      1.37
+++ client/gui-win32/gui_main.c 9 Feb 2005 22:23:11 -0000
@@ -645,3 +645,17 @@
 {
        /* PORTME */
 }
+
+/****************************************************************************
+  Enqueue a callback to be called during an idle moment.  The 'callback'
+  function should be called sometimes soon, and passed the 'data' pointer
+  as its data.
+****************************************************************************/
+void add_idle_callback(void (callback)(void *), void *data)
+{
+  /* PORTME */
+
+  /* This is a reasonable fallback if it's not ported. */
+  freelog(LOG_ERROR, "Unimplemented add_idle_callback.");
+  (callback)(data);
+}
Index: client/gui-xaw/gui_main.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-xaw/gui_main.c,v
retrieving revision 1.99
diff -u -r1.99 gui_main.c
--- client/gui-xaw/gui_main.c   1 Dec 2004 22:15:23 -0000       1.99
+++ client/gui-xaw/gui_main.c   9 Feb 2005 22:23:12 -0000
@@ -890,3 +890,17 @@
     showing = FALSE;
   }
 }
+
+/****************************************************************************
+  Enqueue a callback to be called during an idle moment.  The 'callback'
+  function should be called sometimes soon, and passed the 'data' pointer
+  as its data.
+****************************************************************************/
+void add_idle_callback(void (callback)(void *), void *data)
+{
+  /* PORTME */
+
+  /* This is a reasonable fallback if it's not ported. */
+  freelog(LOG_ERROR, "Unimplemented add_idle_callback.");
+  (callback)(data);
+}
Index: client/include/gui_main_g.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/include/gui_main_g.h,v
retrieving revision 1.10
diff -u -r1.10 gui_main_g.h
--- client/include/gui_main_g.h 3 Sep 2004 04:22:36 -0000       1.10
+++ client/include/gui_main_g.h 9 Feb 2005 22:23:12 -0000
@@ -27,6 +27,8 @@
 void set_unit_icon(int idx, struct unit *punit);
 void set_unit_icons_more_arrow(bool onoff);
 
+void add_idle_callback(void (callback)(void *), void *data);
+
 extern const char *client_string;
 
 #endif  /* FC__GUI_MAIN_G_H */

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