Complete.Org: Mailing Lists: Archives: freeciv-dev: September 2004:
[Freeciv-Dev] (PR#8998) Small map meets large screen, they have problems
Home

[Freeciv-Dev] (PR#8998) Small map meets large screen, they have problems

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
To: vasc@xxxxxxxxxxxxxx
Subject: [Freeciv-Dev] (PR#8998) Small map meets large screen, they have problems together.
From: "Jason Short" <jdorje@xxxxxxxxxxxxxxxxxxxxx>
Date: Mon, 27 Sep 2004 01:16:24 -0700
Reply-to: rt@xxxxxxxxxxx

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

> [jdorje - Wed Sep 22 00:44:05 2004]:
> 
> Here is a patch that restricts the maximum size of the mapview.  I don't 
> think I can explain it any better than is done in the patch...which 
> isn't very well.  To large degree these limits were determined by 
> trial-and-error, and I'm still not sure about the non-aligned case 
> (except I am sure the player doesn't want to play non-aligned).

Another possibility is to just draw the tiles multiple times.  Various
people have decared this to be Evil over the years, but I imagine they
haven't seen the bugs with the current system!  Anyway, this is both
easier and will give better results than limiting the size of the mapview.

There may be speed issues (I doubt it), and some debugging will have to
be done to find the cases that aren't handled right (like citymap
overlays and goto turn numbers).

jason

Index: client/citydlg_common.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/citydlg_common.c,v
retrieving revision 1.48
diff -u -r1.48 citydlg_common.c
--- client/citydlg_common.c     23 Sep 2004 00:37:27 -0000      1.48
+++ client/citydlg_common.c     27 Sep 2004 08:11:25 -0000
@@ -174,14 +174,7 @@
 
   citydlg_known_iterate(pcity, city_x, city_y,
                        map_x, map_y, canvas_x, canvas_y) {
-    if (is_isometric) {
-      put_one_tile_iso(pcanvas, map_x, map_y,
-                      canvas_x, canvas_y,
-                      TRUE);
-    } else {
-      put_one_tile(pcanvas, map_x, map_y,
-                  canvas_x, canvas_y, TRUE);
-    }
+    put_tile(pcanvas, map_x, map_y, canvas_x, canvas_y, TRUE);
   } citydlg_known_iterate_end;
 
   /* We have to put the output afterwards or it will be covered
Index: client/goto.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/goto.c,v
retrieving revision 1.73
diff -u -r1.73 goto.c
--- client/goto.c       25 Sep 2004 17:40:49 -0000      1.73
+++ client/goto.c       27 Sep 2004 08:11:25 -0000
@@ -1060,7 +1060,8 @@
   }
 
   if (*count == 1) {
-    draw_segment(src_x, src_y, dir);
+    refresh_tile_mapcanvas(src_x, src_y, FALSE);
+    // draw_segment(src_x, src_y, dir);
   }
 }
 
@@ -1083,7 +1084,8 @@
   }
 
   if (*count == 0) {
-    undraw_segment(src_x, src_y, dir);
+    refresh_tile_mapcanvas(src_x, src_y, FALSE);
+    // undraw_segment(src_x, src_y, dir);
   }
 }
 
Index: client/mapview_common.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/mapview_common.c,v
retrieving revision 1.148
diff -u -r1.148 mapview_common.c
--- client/mapview_common.c     20 Sep 2004 16:27:12 -0000      1.148
+++ client/mapview_common.c     27 Sep 2004 08:11:26 -0000
@@ -57,25 +57,32 @@
 static void dirty_overview(void);
 static void flush_dirty_overview(void);
 
+static void map_to_gui_pos(int *gui_x, int *gui_y, int map_x, int map_y);
+
 /**************************************************************************
  Refreshes a single tile on the map canvas.
 **************************************************************************/
 void refresh_tile_mapcanvas(int x, int y, bool write_to_screen)
 {
-  int canvas_x, canvas_y;
+  int dy = (UNIT_TILE_HEIGHT - NORMAL_TILE_HEIGHT);
 
-  assert(is_real_map_pos(x, y));
-  if (!normalize_map_pos(&x, &y)) {
-    return;
-  }
+  CHECK_MAP_POS(x, y);
 
-  if (map_to_canvas_pos(&canvas_x, &canvas_y, x, y)) {
-    canvas_y += NORMAL_TILE_HEIGHT - UNIT_TILE_HEIGHT;
-    update_map_canvas(canvas_x, canvas_y, UNIT_TILE_WIDTH, UNIT_TILE_HEIGHT);
+  gui_rect_iterate(mapview_canvas.gui_x0, mapview_canvas.gui_y0,
+                  mapview_canvas.width,
+                  mapview_canvas.height + dy,
+                  gui_x, gui_y, map_x, map_y) {
+    if (same_pos(x, y, map_x, map_y)) {
+      int canvas_x = gui_x - mapview_canvas.gui_x0;
+      int canvas_y = gui_y - mapview_canvas.gui_y0 - dy;
 
-    if (write_to_screen) {
-      flush_dirty();
+      update_map_canvas(canvas_x, canvas_y,
+                       UNIT_TILE_WIDTH, UNIT_TILE_HEIGHT);
     }
+  } gui_rect_iterate_end;
+
+  if (write_to_screen) {
+    flush_dirty();
   }
   overview_update_tile(x, y);
 }
@@ -1264,48 +1271,6 @@
   }
 }
 
-/**************************************************************************
-  Draw the given map tile at the given canvas position in non-isometric
-  view.
-**************************************************************************/
-void put_one_tile(struct canvas *pcanvas, int map_x, int map_y,
-                 int canvas_x, int canvas_y, bool citymode)
-{
-  if (normalize_map_pos(&map_x, &map_y)
-      && tile_get_known(map_x, map_y) != TILE_UNKNOWN) {
-    struct drawn_sprite tile_sprs[80];
-    int count = fill_sprite_array(tile_sprs, map_x, map_y,
-                                 map_get_tile(map_x, map_y),
-                                 get_drawable_unit(map_x, map_y, citymode),
-                                 map_get_city(map_x, map_y), citymode);
-
-    put_drawn_sprites(pcanvas, canvas_x, canvas_y,
-                     count, tile_sprs, FALSE);
-  } else {
-    /* tile is unknown */
-    canvas_put_rectangle(pcanvas, COLOR_STD_BLACK,
-                        canvas_x, canvas_y,
-                        NORMAL_TILE_WIDTH, NORMAL_TILE_HEIGHT);
-  }
-}
-
-/**************************************************************************
-  Draw the unique tile for the given map position, in non-isometric view.
-  The coordinates have not been normalized, and are not guaranteed to be
-  real (we have to draw unreal tiles too).
-**************************************************************************/
-static void put_tile(int map_x, int map_y)
-{
-  int canvas_x, canvas_y;
-
-  if (map_to_canvas_pos(&canvas_x, &canvas_y, map_x, map_y)) {
-    freelog(LOG_DEBUG, "putting (%d,%d) at (%d,%d)",
-           map_x, map_y, canvas_x, canvas_y);
-    put_one_tile(mapview_canvas.store, map_x, map_y,
-                canvas_x, canvas_y, FALSE);
-  }
-}
-
 /****************************************************************************
    Draw the map grid around the given map tile at the given canvas position.
 ****************************************************************************/
@@ -1420,45 +1385,23 @@
 /**************************************************************************
   Draw some or all of a tile onto the canvas, in iso-view.
 **************************************************************************/
-void put_one_tile_iso(struct canvas *pcanvas, int map_x, int map_y,
-                     int canvas_x, int canvas_y, bool citymode)
+void put_tile(struct canvas *pcanvas, int map_x, int map_y,
+             int canvas_x, int canvas_y, bool citymode)
 {
   struct drawn_sprite tile_sprs[80];
   struct tile *ptile = map_get_tile(map_x, map_y);
   int count = fill_sprite_array(tile_sprs, map_x, map_y, ptile,
                                get_drawable_unit(map_x, map_y, citymode),
                                ptile->city, citymode);
-  bool fog = ptile->known == TILE_KNOWN_FOGGED && draw_fog_of_war;
+  bool fog = (is_isometric
+             && ptile->known == TILE_KNOWN_FOGGED
+             && draw_fog_of_war);
 
   /*** Draw terrain and specials ***/
   put_drawn_sprites(pcanvas, canvas_x, canvas_y, count, tile_sprs, fog);
 }
 
 /**************************************************************************
-  Draw the unique tile for the given map position, in isometric view.
-  The coordinates have not been normalized, and are not guaranteed to be
-  real (we have to draw unreal tiles too).
-**************************************************************************/
-static void put_tile_iso(int map_x, int map_y)
-{
-  int canvas_x, canvas_y;
-
-  if (map_to_canvas_pos(&canvas_x, &canvas_y, map_x, map_y)) {
-    freelog(LOG_DEBUG, "putting (%d,%d) at (%d,%d)",
-           map_x, map_y, canvas_x, canvas_y);
-
-    if (normalize_map_pos(&map_x, &map_y)) {
-      put_one_tile_iso(mapview_canvas.store,
-                      map_x, map_y, canvas_x, canvas_y,
-                      FALSE);
-    } else {
-      canvas_put_sprite_full(mapview_canvas.store, canvas_x, canvas_y,
-                            sprites.black_tile);
-    }
-  }
-}
-
-/**************************************************************************
   Update (refresh) the map canvas starting at the given tile (in map
   coordinates) and with the given dimensions (also in map coordinates).
 
@@ -1514,23 +1457,13 @@
   canvas_put_rectangle(mapview_canvas.store, COLOR_STD_BLACK,
                       canvas_x, canvas_y, width, height);
 
-  /* FIXME: we don't have to draw black (unknown) tiles since they're already
-   * cleared. */
-  if (is_isometric) {
-    gui_rect_iterate(gui_x0, gui_y0, width, height + NORMAL_TILE_HEIGHT / 2,
-                    map_x, map_y) {
-      put_tile_iso(map_x, map_y);
-    } gui_rect_iterate_end;
-  } else {
-    /* not isometric */
-    gui_rect_iterate(gui_x0, gui_y0, width, height, map_x, map_y) {
-      /*
-       * We don't normalize until later because we want to draw
-       * black tiles for unreal positions.
-       */
-      put_tile(map_x, map_y);
-    } gui_rect_iterate_end;
-  }
+  gui_rect_iterate(gui_x0, gui_y0,
+                  width, height + (UNIT_TILE_HEIGHT - NORMAL_TILE_HEIGHT),
+                  gui_x, gui_y, map_x, map_y) {
+    put_tile(mapview_canvas.store, map_x, map_y,
+            gui_x - mapview_canvas.gui_x0, gui_y - mapview_canvas.gui_y0,
+            FALSE);
+  } gui_rect_iterate_end;
 
   /* Draw the goto lines on top of the whole thing. This is done last as
    * we want it completely on top.
@@ -1540,46 +1473,46 @@
    * from adjacent tiles (if they're close enough). */
   gui_rect_iterate(gui_x0 - GOTO_WIDTH, gui_y0 - GOTO_WIDTH,
                   width + 2 * GOTO_WIDTH, height + 2 * GOTO_WIDTH,
-                  map_x, map_y) {
-    if (normalize_map_pos(&map_x, &map_y)) {
-      adjc_dir_iterate(map_x, map_y, adjc_x, adjc_y, dir) {
-       if (is_drawn_line(map_x, map_y, dir)) {
-         draw_segment(map_x, map_y, dir);
-       }
-      } adjc_dir_iterate_end;
-    }
+                  gui_x, gui_y, map_x, map_y) {
+    adjc_dir_iterate(map_x, map_y, adjc_x, adjc_y, dir) {
+      if (is_drawn_line(map_x, map_y, dir)) {
+       draw_segment(gui_x - mapview_canvas.gui_x0,
+                    gui_y - mapview_canvas.gui_y0, dir);
+      }
+    } adjc_dir_iterate_end;
   } gui_rect_iterate_end;
 
   /* Draw citymap overlays on top. */
-  gui_rect_iterate(gui_x0, gui_y0, width, height, map_x, map_y) {
-    if (normalize_map_pos(&map_x, &map_y)
-       && tile_get_known(map_x, map_y) != TILE_UNKNOWN) {
+  gui_rect_iterate(gui_x0, gui_y0, width, height,
+                  gui_x, gui_y, map_x, map_y) {
+    if (tile_get_known(map_x, map_y) != TILE_UNKNOWN) {
       struct unit *punit;
       struct city *pcity;
-      int city_x, city_y, canvas_x2, canvas_y2;
+      int city_x, city_y;
 
       pcity = find_city_or_settler_near_tile(map_x, map_y, &punit);
       if (pcity
          && city_colors[pcity->client.color] != COLOR_STD_LAST
-         && map_to_city_map(&city_x, &city_y, pcity, map_x, map_y)
-         && map_to_canvas_pos(&canvas_x2, &canvas_y2, map_x, map_y)) {
+         && map_to_city_map(&city_x, &city_y, pcity, map_x, map_y)) {
        enum city_tile_type worker = get_worker_city(pcity, city_x, city_y);
 
        put_city_worker(mapview_canvas.store,
                        city_colors[pcity->client.color], worker,
-                       canvas_x2, canvas_y2);
+                       gui_x - mapview_canvas.gui_x0,
+                       gui_y - mapview_canvas.gui_y0);
        if (worker == C_TILE_WORKER) {
          put_city_tile_output(pcity, city_x, city_y,
-                              mapview_canvas.store, canvas_x2, canvas_y2);
+                              mapview_canvas.store,
+                              gui_x - mapview_canvas.gui_x0,
+                              gui_y - mapview_canvas.gui_y0);
        }
       } else if (punit
-                && city_colors[punit->client.color] != COLOR_STD_LAST
-                && map_to_canvas_pos(&canvas_x2, &canvas_y2,
-                                     map_x, map_y)) {
+                && city_colors[punit->client.color] != COLOR_STD_LAST) {
        /* Draw citymap overlay for settlers. */
        put_city_worker(mapview_canvas.store,
                        city_colors[punit->client.color], C_TILE_EMPTY,
-                       canvas_x2, canvas_y2);
+                       gui_x - mapview_canvas.gui_x0,
+                       gui_y - mapview_canvas.gui_y0);
       }
     }
   } gui_rect_iterate_end;
@@ -1673,7 +1606,7 @@
   gui_rect_iterate(mapview_canvas.gui_x0 + canvas_x - dx / 2,
                   mapview_canvas.gui_y0 + canvas_y - dy,
                   width + dx, height + dy - NORMAL_TILE_HEIGHT,
-                  map_x, map_y) {
+                  map_x, map_y, gui_x, gui_y) {
     int canvas_x, canvas_y;
     struct city *pcity;
 
@@ -1740,12 +1673,11 @@
   Draw a goto line at the given location and direction.  The line goes from
   the source tile to the adjacent tile in the given direction.
 ****************************************************************************/
-void draw_segment(int src_x, int src_y, enum direction8 dir)
+void draw_segment(int canvas_x, int canvas_y, enum direction8 dir)
 {
-  int canvas_x, canvas_y, canvas_dx, canvas_dy;
+  int canvas_dx, canvas_dy;
 
   /* Determine the source position of the segment. */
-  (void) map_to_canvas_pos(&canvas_x, &canvas_y, src_x, src_y);
   canvas_x += NORMAL_TILE_WIDTH / 2;
   canvas_y += NORMAL_TILE_HEIGHT / 2;
 
@@ -1774,21 +1706,14 @@
   Remove the line from src_x, src_y in the given direction, and redraw
   the change if necessary.
 **************************************************************************/
-void undraw_segment(int src_x, int src_y, int dir)
+void undraw_segment(int canvas_x, int canvas_y, int dir)
 {
-  int dest_x, dest_y, canvas_x, canvas_y, canvas_dx, canvas_dy;
-
-  assert(!is_drawn_line(src_x, src_y, dir));
-
-  if (!MAPSTEP(dest_x, dest_y, src_x, src_y, dir)) {
-    assert(0);
-  }
+  int canvas_dx, canvas_dy;
 
   /* 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) map_to_canvas_pos(&canvas_x, &canvas_y, src_x, src_y);
   map_to_gui_vector(&canvas_dx, &canvas_dy, DIR_DX[dir], DIR_DY[dir]);
 
   update_map_canvas(MIN(canvas_x, canvas_x + canvas_dx),
Index: client/mapview_common.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/mapview_common.h,v
retrieving revision 1.76
diff -u -r1.76 mapview_common.h
--- client/mapview_common.h     20 Sep 2004 16:27:12 -0000      1.76
+++ client/mapview_common.h     27 Sep 2004 08:11:26 -0000
@@ -72,7 +72,8 @@
  * iso-view iteration is at
  * http://rt.freeciv.org/Ticket/Attachment/51374/37363/isogrid.png.
  */
-#define gui_rect_iterate(gui_x0, gui_y0, width, height, map_x, map_y)      \
+#define gui_rect_iterate(gui_x0, gui_y0, width, height,                        
    \
+                        gui_x, gui_y, map_x, map_y)                        \
 {                                                                          \
   int _gui_x0 = (gui_x0), _gui_y0 = (gui_y0);                              \
   int _width = (width), _height = (height);                                \
@@ -91,7 +92,7 @@
     int GRI_x0 = DIVIDE(_gui_x0, W), GRI_y0 = DIVIDE(_gui_y0, H);          \
     int GRI_x1 = DIVIDE(_gui_x0 + _width + W - 1, W);                      \
     int GRI_y1 = DIVIDE(_gui_y0 + _height + H - 1, H);                     \
-    int GRI_itr, GRI_x_itr, GRI_y_itr, map_x, map_y;                       \
+    int GRI_itr, GRI_x_itr, GRI_y_itr, map_x, map_y, gui_x, gui_y;         \
     int count;                                                             \
                                                                            \
     if (is_isometric) {                                                        
    \
@@ -112,6 +113,10 @@
       } else {                                                             \
        map_x = GRI_x_itr;                                                  \
        map_y = GRI_y_itr;                                                  \
+      }                                                                        
    \
+      map_to_gui_pos(&gui_x, &gui_y, map_x, map_y);                        \
+      if (!normalize_map_pos(&map_x, &map_y)) {                                
    \
+       continue;                                                           \
       }
 
 #define gui_rect_iterate_end                                               \
@@ -160,10 +165,8 @@
 
 void put_nuke_mushroom_pixmaps(int map_x, int map_y);
 
-void put_one_tile(struct canvas *pcanvas, int map_x, int map_y,
-                 int canvas_x, int canvas_y, bool citymode);
-void put_one_tile_iso(struct canvas *pcanvas, int map_x, int map_y,
-                     int canvas_x, int canvas_y, bool citymode);
+void put_tile(struct canvas *pcanvas, int map_x, int map_y,
+             int canvas_x, int canvas_y, bool citymode);
 void tile_draw_grid(struct canvas *pcanvas, int map_x, int map_y,
                    int canvas_x, int canvas_y, bool citymode);
 
@@ -175,8 +178,8 @@
                            int width, int height);
 bool show_unit_orders(struct unit *punit);
 
-void draw_segment(int src_x, int src_y, enum direction8 dir);
-void undraw_segment(int src_x, int src_y, int dir);
+void draw_segment(int canvas_x, int canvas_y, enum direction8 dir);
+void undraw_segment(int canvas_x, int canvas_y, int dir);
 
 void decrease_unit_hp_smooth(struct unit *punit0, int hp0, 
                             struct unit *punit1, int hp1);
Index: client/packhand.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/packhand.c,v
retrieving revision 1.406
diff -u -r1.406 packhand.c
--- client/packhand.c   25 Sep 2004 23:15:43 -0000      1.406
+++ client/packhand.c   27 Sep 2004 08:11:26 -0000
@@ -1235,6 +1235,7 @@
       int height = get_citydlg_canvas_height();
       int canvas_x, canvas_y;
 
+      /* FIXME: should use a specialized refresh_city_mapcanvas(). */
       map_to_canvas_pos(&canvas_x, &canvas_y, punit->x, punit->y);
       update_map_canvas(canvas_x - (width - NORMAL_TILE_WIDTH) / 2,
                        canvas_y - (height - NORMAL_TILE_HEIGHT) / 2,

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