Complete.Org:
Mailing Lists:
Archives:
freeciv-dev:
September 2005: [Freeciv-Dev] Re: (PR#13982) small map wrap around problems |
![]() |
[Freeciv-Dev] Re: (PR#13982) small map wrap around problems[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
<URL: http://bugs.freeciv.org/Ticket/Display.html?id=13982 > Jason Short wrote: > <URL: http://bugs.freeciv.org/Ticket/Display.html?id=13982 > > > Here is a preliminary patch - it will work if the mapview and map align. > This is the beginning of my Solution To All Mapview Wrapping Problems > patch which should also address various speed problems. And...this patch handles the unaligned maps. -jason Index: client/mapview_common.c =================================================================== RCS file: /home/freeciv/CVS/freeciv/client/mapview_common.c,v retrieving revision 1.246 diff -p -u -r1.246 mapview_common.c --- client/mapview_common.c 26 Sep 2005 22:34:47 -0000 1.246 +++ client/mapview_common.c 30 Sep 2005 01:59:28 -0000 @@ -499,15 +499,15 @@ static void base_set_mapview_origin(int if (update_y1 > update_y0) { update_map_canvas(0, update_y0 - gui_y0, - width, update_y1 - update_y0); + width, update_y1 - update_y0, FALSE); } if (update_x1 > update_x0) { update_map_canvas(update_x0 - gui_x0, common_y0 - gui_y0, - update_x1 - update_x0, common_y1 - common_y0); + update_x1 - update_x0, common_y1 - common_y0, FALSE); } } else { dirty_all(); - update_map_canvas(0, 0, mapview.store_width, mapview.store_height); + update_map_canvas(0, 0, mapview.store_width, mapview.store_height, FALSE); } center_tile_overviewcanvas(); @@ -1066,6 +1066,91 @@ static void put_one_tile(struct canvas * } } +/**************************************************************************** + This function copies areas of the mapview onto other areas to account + for wrapping. E.g., if you update a certain area of the mapview, call + this function and it will copy the just-updated area onto any other + visible spot to account for duplicate tiles. +****************************************************************************/ +static void copy_mapview_for_wrap(int canvas_x, int canvas_y, + int width, int height) +{ + /* FIXME: this function is colossaly overcomplicated. */ + /* Canvas-coordinate vectors for a 1-map wrap in the X or Y directions. */ + int xwrap_x, xwrap_y, ywrap_x, ywrap_y; + int i, j; + const bool tileset_is_iso = tileset_is_isometric(tileset); + const int W = tileset_tile_width(tileset), H = tileset_tile_height(tileset); + + freelog(LOG_DEBUG, "Handling wrap - %d,%d x %d,%d.", + canvas_x, canvas_y, width, height); + + if (MAP_IS_ISOMETRIC) { + if (tileset_is_iso) { + xwrap_x = map.xsize * W * 2; + ywrap_y = map.ysize * H; + xwrap_y = ywrap_x = 0; /* Wrapping is orthogonal */ + } else { + xwrap_x = map.xsize * W; + xwrap_y = -map.xsize * H; + ywrap_x = map.ysize * W / 2; + ywrap_y = map.ysize * H / 2; + } + } else { + if (tileset_is_iso) { + xwrap_x = map.xsize * W / 2; + xwrap_y = map.xsize * H / 2; + ywrap_x = - map.ysize * W / 2; + ywrap_y = map.ysize * H / 2; + } else { + xwrap_x = map.xsize * W; + ywrap_y = map.ysize * H; + xwrap_y = ywrap_x = 0; /* Wrapping is orthogonal */ + } + } + + for (i = 0; ; i++) { + int xworking = 0; + for (j = 0; ; j++) { + int yworking = 0, k; + + for (k = 0; k < 4; k++) { + if ((i == 0 && (k & 2)) + || (j == 0 && (k & 1)) + || (i > 0 && !topo_has_flag(TF_WRAPX)) + || (j > 0 && !topo_has_flag(TF_WRAPY))) { + /* Nothing. */ + } else { + const int mx = 1 - 2 * ((k & 2) != 0), my = 1 - 2 * ((k & 1) != 0); + int canvas_x2 = canvas_x + mx * i * xwrap_x + my * j * ywrap_x; + int canvas_y2 = canvas_y + mx * i * xwrap_y + my * j * ywrap_y; + + freelog(LOG_DEBUG, " Copying %d,%d - %d,%d", + mx * i, my * j, canvas_x2, canvas_y2); + if (canvas_x2 < mapview.store_width + && canvas_x2 + width > 0 + && canvas_y2 < mapview.store_height + && canvas_y2 + height > 0) { + freelog(LOG_DEBUG, " COPYING!"); + canvas_copy(mapview.store, mapview.tmp_store, + canvas_x, canvas_y, canvas_x2, canvas_y2, + width, height); + dirty_rect(canvas_x2, canvas_y2, width, height); + xworking++; + yworking++; + } + } + } + if (yworking == 0) { + break; + } + } + if (xworking == 0) { + break; + } + } +} + /************************************************************************** Update (refresh) the map canvas starting at the given tile (in map coordinates) and with the given dimensions (also in map coordinates). @@ -1081,7 +1166,8 @@ static void put_one_tile(struct canvas * x, y, width, and height are in map coordinates; they need not be normalized or even real. **************************************************************************/ -void update_map_canvas(int canvas_x, int canvas_y, int width, int height) +void update_map_canvas(int canvas_x, int canvas_y, int width, int height, + bool handle_wrapping) { int gui_x0, gui_y0; bool full; @@ -1174,11 +1260,16 @@ void update_map_canvas(int canvas_x, int mapview.tmp_store = tmp; /* And copy store to tmp_store. */ - canvas_copy(mapview.store, mapview.tmp_store, - canvas_x, canvas_y, canvas_x, canvas_y, width, height); + if (handle_wrapping) { + copy_mapview_for_wrap(canvas_x, canvas_y, width, height); + } else { + canvas_copy(mapview.store, mapview.tmp_store, + canvas_x, canvas_y, canvas_x, canvas_y, width, height); + dirty_rect(canvas_x, canvas_y, width, height); + } + } else { + dirty_all(); } - - dirty_rect(canvas_x, canvas_y, width, height); } /************************************************************************** @@ -2066,7 +2157,7 @@ void unqueue_mapview_updates(bool write_ || (needed_updates & UPDATE_CITY_DESCRIPTIONS)) { dirty_all(); update_map_canvas(0, 0, mapview.store_width, - mapview.store_height); + mapview.store_height, FALSE); /* Have to update the overview too, since some tiles may have changed. */ refresh_overview_canvas(); } else { @@ -2103,7 +2194,7 @@ void unqueue_mapview_updates(bool write_ } if (min_x < max_x && min_y < max_y) { - update_map_canvas(min_x, min_y, max_x - min_x, max_y - min_y); + update_map_canvas(min_x, min_y, max_x - min_x, max_y - min_y, TRUE); } } } Index: client/mapview_common.h =================================================================== RCS file: /home/freeciv/CVS/freeciv/client/mapview_common.h,v retrieving revision 1.113 diff -p -u -r1.113 mapview_common.h --- client/mapview_common.h 11 May 2005 20:54:30 -0000 1.113 +++ client/mapview_common.h 30 Sep 2005 01:59:28 -0000 @@ -261,7 +261,8 @@ void put_one_element(struct canvas *pcan int canvas_x, int canvas_y, const struct city *citymode); -void update_map_canvas(int canvas_x, int canvas_y, int width, int height); +void update_map_canvas(int canvas_x, int canvas_y, int width, int height, + bool handle_wrap); void update_map_canvas_visible(void); void update_city_description(struct city *pcity); Index: utility/shared.h =================================================================== RCS file: /home/freeciv/CVS/freeciv/utility/shared.h,v retrieving revision 1.146 diff -p -u -r1.146 shared.h --- utility/shared.h 12 Jul 2005 23:57:53 -0000 1.146 +++ utility/shared.h 30 Sep 2005 02:02:49 -0000 @@ -88,6 +88,7 @@ typedef unsigned int fc_bool; #define BOOL_VAL(x) ((x) != 0) #define XOR(p, q) (!(p) != !(q)) +#define EQ(p, q) (!(p) == !(q)) /* * DIVIDE() divides and rounds down, rather than just divides and
|