[Freeciv-Dev] (PR#13982) small map wrap around problems
[Top] [All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
<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.
-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 29 Sep 2005 21:58: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,87 @@ 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 {
+ /* TODO */
+ assert(0);
+ }
+ } else {
+ if (tileset_is_iso) {
+ /* TODO */
+ assert(0);
+ } 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 +1162,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 +1256,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 +2153,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 +2190,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 29 Sep 2005 21:58:30 -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 29 Sep 2005 21:58:31 -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
|
|