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]
To: undisclosed-recipients:;
Subject: [Freeciv-Dev] (PR#2509) unification of update_map_canvas
From: "Jason Short via RT" <rt@xxxxxxxxxxxxxx>
Date: Fri, 6 Dec 2002 19:06:55 -0800
Reply-to: rt@xxxxxxxxxxxxxx

This patch unifies update_map_canvas() over most GUIs.

This requires the creation of three new GUI functions: put_one_tile,
put_one_tile_iso, and flush_mapcanvas:

* put_one_tile is a frontend for pixmap_put_tile in most GUIs.  It draws
a single tile to the backing store in non-iso mode.

* put_one_tile_iso is similar to what was put_one_tile in most GUIs. 
The difference is it is given the canvas position rather than finding it
itself.  It draws a single tile (or part of one) to the backing store in
iso mode.  Note that the drawing systems of gui-win32 and gui-sdl may
not be easily compatible with this system.

* flush_mapcanvas writes a rectangular portion of the backing store to
the display.

This patch is not ready for inclusion: there is no SDL or MUI support,
and win32 support is poor.  Win32 is the major problem here, since the
current drawing system seems to depend on clever use of buffering
instead of the partial-tile drawing that is used by gtk, gtk2, and mui. 
To fix this cleanly may mean providing support for both drawing systems
(gui-sdl, by the way, also uses the clever buffering method) - but this
may mean adding up to two new GUI functions.

The advantage of the patch is that it removes hundreds of lines of
duplicate code.  In particular, the introduction of flush_mapcanvas will
allow a lot of streamlining of the drawing process to get rid of
spurious redraws.  And it another step toward minimizing the iso/non-iso
differences in the GUI code.

jason


Index: client//mapview_common.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/mapview_common.c,v
retrieving revision 1.22
diff -u -r1.22 mapview_common.c
--- client//mapview_common.c    2002/12/06 22:25:12     1.22
+++ client//mapview_common.c    2002/12/07 03:05:18
@@ -376,6 +376,169 @@
 }
 
 /**************************************************************************
+  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)) {
+    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)) {
+    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. */
+      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 { /* 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++) {
+       /*
+        * 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;
+
+      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.16
diff -u -r1.16 mapview_common.h
--- client//mapview_common.h    2002/11/29 10:01:58     1.16
+++ client//mapview_common.h    2002/12/07 03:05:18
@@ -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.141
diff -u -r1.141 mapview.c
--- client//gui-gtk/mapview.c   2002/12/06 22:25:12     1.141
+++ client//gui-gtk/mapview.c   2002/12/07 03:05:18
@@ -993,11 +993,22 @@
 }
 
 /**************************************************************************
-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;
 
@@ -1027,163 +1038,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.29
diff -u -r1.29 mapview.c
--- client//gui-gtk-2.0/mapview.c       2002/12/06 22:25:12     1.29
+++ client//gui-gtk-2.0/mapview.c       2002/12/07 03:05:18
@@ -1018,11 +1018,22 @@
 }
 
 /**************************************************************************
-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;
 
@@ -1052,163 +1063,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.22
diff -u -r1.22 mapview.c
--- client//gui-stub/mapview.c  2002/11/30 19:27:37     1.22
+++ client//gui-stub/mapview.c  2002/12/07 03:05:18
@@ -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.42
diff -u -r1.42 mapview.c
--- client//gui-win32/mapview.c 2002/12/06 22:25:12     1.42
+++ client//gui-win32/mapview.c 2002/12/07 03:05:19
@@ -645,153 +645,43 @@
 }
 
 /**************************************************************************
-
+  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 */
 
-    /*** 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);
-    }
+  /* FIXME: we don't want to have to recreate the hdc each time! */
+  mapstoredc = CreateCompatibleDC(NULL);
+  old = SelectObject(mapstoredc, mapstorebitmap);
 
+  pixmap_put_tile(mapstoredc, map_x, map_y,
+                 canvas_x, canvas_y, FALSE);
 
-  }
-  SelectObject(mapstoredc,old);
+  SelectObject(mapstoredc, old);
   DeleteDC(mapstoredc);
 }
 
 /**************************************************************************
+  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 hdc = GetDC(map_window);
+  BitBlt(whdc, canvas_x, canvas_y
+        pixel_width, pixel_height,
+        canvas_x, canvas_y,
+        SRCCOPY);
+  show_city_descriptions();    /* is this necessary? */
+  ReleaseDC(map_window, whdc);
+}
 
+/**************************************************************************
+
 **************************************************************************/
 void update_map_canvas_scrollbars_size(void)
 {
@@ -1513,13 +1403,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)
+static 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;
+
+  /* FIXME: we don't want to have to recreate the hdc each time! */
+  hdc = CreateCompatibleDC(NULL);
+  old = SelectObject(hdc, mapstorebitmap);
   
   if (!tile_visible_mapcanvas(x, y)) {
     freelog(LOG_DEBUG, "dropping %d,%d", x, y);
@@ -1547,21 +1444,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(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);
   }
+
+  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.112
diff -u -r1.112 mapview.c
--- client//gui-xaw/mapview.c   2002/12/06 22:25:12     1.112
+++ client//gui-xaw/mapview.c   2002/12/07 03:05:19
@@ -630,38 +630,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_height, pixel_width,
+           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.27
diff -u -r1.27 mapview_g.h
--- client//include/mapview_g.h 2002/11/29 10:01:58     1.27
+++ client//include/mapview_g.h 2002/12/07 03:05:19
@@ -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]