Complete.Org: Mailing Lists: Archives: freeciv-dev: December 2002:
[Freeciv-Dev] (PR#2509) unification of update_map_canvas
Home

[Freeciv-Dev] (PR#2509) unification of update_map_canvas

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
Cc: freeciv-dev@xxxxxxxxxxx
Subject: [Freeciv-Dev] (PR#2509) unification of update_map_canvas
From: "Jason Short via RT" <rt@xxxxxxxxxxxxxx>
Date: Sun, 29 Dec 2002 13:54:27 -0800
Reply-to: rt@xxxxxxxxxxxxxx

This version fixes a couple of obvious bugs in the win32 client.  The
win32 client still doesn't completely work, though.

jason

Index: client/mapview_common.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/mapview_common.c,v
retrieving revision 1.23
diff -u -r1.23 mapview_common.c
--- client/mapview_common.c     2002/12/18 15:59:27     1.23
+++ client/mapview_common.c     2002/12/29 21:34:55
@@ -378,6 +378,181 @@
 }
 
 /**************************************************************************
+  Draw the unique tile for the given (unnormalized) map position, in
+  non-isometric view.
+**************************************************************************/
+static void put_tile(int map_x, int map_y)
+{
+  int canvas_x, canvas_y;
+
+  if (get_canvas_xy(map_x, map_y, &canvas_x, &canvas_y)) {
+    freelog(LOG_DEBUG, "putting (%d,%d) at (%d,%d)",
+           map_x, map_y, canvas_x, canvas_y);
+    put_one_tile(map_x, map_y, canvas_x, canvas_y);
+  }
+}
+
+/**************************************************************************
+  Draw the unique tile for the given (unnormalized) map position, in
+  isometric view.
+**************************************************************************/
+static void put_tile_iso(int map_x, int map_y, enum draw_type draw)
+{
+  int canvas_x, canvas_y;
+
+  if (get_canvas_xy(map_x, map_y, &canvas_x, &canvas_y)) {
+    freelog(LOG_DEBUG, "putting (%d,%d) at (%d,%d), draw %x",
+           map_x, map_y, canvas_x, canvas_y, draw);
+    put_one_tile_iso(map_x, map_y, canvas_x, canvas_y, draw);
+  }
+}
+
+/**************************************************************************
+  Update (refresh) the map canvas starting at the given tile (in map
+  coordinates) and with the given dimensions (also in map coordinates).
+
+  In non-iso view, this is easy.  In iso view, we have to use the
+  Painter's Algorithm to draw the tiles in back first.  When we draw
+  a tile, we tell the GUI which part of the tile to draw - which is
+  necessary for clients that don't do manual buffering.
+
+  After refreshing the backing store tile-by-tile, we write the store
+  out to the display if write_to_screen is specified.
+
+  x, y, width, and height are in unnormalized map coordinates.
+**************************************************************************/
+void update_map_canvas(int x, int y, int width, int height, 
+                      bool write_to_screen)
+{
+  freelog(LOG_DEBUG,
+         "update_map_canvas(pos=(%d,%d), size=(%d,%d), write_to_screen=%d)",
+         x, y, width, height, write_to_screen);
+
+  if (is_isometric) {
+    int x_itr, y_itr, i;
+
+    /* First refresh the tiles above the area to remove the old tiles'
+     * overlapping graphics. */
+    put_tile_iso(x - 1, y - 1, D_B_LR); /* top_left corner */
+
+    for (i = 0; i < height - 1; i++) { /* left side - last tile. */
+      put_tile_iso(x - 1, y + i, D_MB_LR);
+    }
+    put_tile_iso(x - 1, y + height - 1, D_TMB_R); /* last tile left side. */
+
+    for (i = 0; i < width - 1; i++) {
+      /* top side */
+      put_tile_iso(x + i, y - 1, D_MB_LR);
+    }
+    if (width > 1) {
+      /* last tile top side. */
+      put_tile_iso(x + width - 1, y - 1, D_TMB_L);
+    } else {
+      put_tile_iso(x + width - 1, y - 1, D_MB_L);
+    }
+
+    /* Now draw the tiles to be refreshed, from the top down to get the
+     * overlapping areas correct. */
+    for (x_itr = x; x_itr < x + width; x_itr++) {
+      for (y_itr = y; y_itr < y + height; y_itr++) {
+       put_tile_iso(x_itr, y_itr, D_FULL);
+      }
+    }
+
+    /* Then draw the tiles underneath to refresh the parts of them that
+     * overlap onto the area just drawn. */
+    put_tile_iso(x, y + height, D_TM_R);  /* bottom side */
+    for (i = 1; i < width; i++) {
+      int x1 = x + i;
+      int y1 = y + height;
+      put_tile_iso(x1, y1, D_TM_R);
+      put_tile_iso(x1, y1, D_T_L);
+    }
+
+    put_tile_iso(x + width, y, D_TM_L); /* right side */
+    for (i=1; i < height; i++) {
+      int x1 = x + width;
+      int y1 = y + i;
+      put_tile_iso(x1, y1, D_TM_L);
+      put_tile_iso(x1, y1, D_T_R);
+    }
+
+    put_tile_iso(x + width, y + height, D_T_LR); /* right-bottom corner */
+
+
+    /* Draw the goto lines on top of the whole thing. This is done last as
+     * we want it completely on top. */
+    for (x_itr = x - 1; x_itr <= x + width; x_itr++) {
+      for (y_itr = y - 1; y_itr <= y + height; y_itr++) {
+       int x1 = x_itr;
+       int y1 = y_itr;
+       if (normalize_map_pos(&x1, &y1)) {
+         adjc_dir_iterate(x1, y1, x2, y2, dir) {
+           if (get_drawn(x1, y1, dir)) {
+             draw_segment(x1, y1, dir);
+           }
+         } adjc_dir_iterate_end;
+       }
+      }
+    }
+
+
+    /* Lastly draw our changes to the screen. */
+    if (write_to_screen) {
+      int canvas_start_x, canvas_start_y;
+
+      /* top left corner */
+      get_canvas_xy(x, y, &canvas_start_x, &canvas_start_y);
+
+      /* top left corner in isometric view */
+      canvas_start_x -= height * NORMAL_TILE_WIDTH / 2;
+
+      /* because of where get_canvas_xy() sets canvas_x */
+      canvas_start_x += NORMAL_TILE_WIDTH / 2;
+
+      /* And because units fill a little extra */
+      canvas_start_y -= NORMAL_TILE_HEIGHT / 2;
+
+      /* Here we draw a rectangle that includes the updated tiles.  This
+       * method can fail if the area wraps off one side of the screen and
+       * back to the other (although this will not be a problem for
+       * update_map_canvas_visible(). */
+      flush_mapcanvas(canvas_start_x, canvas_start_y,
+                     (height + width) * NORMAL_TILE_WIDTH / 2,
+                     (height + width) * NORMAL_TILE_HEIGHT / 2
+                     + NORMAL_TILE_HEIGHT / 2);
+    }
+
+  } else {
+    /* not isometric */
+    int map_x, map_y;
+
+    for (map_y = y; map_y < y + height; map_y++) {
+      for (map_x = x; map_x < x + width; map_x++) {
+       /*
+        * We don't normalize until later because we want to draw
+        * black tiles for unreal positions.
+        */
+       put_tile(map_x, map_y);
+      }
+    }
+
+    if (write_to_screen) {
+      int canvas_x, canvas_y;
+
+      /* Here we draw a rectangle that includes the updated tiles.  This
+       * method can fail if the area wraps off one side of the screen and
+       * back to the other (although this will not be a problem for
+       * update_map_canvas_visible(). */
+      get_canvas_xy(x, y, &canvas_x, &canvas_y);
+      flush_mapcanvas(canvas_x, canvas_y,
+                     width * NORMAL_TILE_WIDTH,
+                     height * NORMAL_TILE_HEIGHT);
+    }
+  }
+}
+
+/**************************************************************************
  Update (only) the visible part of the map
 **************************************************************************/
 void update_map_canvas_visible(void)
Index: client/mapview_common.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/mapview_common.h,v
retrieving revision 1.17
diff -u -r1.17 mapview_common.h
--- client/mapview_common.h     2002/12/18 15:59:27     1.17
+++ client/mapview_common.h     2002/12/29 21:34:55
@@ -130,6 +130,8 @@
 bool tile_visible_mapcanvas(int map_x, int map_y);
 bool tile_visible_and_not_on_border_mapcanvas(int map_x, int map_y);
 
+void update_map_canvas(int x, int y, int width, int height,
+                      bool write_to_screen);
 void update_map_canvas_visible(void);
 
 void show_city_descriptions(void);
Index: client/gui-gtk/mapview.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-gtk/mapview.c,v
retrieving revision 1.145
diff -u -r1.145 mapview.c
--- client/gui-gtk/mapview.c    2002/12/18 15:59:27     1.145
+++ client/gui-gtk/mapview.c    2002/12/29 21:34:56
@@ -879,20 +879,25 @@
 }
 
 /**************************************************************************
-Only used for isometric view.
+  Draw the given map tile at the given canvas position in non-isometric
+  view.
 **************************************************************************/
-static void put_one_tile(int x, int y, enum draw_type draw)
+void put_one_tile(int map_x, int map_y, int canvas_x, int canvas_y)
 {
-  int canvas_x, canvas_y;
+  pixmap_put_tile(map_canvas_store, map_x, map_y, canvas_x, canvas_y,
+                 FALSE);
+}
+
+/**************************************************************************
+  Draw the given map tile at the given canvas position in isometric
+  view.
+**************************************************************************/
+void put_one_tile_iso(int x, int y, int canvas_x, int canvas_y,
+                     enum draw_type draw)
+{
   int height, width, height_unit;
   int offset_x, offset_y, offset_y_unit;
 
-  if (!tile_visible_mapcanvas(x, y)) {
-    freelog(LOG_DEBUG, "dropping %d,%d", x, y);
-    return;
-  }
-  freelog(LOG_DEBUG, "putting %d,%d draw %x", x, y, draw);
-
   width = (draw & D_TMB_L) && (draw & D_TMB_R) ? NORMAL_TILE_WIDTH : 
NORMAL_TILE_WIDTH/2;
   if (!(draw & D_TMB_L))
     offset_x = NORMAL_TILE_WIDTH/2;
@@ -913,163 +918,28 @@
   else
     offset_y_unit = 0;
 
-  /* returns whether the tile is visible. */
-  if (get_canvas_xy(x, y, &canvas_x, &canvas_y)) {
-    if (normalize_map_pos(&x, &y)) {
-      pixmap_put_tile_iso(map_canvas_store, x, y, canvas_x, canvas_y, 0,
-                         offset_x, offset_y, offset_y_unit,
-                         width, height, height_unit,
-                         draw);
-    } else {
-      pixmap_put_black_tile_iso(map_canvas_store, canvas_x, canvas_y,
-                               offset_x, offset_y,
-                               width, height);
-    }
+  if (normalize_map_pos(&x, &y)) {
+    pixmap_put_tile_iso(map_canvas_store, x, y, canvas_x, canvas_y, 0,
+                       offset_x, offset_y, offset_y_unit,
+                       width, height, height_unit,
+                       draw);
+  } else {
+    pixmap_put_black_tile_iso(map_canvas_store, canvas_x, canvas_y,
+                             offset_x, offset_y,
+                             width, height);
   }
 }
 
 /**************************************************************************
-Refresh and draw to sceen all the tiles in a rectangde width,height (as
-seen in overhead ciew) with the top corner at x,y.
-All references to "left","right", "top" and "bottom" refer to the sides of
-the rectangle width, height as it would be seen in top-down view, unless
-said otherwise.
-The trick is to draw tiles furthest up on the map first, since we will be
-drawing on top of them when we draw tiles further down.
-
-Works by first refreshing map_canvas_store and then drawing the result to
-the screen.
+  Flush the given part of the canvas buffer (if there is one) to the
+  screen.
 **************************************************************************/
-void update_map_canvas(int x, int y, int width, int height, 
-                      bool write_to_screen)
+void flush_mapcanvas(int canvas_x, int canvas_y,
+                    int pixel_width, int pixel_height)
 {
-  freelog(LOG_DEBUG,
-         "update_map_canvas(pos=(%d,%d), size=(%d,%d), write_to_screen=%d)",
-         x, y, width, height, write_to_screen);
-
-  if (is_isometric) {
-    int i;
-    int x_itr, y_itr;
-
-    /*** First refresh the tiles above the area to remove the old tiles'
-        overlapping gfx ***/
-    put_one_tile(x-1, y-1, D_B_LR); /* top_left corner */
-
-    for (i=0; i<height-1; i++) { /* left side - last tile. */
-      int x1 = x - 1;
-      int y1 = y + i;
-      put_one_tile(x1, y1, D_MB_LR);
-    }
-    put_one_tile(x-1, y+height-1, D_TMB_R); /* last tile left side. */
-
-    for (i=0; i<width-1; i++) { /* top side */
-      int x1 = x + i;
-      int y1 = y - 1;
-      put_one_tile(x1, y1, D_MB_LR);
-    }
-    if (width > 1) /* last tile top side. */
-      put_one_tile(x+width-1, y-1, D_TMB_L);
-    else
-      put_one_tile(x+width-1, y-1, D_MB_L);
-
-    /*** Now draw the tiles to be refreshed, from the top down to get the
-        overlapping areas correct ***/
-    for (x_itr = x; x_itr < x+width; x_itr++) {
-      for (y_itr = y; y_itr < y+height; y_itr++) {
-       put_one_tile(x_itr, y_itr, D_FULL);
-      }
-    }
-
-    /*** Then draw the tiles underneath to refresh the parts of them that
-        overlap onto the area just drawn ***/
-    put_one_tile(x, y+height, D_TM_R);  /* bottom side */
-    for (i=1; i<width; i++) {
-      int x1 = x + i;
-      int y1 = y + height;
-      put_one_tile(x1, y1, D_TM_R);
-      put_one_tile(x1, y1, D_T_L);
-    }
-
-    put_one_tile(x+width, y, D_TM_L); /* right side */
-    for (i=1; i < height; i++) {
-      int x1 = x + width;
-      int y1 = y + i;
-      put_one_tile(x1, y1, D_TM_L);
-      put_one_tile(x1, y1, D_T_R);
-    }
-
-    put_one_tile(x+width, y+height, D_T_LR); /* right-bottom corner */
-
-
-    /*** Draw the goto line on top of the whole thing. Done last as
-        we want it completely on top. ***/
-    /* Drawing is cheap; we just draw all the lines.
-       Perhaps this should be optimized, though... */
-    for (x_itr = x-1; x_itr <= x+width; x_itr++) {
-      for (y_itr = y-1; y_itr <= y+height; y_itr++) {
-       int x1 = x_itr;
-       int y1 = y_itr;
-       if (normalize_map_pos(&x1, &y1)) {
-         adjc_dir_iterate(x1, y1, x2, y2, dir) {
-           if (get_drawn(x1, y1, dir)) {
-             really_draw_segment(x1, y1, dir, FALSE, TRUE);
-           }
-         } adjc_dir_iterate_end;
-       }
-      }
-    }
-
-
-    /*** Lastly draw our changes to the screen. ***/
-    if (write_to_screen) {
-      int canvas_start_x, canvas_start_y;
-      get_canvas_xy(x, y, &canvas_start_x, &canvas_start_y); /* top left 
corner */
-      /* top left corner in isometric view */
-      canvas_start_x -= height * NORMAL_TILE_WIDTH/2;
-
-      /* because of where get_canvas_xy() sets canvas_x */
-      canvas_start_x += NORMAL_TILE_WIDTH/2;
-
-      /* And because units fill a little extra */
-      canvas_start_y -= NORMAL_TILE_HEIGHT/2;
-
-      /* here we draw a rectangle that includes the updated tiles. */
-      gdk_draw_pixmap(map_canvas->window, civ_gc, map_canvas_store,
-                     canvas_start_x, canvas_start_y,
-                     canvas_start_x, canvas_start_y,
-                     (height + width) * NORMAL_TILE_WIDTH/2,
-                     (height + width) * NORMAL_TILE_HEIGHT/2 + 
NORMAL_TILE_HEIGHT/2);
-    }
-
-  } else { /* is_isometric */
-    int map_x, map_y;
-
-    for (map_y = y; map_y < y + height; map_y++) {
-      for (map_x = x; map_x < x + width; map_x++) {
-       int canvas_x, canvas_y;
-
-       /*
-        * We don't normalize until later because we want to draw
-        * black tiles for unreal positions.
-        */
-       if (get_canvas_xy(map_x, map_y, &canvas_x, &canvas_y)) {
-         pixmap_put_tile(map_canvas_store,
-                         map_x, map_y, canvas_x, canvas_y, 0);
-       }
-      }
-    }
-
-    if (write_to_screen) {
-      int canvas_x, canvas_y;
-
-      get_canvas_xy(x, y, &canvas_x, &canvas_y);
-      gdk_draw_pixmap(map_canvas->window, civ_gc, map_canvas_store,
-                     canvas_x, canvas_y,
-                     canvas_x, canvas_y,
-                     width*NORMAL_TILE_WIDTH,
-                     height*NORMAL_TILE_HEIGHT);
-    }
-  }
+  gdk_draw_pixmap(map_canvas->window, civ_gc, map_canvas_store,
+                 canvas_x, canvas_y, canvas_x, canvas_y,
+                 pixel_width, pixel_height);
 }
 
 /**************************************************************************
Index: client/gui-gtk-2.0/mapview.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-gtk-2.0/mapview.c,v
retrieving revision 1.33
diff -u -r1.33 mapview.c
--- client/gui-gtk-2.0/mapview.c        2002/12/18 15:59:27     1.33
+++ client/gui-gtk-2.0/mapview.c        2002/12/29 21:34:57
@@ -907,20 +907,25 @@
 }
 
 /**************************************************************************
-Only used for isometric view.
+  Draw the given map tile at the given canvas position in non-isometric
+  view.
 **************************************************************************/
-static void put_one_tile(int x, int y, enum draw_type draw)
+void put_one_tile(int map_x, int map_y, int canvas_x, int canvas_y)
 {
-  int canvas_x, canvas_y;
+  pixmap_put_tile(map_canvas_store, map_x, map_y, canvas_x, canvas_y,
+                 FALSE);
+}
+
+/**************************************************************************
+  Draw the given map tile at the given canvas position in isometric
+  view.
+**************************************************************************/
+void put_one_tile_iso(int x, int y, int canvas_x, int canvas_y,
+                     enum draw_type draw)
+{
   int height, width, height_unit;
   int offset_x, offset_y, offset_y_unit;
 
-  if (!tile_visible_mapcanvas(x, y)) {
-    freelog(LOG_DEBUG, "dropping %d,%d", x, y);
-    return;
-  }
-  freelog(LOG_DEBUG, "putting %d,%d draw %x", x, y, draw);
-
   width = (draw & D_TMB_L) && (draw & D_TMB_R) ? NORMAL_TILE_WIDTH : 
NORMAL_TILE_WIDTH/2;
   if (!(draw & D_TMB_L))
     offset_x = NORMAL_TILE_WIDTH/2;
@@ -941,163 +946,28 @@
   else
     offset_y_unit = 0;
 
-  /* returns whether the tile is visible. */
-  if (get_canvas_xy(x, y, &canvas_x, &canvas_y)) {
-    if (normalize_map_pos(&x, &y)) {
-      pixmap_put_tile_iso(map_canvas_store, x, y, canvas_x, canvas_y, 0,
-                         offset_x, offset_y, offset_y_unit,
-                         width, height, height_unit,
-                         draw);
-    } else {
-      pixmap_put_black_tile_iso(map_canvas_store, canvas_x, canvas_y,
-                               offset_x, offset_y,
-                               width, height);
-    }
+  if (normalize_map_pos(&x, &y)) {
+    pixmap_put_tile_iso(map_canvas_store, x, y, canvas_x, canvas_y, 0,
+                       offset_x, offset_y, offset_y_unit,
+                       width, height, height_unit,
+                       draw);
+  } else {
+    pixmap_put_black_tile_iso(map_canvas_store, canvas_x, canvas_y,
+                             offset_x, offset_y,
+                             width, height);
   }
 }
 
 /**************************************************************************
-Refresh and draw to sceen all the tiles in a rectangde width,height (as
-seen in overhead ciew) with the top corner at x,y.
-All references to "left","right", "top" and "bottom" refer to the sides of
-the rectangle width, height as it would be seen in top-down view, unless
-said otherwise.
-The trick is to draw tiles furthest up on the map first, since we will be
-drawing on top of them when we draw tiles further down.
-
-Works by first refreshing map_canvas_store and then drawing the result to
-the screen.
+  Flush the given part of the canvas buffer (if there is one) to the
+  screen.
 **************************************************************************/
-void update_map_canvas(int x, int y, int width, int height, 
-                      bool write_to_screen)
+void flush_mapcanvas(int canvas_x, int canvas_y,
+                    int pixel_width, int pixel_height)
 {
-  freelog(LOG_DEBUG,
-         "update_map_canvas(pos=(%d,%d), size=(%d,%d), write_to_screen=%d)",
-         x, y, width, height, write_to_screen);
-
-  if (is_isometric) {
-    int i;
-    int x_itr, y_itr;
-
-    /*** First refresh the tiles above the area to remove the old tiles'
-        overlapping gfx ***/
-    put_one_tile(x-1, y-1, D_B_LR); /* top_left corner */
-
-    for (i=0; i<height-1; i++) { /* left side - last tile. */
-      int x1 = x - 1;
-      int y1 = y + i;
-      put_one_tile(x1, y1, D_MB_LR);
-    }
-    put_one_tile(x-1, y+height-1, D_TMB_R); /* last tile left side. */
-
-    for (i=0; i<width-1; i++) { /* top side */
-      int x1 = x + i;
-      int y1 = y - 1;
-      put_one_tile(x1, y1, D_MB_LR);
-    }
-    if (width > 1) /* last tile top side. */
-      put_one_tile(x+width-1, y-1, D_TMB_L);
-    else
-      put_one_tile(x+width-1, y-1, D_MB_L);
-
-    /*** Now draw the tiles to be refreshed, from the top down to get the
-        overlapping areas correct ***/
-    for (x_itr = x; x_itr < x+width; x_itr++) {
-      for (y_itr = y; y_itr < y+height; y_itr++) {
-       put_one_tile(x_itr, y_itr, D_FULL);
-      }
-    }
-
-    /*** Then draw the tiles underneath to refresh the parts of them that
-        overlap onto the area just drawn ***/
-    put_one_tile(x, y+height, D_TM_R);  /* bottom side */
-    for (i=1; i<width; i++) {
-      int x1 = x + i;
-      int y1 = y + height;
-      put_one_tile(x1, y1, D_TM_R);
-      put_one_tile(x1, y1, D_T_L);
-    }
-
-    put_one_tile(x+width, y, D_TM_L); /* right side */
-    for (i=1; i < height; i++) {
-      int x1 = x + width;
-      int y1 = y + i;
-      put_one_tile(x1, y1, D_TM_L);
-      put_one_tile(x1, y1, D_T_R);
-    }
-
-    put_one_tile(x+width, y+height, D_T_LR); /* right-bottom corner */
-
-
-    /*** Draw the goto line on top of the whole thing. Done last as
-        we want it completely on top. ***/
-    /* Drawing is cheap; we just draw all the lines.
-       Perhaps this should be optimized, though... */
-    for (x_itr = x-1; x_itr <= x+width; x_itr++) {
-      for (y_itr = y-1; y_itr <= y+height; y_itr++) {
-       int x1 = x_itr;
-       int y1 = y_itr;
-       if (normalize_map_pos(&x1, &y1)) {
-         adjc_dir_iterate(x1, y1, x2, y2, dir) {
-           if (get_drawn(x1, y1, dir)) {
-             really_draw_segment(x1, y1, dir, FALSE, TRUE);
-           }
-         } adjc_dir_iterate_end;
-       }
-      }
-    }
-
-
-    /*** Lastly draw our changes to the screen. ***/
-    if (write_to_screen) {
-      int canvas_start_x, canvas_start_y;
-      get_canvas_xy(x, y, &canvas_start_x, &canvas_start_y); /* top left 
corner */
-      /* top left corner in isometric view */
-      canvas_start_x -= height * NORMAL_TILE_WIDTH/2;
-
-      /* because of where get_canvas_xy() sets canvas_x */
-      canvas_start_x += NORMAL_TILE_WIDTH/2;
-
-      /* And because units fill a little extra */
-      canvas_start_y -= NORMAL_TILE_HEIGHT/2;
-
-      /* here we draw a rectangle that includes the updated tiles. */
-      gdk_draw_pixmap(map_canvas->window, civ_gc, map_canvas_store,
-                     canvas_start_x, canvas_start_y,
-                     canvas_start_x, canvas_start_y,
-                     (height + width) * NORMAL_TILE_WIDTH/2,
-                     (height + width) * NORMAL_TILE_HEIGHT/2 + 
NORMAL_TILE_HEIGHT/2);
-    }
-
-  } else { /* is_isometric */
-    int map_x, map_y;
-
-    for (map_y = y; map_y < y + height; map_y++) {
-      for (map_x = x; map_x < x + width; map_x++) {
-       int canvas_x, canvas_y;
-
-       /*
-        * We don't normalize until later because we want to draw
-        * black tiles for unreal positions.
-        */
-       if (get_canvas_xy(map_x, map_y, &canvas_x, &canvas_y)) {
-         pixmap_put_tile(map_canvas_store,
-                         map_x, map_y, canvas_x, canvas_y, 0);
-       }
-      }
-    }
-
-    if (write_to_screen) {
-      int canvas_x, canvas_y;
-
-      get_canvas_xy(x, y, &canvas_x, &canvas_y);
-      gdk_draw_pixmap(map_canvas->window, civ_gc, map_canvas_store,
-                     canvas_x, canvas_y,
-                     canvas_x, canvas_y,
-                     width*NORMAL_TILE_WIDTH,
-                     height*NORMAL_TILE_HEIGHT);
-    }
-  }
+  gdk_draw_pixmap(map_canvas->window, civ_gc, map_canvas_store,
+                 canvas_x, canvas_y, canvas_x, canvas_y,
+                 pixel_width, pixel_height);
 }
 
 /**************************************************************************
Index: client/gui-stub/mapview.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-stub/mapview.c,v
retrieving revision 1.23
diff -u -r1.23 mapview.c
--- client/gui-stub/mapview.c   2002/12/18 15:59:28     1.23
+++ client/gui-stub/mapview.c   2002/12/29 21:34:57
@@ -184,17 +184,34 @@
 }
 
 /**************************************************************************
-  Update (refresh) the map canvas starting at the given tile (in map
-  coordinates) and with the given dimensions (also in map coordinates).
+  Draw the given map tile at the given canvas position in non-isometric
+  view.
+**************************************************************************/
+void put_one_tile(int map_x, int map_y, int canvas_x, int canvas_y)
+{
+  /* PORTME */
+}
+
+/**************************************************************************
+  Draw the given map tile at the given canvas position in isometric
+  view.
+**************************************************************************/
+void put_one_tile_iso(int map_x, int map_y, int canvas_x, int canvas_y,
+                     enum draw_type draw)
+{
+  /* PORTME */
+}
 
-  This function contains a lot of the drawing logic.  It is very similar
-  in each GUI.
+/**************************************************************************
+  Flush the given part of the canvas buffer (if there is one) to the
+  screen.
 **************************************************************************/
-void update_map_canvas(int tile_x, int tile_y, int width, int height,
-                      bool write_to_screen)
+void flush_mapcanvas(int canvas_x, int canvas_y,
+                    int pixel_width, int pixel_height)
 {
   /* PORTME */
 }
+
 
 /**************************************************************************
   Update (refresh) the locations of the mapview scrollbars (if it uses
Index: client/gui-win32/mapview.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-win32/mapview.c,v
retrieving revision 1.46
diff -u -r1.46 mapview.c
--- client/gui-win32/mapview.c  2002/12/22 13:12:09     1.46
+++ client/gui-win32/mapview.c  2002/12/29 21:34:57
@@ -67,7 +67,6 @@
 void update_map_canvas_scrollbars_size(void);
 void refresh_overview_viewrect_real(HDC hdcp);
 void set_overview_win_dim(int w,int h);
-static void put_one_tile(HDC mapstoredc,int x, int y, enum draw_type draw);
 void put_one_tile_full(HDC hdc, int x, int y,
                              int canvas_x, int canvas_y, int citymode);
 static void pixmap_put_tile_iso(HDC hdc, int x, int y,
@@ -636,148 +635,42 @@
 }
 
 /**************************************************************************
-
+  Draw the given map tile at the given canvas position in non-isometric
+  view.
 **************************************************************************/
-void
-update_map_canvas(int x, int y, int width, int height,
-                 bool write_to_screen)
+void put_one_tile(int map_x, int map_y, int canvas_x, int canvas_y)
 {
   HDC mapstoredc;
   HBITMAP old;
-  mapstoredc=CreateCompatibleDC(NULL);
-  old=SelectObject(mapstoredc,mapstorebitmap);
-  if (!is_isometric) {
-    int map_x, map_y;
-    int canvas_x,canvas_y;
-    int old_x;
-    old_x=-1;
-    for(map_y=y; map_y<y+height; map_y++)
-      for(map_x=x; map_x<x+width; map_x++) {
-       /*
-        * We don't normalize until later because we want to draw
-        * black tiles for unreal positions.
-        */
-       if (get_canvas_xy(map_x,map_y,&canvas_x,&canvas_y))
-         {
-           old_x=map_x;
-           pixmap_put_tile(mapstoredc, map_x, map_y,
-                           canvas_x,canvas_y, 0);
-         }
-      }
-    if (write_to_screen)
-      {
-       int scr_x,scr_y;
-       HDC whdc;
-       whdc=GetDC(map_window);
-       get_canvas_xy(x,y,&scr_x,&scr_y);
-       BitBlt(whdc,scr_x,
-              scr_y,
-              NORMAL_TILE_WIDTH*width,NORMAL_TILE_HEIGHT*height,mapstoredc,
-              scr_x,
-              scr_y,
-              SRCCOPY);
-       show_city_descriptions();       /* is this necessary? */
-       ReleaseDC(map_window,whdc);
-      }
-  } else {
-    int i,x_itr,y_itr;
-    
-    put_one_tile(mapstoredc,x-1,y-1,D_B_LR);
-    for(i=0;i<height-1;i++) {
-      int x1 = x - 1;
-      int y1 = y + i;
-      put_one_tile(mapstoredc,x1, y1, D_MB_LR);
-      
-    }
-    put_one_tile(mapstoredc,
-                x-1, y+height-1, D_TMB_R); /* last tile left side. */
-    
-    for (i=0; i<width-1; i++) { /* top side */
-      int x1 = x + i;
-      int y1 = y - 1;
-      put_one_tile(mapstoredc,
-                  x1, y1, D_MB_LR);
-    }
-    if (width > 1) /* last tile top side. */
-      put_one_tile(mapstoredc,
-                  x+width-1, y-1, D_TMB_L);
-    else
-      put_one_tile(mapstoredc,
-                  x+width-1, y-1, D_MB_L);
-    /*** Now draw the tiles to be refreshed, from the top down to get the
-         overlapping areas correct ***/
-    for (x_itr = x; x_itr < x+width; x_itr++) {
-      for (y_itr = y; y_itr < y+height; y_itr++) {
-       put_one_tile(mapstoredc,x_itr, y_itr, D_FULL);
-      }
-    }
-    
-      /*** Then draw the tiles underneath to refresh the parts of them that
-          overlap onto the area just drawn ***/
-    put_one_tile(mapstoredc,x, y+height, D_TM_R);  /* bottom side */
-    for (i=1; i<width; i++) {
-      int x1 = x + i;
-      int y1 = y + height;
-      put_one_tile(mapstoredc,x1, y1, D_TM_R);
-      put_one_tile(mapstoredc,x1, y1, D_T_L);
-    }
-    
-    put_one_tile(mapstoredc,x+width, y, D_TM_L); /* right side */
-    for (i=1; i < height; i++) {
-      int x1 = x + width;
-      int y1 = y + i;
-      put_one_tile(mapstoredc,x1, y1, D_TM_L);
-      put_one_tile(mapstoredc,x1, y1, D_T_R);
-    }
 
-    put_one_tile(mapstoredc,
-                x+width, y+height, D_T_LR); /* right-bottom corner */
+  /* FIXME: we don't want to have to recreate the hdc each time! */
+  mapstoredc = CreateCompatibleDC(NULL);
+  old = SelectObject(mapstoredc, mapstorebitmap);
 
-    /*** Draw the goto line on top of the whole thing. Done last as
-        we want it completely on top. ***/
-    /* Drawing is cheap; we just draw all the lines.
-       Perhaps this should be optimized, though... */
-    for (x_itr = x-1; x_itr <= x+width; x_itr++) {
-      for (y_itr = y-1; y_itr <= y+height; y_itr++) {
-       int x1 = x_itr;
-       int y1 = y_itr;
-       if (normalize_map_pos(&x1, &y1)) {
-         adjc_dir_iterate(x1, y1, x2, y2, dir) {
-           if (get_drawn(x1, y1, dir)) {
-             really_draw_segment(mapstoredc,x1, y1, dir, FALSE, TRUE);
-           }
-         } adjc_dir_iterate_end;
-       }
-      } 
-    }
-    
-    if (write_to_screen) {
-      HDC hdc;
-      int canvas_start_x, canvas_start_y;
-      get_canvas_xy(x, y, &canvas_start_x, &canvas_start_y); /* top left 
corner */
-      /* top left corner in isometric view */
-      canvas_start_x -= height * NORMAL_TILE_WIDTH/2;
-      
-      /* because of where get_canvas_xy() sets canvas_x */
-      canvas_start_x += NORMAL_TILE_WIDTH/2;
-      
-      /* And because units fill a little extra */
-      canvas_start_y -= NORMAL_TILE_HEIGHT/2;
-      
-      /* here we draw a rectangle that includes the updated tiles. */
-      hdc=GetDC(map_window);
-      BitBlt(hdc,canvas_start_x,canvas_start_y,
-            (height + width) * NORMAL_TILE_WIDTH/2,
-            (height + width) * NORMAL_TILE_HEIGHT/2 + NORMAL_TILE_HEIGHT/2,
-            mapstoredc,
-            canvas_start_x,canvas_start_y,SRCCOPY);
-      show_city_descriptions(); /* is this necessary? */
-      ReleaseDC(map_window,hdc);
-    }
+  pixmap_put_tile(mapstoredc, map_x, map_y,
+                 canvas_x, canvas_y, FALSE);
 
+  SelectObject(mapstoredc, old);
+  DeleteDC(mapstoredc);
+}
 
-  }
-  SelectObject(mapstoredc,old);
+/**************************************************************************
+  Flush the given part of the canvas buffer (if there is one) to the
+  screen.
+**************************************************************************/
+void flush_mapcanvas(int canvas_x, int canvas_y,
+                    int pixel_width, int pixel_height)
+{
+  HDC hdcwin = GetDC(map_window);
+  HDC mapstoredc = CreateCompatibleDC(NULL);
+  HBITMAP old = SelectObject(mapstoredc, mapstorebitmap);
+  BitBlt(hdcwin, canvas_x, canvas_y,
+        pixel_width, pixel_height,
+        mapstoredc,
+        canvas_x, canvas_y,
+        SRCCOPY);
+  ReleaseDC(map_window, hdcwin);
+  SelectObject(mapstoredc, old);
   DeleteDC(mapstoredc);
 }
 
@@ -1434,19 +1327,20 @@
 
 
 /**************************************************************************
-Only used for isometric view.
+  Draw the given map tile at the given canvas position in isometric
+  view.
 **************************************************************************/
-static void put_one_tile(HDC mapstoredc,int x, int y, enum draw_type draw)
+void put_one_tile_iso(int x, int y, int canvas_x, int canvas_y,
+                     enum draw_type draw)
 {
-  int canvas_x, canvas_y;
+  HDC hdc;
+  HBITMAP old;
   int height, width, height_unit;
   int offset_x, offset_y, offset_y_unit;
-  
-  if (!tile_visible_mapcanvas(x, y)) {
-    freelog(LOG_DEBUG, "dropping %d,%d", x, y);
-    return;
-  }
-  freelog(LOG_DEBUG, "putting %d,%d draw %x", x, y, draw);
+
+  /* FIXME: we don't want to have to recreate the hdc each time! */
+  hdc = CreateCompatibleDC(NULL);
+  old = SelectObject(hdc, mapstorebitmap);
   
   width = (draw & D_TMB_L) && (draw & D_TMB_R) ? NORMAL_TILE_WIDTH : 
NORMAL_TILE_WIDTH/2;
   if (!(draw & D_TMB_L))
@@ -1468,21 +1362,19 @@
   else
     offset_y_unit = 0;
 
-  /* returns whether the tile is visible. */
-  if (get_canvas_xy(x, y, &canvas_x, &canvas_y)) {
-    
-    if (normalize_map_pos(&x, &y)) {
-    
-      pixmap_put_tile_iso(mapstoredc, x, y, canvas_x, canvas_y, 0,
-                          offset_x, offset_y, offset_y_unit,
-                          width, height, height_unit,
-                          draw);
-    } else {
-      pixmap_put_black_tile_iso(mapstoredc, canvas_x, canvas_y,
-                                offset_x, offset_y,
-                                width, height);
-    }
+  if (normalize_map_pos(&x, &y)) {
+    pixmap_put_tile_iso(hdc, x, y, canvas_x, canvas_y, 0,
+                       offset_x, offset_y, offset_y_unit,
+                       width, height, height_unit,
+                       draw);
+  } else {
+    pixmap_put_black_tile_iso(hdc, canvas_x, canvas_y,
+                             offset_x, offset_y,
+                             width, height);
   }
+
+  SelectObject(hdc, old);
+  DeleteDC(hdc);
 }
 
 
Index: client/gui-xaw/mapview.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-xaw/mapview.c,v
retrieving revision 1.114
diff -u -r1.114 mapview.c
--- client/gui-xaw/mapview.c    2002/12/18 15:59:28     1.114
+++ client/gui-xaw/mapview.c    2002/12/29 21:34:58
@@ -592,38 +592,37 @@
 }
 
 /**************************************************************************
-...
+  Draw the given map tile at the given canvas position in non-isometric
+  view.
 **************************************************************************/
-void update_map_canvas(int x, int y, int width, int height, 
-                      bool write_to_screen)
+void put_one_tile(int map_x, int map_y, int canvas_x, int canvas_y)
 {
-  int map_x, map_y;
+  pixmap_put_tile(map_canvas_store, map_x, map_y,
+                 canvas_x, canvas_y, FALSE);
+}
 
-  for (map_y = y; map_y < y + height; map_y++) {
-    for (map_x = x; map_x < x + width; map_x++) {
-      int canvas_x, canvas_y;
-
-      /*
-       * We don't normalize until later because we want to draw
-       * black tiles for unreal positions.
-       */
-      if (get_canvas_xy(map_x, map_y, &canvas_x, &canvas_y)) {
-       pixmap_put_tile(map_canvas_store, map_x, map_y,
-                       canvas_x, canvas_y, 0);
-      }
-    }
-  }
-
-  if (write_to_screen) {
-    int canvas_x, canvas_y;
+/**************************************************************************
+  Draw the given map tile at the given canvas position in isometric
+  view.
+**************************************************************************/
+void put_one_tile_iso(int map_x, int map_y, int canvas_x, int canvas_y,
+                     enum draw_type draw)
+{
+  /* PORTME */
+  assert(0);
+}
 
-    get_canvas_xy(x, y, &canvas_x, &canvas_y);
-    XCopyArea(display, map_canvas_store, XtWindow(map_canvas), 
-             civ_gc, 
-             canvas_x, canvas_y,
-             width*NORMAL_TILE_WIDTH, height*NORMAL_TILE_HEIGHT,
-             canvas_x, canvas_y);
-  }
+/**************************************************************************
+  Flush the given part of the canvas buffer (if there is one) to the
+  screen.
+**************************************************************************/
+void flush_mapcanvas(int canvas_x, int canvas_y,
+                    int pixel_width, int pixel_height)
+{
+  XCopyArea(display, map_canvas_store, XtWindow(map_canvas), 
+           civ_gc, 
+           canvas_x, canvas_y, pixel_width, pixel_height,
+           canvas_x, canvas_y);
 }
 
 /**************************************************************************
Index: client/include/mapview_g.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/include/mapview_g.h,v
retrieving revision 1.28
diff -u -r1.28 mapview_g.h
--- client/include/mapview_g.h  2002/12/18 15:59:28     1.28
+++ client/include/mapview_g.h  2002/12/29 21:34:58
@@ -38,8 +38,12 @@
 
 void show_city_desc(struct city *pcity, int canvas_x, int canvas_y);
 
-void update_map_canvas(int x, int y, int width, int height,
-                      bool write_to_screen);
+void put_one_tile(int map_x, int map_y, int canvas_x, int canvas_y);
+void put_one_tile_iso(int map_x, int map_y, int canvas_x, int canvas_y,
+                     enum draw_type draw);
+void flush_mapcanvas(int canvas_x, int canvas_y,
+                    int pixel_width, int pixel_height);
+
 void update_map_canvas_scrollbars(void);
 
 void put_cross_overlay_tile(int x,int y);

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