Complete.Org: Mailing Lists: Archives: freeciv-dev: March 2003:
[Freeciv-Dev] (PR#3577) pixel resolution for the mapview canvas
Home

[Freeciv-Dev] (PR#3577) pixel resolution for the mapview canvas

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
To: undisclosed-recipients:;
Subject: [Freeciv-Dev] (PR#3577) pixel resolution for the mapview canvas
From: "Jason Short" <jdorje@xxxxxxxxxxxxxxxxxxxxx>
Date: Sun, 2 Mar 2003 03:02:20 -0800
Reply-to: rt@xxxxxxxxxxxxxx

The mapview canvas should have a pixel resolution; that is, the top-left 
corner should not just be aligned to a tile but should be aligned to a 
specific pixel.  This allows better clipping of the viewport when it's 
aligned to the bottom (or right) of the map (e.g., removal of the 
EXTRA_BOTTOM_ROW hack), and makes things like scrollbar scrolling easier 
because it can be done with pixel resolution as well.

The attached patch is a crude demonstration of the sort of thing that is 
possible here.  Under this patch, in non-iso view center_tile_mapcanvas 
will clip the viewport to line up perfectly with the bottom of the map 
(normally there is additional black space down there).

Note, right now EXTRA_BOTTOM_ROW encompasses two pieces of information: 
the extra tile needed so that the bottom row will be shown fully 
(non-iso view only), and an extra spacing that is needed for iso-view 
because the map and mapview do not line up.  With offsets and "perfect" 
clipping, the first usage would no longer be necessary.  The 
functionality of the second must stay, but I think it should be done in 
pixel resolution rather than tile resolution, something like
   #define EXTRA_SIZED_Y (mapview_canvas.height / 6)
although as Ross will tell you this becomes more complicated when 
gen-topologies are introduced.

jason

Index: client/mapview_common.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/mapview_common.c,v
retrieving revision 1.35
diff -u -r1.35 mapview_common.c
--- client/mapview_common.c     2003/03/01 21:03:55     1.35
+++ client/mapview_common.c     2003/03/02 10:51:16
@@ -209,14 +209,6 @@
     *canvas_x = (iso_x - 1) * NORMAL_TILE_WIDTH / 2;
     *canvas_y = iso_y * NORMAL_TILE_HEIGHT / 2;
 
-    /*
-     * Finally we clip; checking to see if _any part_ of the tile is
-     * visible on the canvas.
-     */
-    return (*canvas_x > -NORMAL_TILE_WIDTH)
-       && *canvas_x < (map_view_pixel_width + NORMAL_TILE_WIDTH / 2)
-       && (*canvas_y > -NORMAL_TILE_HEIGHT)
-       && (*canvas_y < map_view_pixel_height);
   } else {                     /* is_isometric */
     /* map_view_map_width is the width in tiles/map positions */
     int map_view_map_width =
@@ -239,11 +231,20 @@
 
     *canvas_x *= NORMAL_TILE_WIDTH;
     *canvas_y *= NORMAL_TILE_HEIGHT;
-
-    return *canvas_x >= 0
-       && *canvas_x < map_view_pixel_width
-       && *canvas_y >= 0 && *canvas_y < map_view_pixel_height;
   }
+
+  /* Adjust for canvas offset. */
+  *canvas_x -= mapview_canvas.offset_x;
+  *canvas_y -= mapview_canvas.offset_y;
+
+  /*
+   * Finally we clip; checking to see if _any part_ of the tile is
+   * visible on the canvas.
+   */
+  return *canvas_x > -NORMAL_TILE_WIDTH
+         && *canvas_x < map_view_pixel_width
+         && *canvas_y > -NORMAL_TILE_HEIGHT
+         && *canvas_y < map_view_pixel_height;
 }
 
 /**************************************************************************
@@ -254,6 +255,16 @@
                                  int map_view_topleft_map_x,
                                  int map_view_topleft_map_y)
 {
+  /* Sanity checking. */
+  assert(mapview_canvas.offset_x >= 0);
+  assert(mapview_canvas.offset_x < NORMAL_TILE_WIDTH);
+  assert(mapview_canvas.offset_y >= 0);
+  assert(mapview_canvas.offset_y < NORMAL_TILE_HEIGHT);
+
+  /* First adjust for the offset. */
+  canvas_x += mapview_canvas.offset_x;
+  canvas_y += mapview_canvas.offset_y;
+
   if (is_isometric) {
     /* The basic operation here is a simple pi/4 rotation; however, we
      * have to first scale because the tiles have different width and
@@ -347,6 +358,8 @@
 **************************************************************************/
 void center_tile_mapcanvas(int map_x, int map_y)
 {
+  int offset_x, offset_y;
+
   /* Find top-left corner. */
   if (is_isometric) {
     map_x -= mapview_canvas.tile_width / 2;
@@ -365,10 +378,21 @@
   map_y = map_adjust_y(map_y);
   map_y = MIN(map_y,
              map.ysize + EXTRA_BOTTOM_ROW - mapview_canvas.tile_height);
+  if (!is_isometric
+      && map_y == map.ysize + EXTRA_BOTTOM_ROW - mapview_canvas.tile_height) {
+    offset_y = mapview_canvas.tile_height * NORMAL_TILE_HEIGHT
+           - mapview_canvas.height;
+    map_y--;
+  } else {
+    offset_y = 0;
+  }
+  offset_x = 0;
 
   /* Now that we've determined the new origin, update everything. */
   mapview_canvas.map_x0 = map_x;
   mapview_canvas.map_y0 = map_y;
+  mapview_canvas.offset_x = offset_x;
+  mapview_canvas.offset_y = offset_y;
   update_map_canvas_visible();
   update_map_canvas_scrollbars();
   refresh_overview_viewrect();
Index: client/mapview_common.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/mapview_common.h,v
retrieving revision 1.26
diff -u -r1.26 mapview_common.h
--- client/mapview_common.h     2003/03/01 21:03:55     1.26
+++ client/mapview_common.h     2003/03/02 10:51:17
@@ -24,6 +24,7 @@
 
 struct canvas {
   int map_x0, map_y0;
+  int offset_x, offset_y;      /* additional offset of the canvas origin */
   int width, height;           /* Size in pixels. */
   int tile_width, tile_height; /* Size in tiles. Rounded up. */
   struct canvas_store *store;

[Prev in Thread] Current Thread [Next in Thread]
  • [Freeciv-Dev] (PR#3577) pixel resolution for the mapview canvas, Jason Short <=