[Freeciv-Dev] (PR#8965) much simpler draw_segment
[Top] [All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
<URL: http://rt.freeciv.org/Ticket/Display.html?id=8965 >
> [jdorje - Sat Jun 12 07:37:38 2004]:
>
> This patch makes draw_segment much simpler.
Here's a better version of the patch that uses map_to_gui_vector.
jason
Index: client/mapview_common.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/mapview_common.c,v
retrieving revision 1.125
diff -u -r1.125 mapview_common.c
--- client/mapview_common.c 13 Jun 2004 16:53:34 -0000 1.125
+++ client/mapview_common.c 15 Jun 2004 00:18:55 -0000
@@ -1631,116 +1631,37 @@
#define ABS(x) (((x) >= 0) ? (x) : -(x))
/****************************************************************************
- Put a segment on the mapview (in iso-view only). The segment is drawn
- from the source tile to the adjacent tile in the given direction.
-
- This method is faster than the one used for non-iso view, but there are
- two drawbacks:
- 1. Since each line spans multiple tiles, updating a single tile is
- harder (see update_map_canvas).
- 2. We don't know where the map wraps, so we have problems when we reach
- the wrapping point. On very large mapviews this means segments might
- not be drawn near the wrapping points.
-****************************************************************************/
-static void draw_segment_iso(int src_x, int src_y, enum direction8 dir)
-{
- int dest_x, dest_y;
- bool is_visible1, is_visible2;
- int canvas_src_x, canvas_src_y;
- int canvas_dest_x, canvas_dest_y;
-
- if (!MAPSTEP(dest_x, dest_y, src_x, src_y, dir)) {
- assert(0);
- return;
- }
-
- /* Find middle of tiles. y-1 to not undraw the the middle pixel of a
- horizontal line when we refresh the tile below-between. */
- is_visible1
- = map_to_canvas_pos(&canvas_src_x, &canvas_src_y, src_x, src_y);
- is_visible2
- = map_to_canvas_pos(&canvas_dest_x, &canvas_dest_y, dest_x, dest_y);
-
- if (!is_visible1 && !is_visible2) {
- return; /* No need to draw anything. */
- }
-
- canvas_src_x += NORMAL_TILE_WIDTH/2;
- canvas_src_y += NORMAL_TILE_HEIGHT/2-1;
- canvas_dest_x += NORMAL_TILE_WIDTH/2;
- canvas_dest_y += NORMAL_TILE_HEIGHT/2-1;
-
- /* HACK: sometimes we draw from a source tile on one side of the screen
- * to a destination tile on the other side. In this case we don't want
- * to draw garbage. Instead we just don't draw the line at all. Note
- * that the non-iso-view method of drawing doesn't have this problem. */
- if (abs(canvas_dest_x - canvas_src_x) > NORMAL_TILE_WIDTH
- || abs(canvas_dest_y - canvas_src_y) > NORMAL_TILE_HEIGHT)
- return;
-
- /* draw it! */
- canvas_put_line(mapview_canvas.store, COLOR_STD_CYAN, LINE_GOTO,
- canvas_src_x, canvas_src_y,
- canvas_dest_x - canvas_src_x,
- canvas_dest_y - canvas_src_y);
- dirty_rect(MIN(canvas_src_x, canvas_dest_x) - 1,
- MIN(canvas_src_y, canvas_dest_y) - 1,
- ABS(canvas_dest_x - canvas_src_x) + 2,
- ABS(canvas_dest_y - canvas_src_y) + 2);
-}
-
-/****************************************************************************
- Put a half-segment (in non-iso view only). The segment goes from the
- given tile *toward* the adjacent tile in the given direction. However
- it only goes the the edge of the source tile. Thus only one tile is
- spanned (making updates of single tiles easier) but two lines must be
- drawn to get a single segment (meaning more work & slower).
-****************************************************************************/
-static void put_line(int x, int y, enum direction8 dir)
-{
- int canvas_src_x, canvas_src_y, canvas_dest_x, canvas_dest_y;
-
- if (!map_to_canvas_pos(&canvas_src_x, &canvas_src_y, x, y)) {
- return;
- }
- canvas_src_x += NORMAL_TILE_WIDTH/2;
- canvas_src_y += NORMAL_TILE_HEIGHT/2;
- DIRSTEP(canvas_dest_x, canvas_dest_y, dir);
- canvas_dest_x = canvas_src_x + (NORMAL_TILE_WIDTH * canvas_dest_x) / 2;
- canvas_dest_y = canvas_src_y + (NORMAL_TILE_WIDTH * canvas_dest_y) / 2;
-
- canvas_put_line(mapview_canvas.store, COLOR_STD_CYAN, LINE_GOTO,
- canvas_src_x, canvas_src_y,
- canvas_dest_x - canvas_src_x,
- canvas_dest_y - canvas_src_y);
-
- dirty_rect(MIN(canvas_src_x, canvas_dest_x) - 1,
- MIN(canvas_src_y, canvas_dest_y) - 1,
- ABS(canvas_dest_x - canvas_src_x) + 2,
- ABS(canvas_dest_y - canvas_src_y) + 2);
-}
-
-/****************************************************************************
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)
{
- if (is_isometric) {
- draw_segment_iso(src_x, src_y, dir);
- } else {
- int dest_x, dest_y;
- bool is_real = MAPSTEP(dest_x, dest_y, src_x, src_y, dir);
+ int canvas_x, canvas_y, canvas_dx, canvas_dy;
- assert(is_real);
+ /* 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;
- if (tile_visible_mapcanvas(src_x, src_y)) {
- put_line(src_x, src_y, dir);
- }
- if (tile_visible_mapcanvas(dest_x, dest_y)) {
- put_line(dest_x, dest_y, DIR_REVERSE(dir));
- }
- }
+ /* Determine the vector of the segment. */
+ map_to_gui_vector(&canvas_dx, &canvas_dy, DIR_DX[dir], DIR_DY[dir]);
+
+ /* Draw the segment. */
+ canvas_put_line(mapview_canvas.store, COLOR_STD_CYAN, LINE_GOTO,
+ canvas_x, canvas_y, canvas_dx, canvas_dy);
+
+ /* The actual area drawn will extend beyond the base rectangle, since
+ * the goto lines have width. */
+ dirty_rect(MIN(canvas_x, canvas_x + canvas_dx) - GOTO_WIDTH,
+ MIN(canvas_y, canvas_y + canvas_dy) - GOTO_WIDTH,
+ ABS(canvas_dx) + 2 * GOTO_WIDTH,
+ ABS(canvas_dy) + 2 * GOTO_WIDTH);
+
+ /* It is possible that the mapview wraps between the source and dest
+ * tiles. In this case they will not be next to each other; they'll be
+ * on the opposite sides of the screen. If this happens then the dest
+ * tile will not be updated. This is consistent with the mapview design
+ * which fails when the size of the mapview approaches that of the map. */
}
/**************************************************************************
Index: client/mapview_common.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/mapview_common.h,v
retrieving revision 1.67
diff -u -r1.67 mapview_common.h
--- client/mapview_common.h 13 Jun 2004 16:53:34 -0000 1.67
+++ client/mapview_common.h 15 Jun 2004 00:18:55 -0000
@@ -128,6 +128,7 @@
#define D_FULL D_TMB_LR
#define BORDER_WIDTH 2
+#define GOTO_WIDTH 2
enum update_type {
/* Masks */
|
|