Index: client/gui-gtk/mapctrl.c =================================================================== RCS file: /home/freeciv/CVS/freeciv/client/gui-gtk/mapctrl.c,v retrieving revision 1.49 diff -u -p -b -r1.49 mapctrl.c --- client/gui-gtk/mapctrl.c 2001/10/09 18:56:59 1.49 +++ client/gui-gtk/mapctrl.c 2001/11/01 04:19:49 @@ -421,10 +421,12 @@ gint butt_down_overviewcanvas(GtkWidget if (is_isometric) { xtile=event->x/2-(map.xsize/2-(map_view_x0+(map_canvas_store_twidth+map_canvas_store_theight)/2)); + ytile=event->y/2; } else { - xtile=event->x/2-(map.xsize/2-(map_view_x0+map_canvas_store_twidth/2)); + xtile = overview_x0 + event->x/2; + ytile = overview_y0 + event->y/2; + normalize_map_pos(&xtile, &ytile); } - ytile=event->y/2; if(get_client_state()!=CLIENT_GAME_RUNNING_STATE) return TRUE; Index: client/gui-gtk/mapview.c =================================================================== RCS file: /home/freeciv/CVS/freeciv/client/gui-gtk/mapview.c,v retrieving revision 1.107 diff -u -p -b -r1.107 mapview.c --- client/gui-gtk/mapview.c 2001/10/30 12:11:44 1.107 +++ client/gui-gtk/mapview.c 2001/11/01 04:19:50 @@ -66,9 +66,12 @@ map, and I added 1 (using the EXTRA_BOTT The places that needs to be adjusted are the same as above. */ #define EXTRA_BOTTOM_ROW (is_isometric ? 6 : 1) -/* contains the x0, y0 coordinates of the upper left corner block */ +/* Contains the coordinates of the tile in the upper left corner. */ int map_view_x0, map_view_y0; +/* Ditto for the overview map. */ +int overview_x0, overview_y0; + /* used by map_canvas expose func */ int force_full_repaint; @@ -249,9 +252,9 @@ void pixmap_put_tile(GdkDrawable *pm, in } /************************************************************************** -Finds the pixel coordinates of a tile. -Beside setting the results in canvas_x,canvas_y it returns whether the tile -is inside the visible map. +Finds the pixel coordinates of a tile. Beside setting the results in +canvas_x, canvas_y it returns TRUE or FALSE according to whether the +tile is inside the visible portion of the map. **************************************************************************/ static int get_canvas_xy(int map_x, int map_y, int *canvas_x, int *canvas_y) { @@ -293,22 +296,18 @@ static int get_canvas_xy(int map_x, int && (*canvas_y > -NORMAL_TILE_HEIGHT) && (*canvas_y < height); } else { /* is_isometric */ - if (map_view_x0+map_canvas_store_twidth <= map.xsize) - *canvas_x = map_x-map_view_x0; - else if(map_x >= map_view_x0) - *canvas_x = map_x-map_view_x0; - else if(map_x < map_adjust_x(map_view_x0+map_canvas_store_twidth)) - *canvas_x = map_x+map.xsize-map_view_x0; - else *canvas_x = -1; + *canvas_x = map_x - map_view_x0; + if (*canvas_x < 0) + *canvas_x += map.xsize; *canvas_y = map_y - map_view_y0; + if (*canvas_y < 0) + *canvas_y += map.ysize; *canvas_x *= NORMAL_TILE_WIDTH; *canvas_y *= NORMAL_TILE_HEIGHT; - return *canvas_x >= 0 - && *canvas_x < map_canvas_store_twidth * NORMAL_TILE_WIDTH - && *canvas_y >= 0 + return *canvas_x < map_canvas_store_twidth * NORMAL_TILE_WIDTH && *canvas_y < map_canvas_store_theight * NORMAL_TILE_HEIGHT; } } @@ -339,13 +338,13 @@ void get_map_xy(int canvas_x, int canvas if (canvas_x > canvas_y) (*map_y) -= 1; if (canvas_x + canvas_y > NORMAL_TILE_WIDTH) (*map_x) += 1; + } else { /* is_isometric */ + *map_x = map_view_x0 + canvas_x / NORMAL_TILE_WIDTH; + *map_y = map_view_y0 + canvas_y / NORMAL_TILE_HEIGHT; + } /* If we are outside the map find the nearest tile, with distance as seen on the map. */ nearest_real_pos(map_x, map_y); - } else { /* is_isometric */ - *map_x = map_adjust_x(map_view_x0 + canvas_x/NORMAL_TILE_WIDTH); - *map_y = map_adjust_y(map_view_y0 + canvas_y/NORMAL_TILE_HEIGHT); - } } @@ -635,15 +634,8 @@ void set_indicator_icons(int bulb, int s **************************************************************************/ int tile_visible_mapcanvas(int x, int y) { - if (is_isometric) { - int dummy_x, dummy_y; /* well, it needs two pointers... */ + int dummy_x, dummy_y; return get_canvas_xy(x, y, &dummy_x, &dummy_y); - } else { - return (y>=map_view_y0 && y=map_view_x0 && x=map_view_x0 && - x+map.xsize= NORMAL_TILE_HEIGHT && canvas_y < height - 3 * NORMAL_TILE_HEIGHT/2; } else { - return ((y>=map_view_y0+2 || (y >= map_view_y0 && map_view_y0 == 0)) - && (y=map_view_x0+2 && x=map_view_x0+2 - && x+map.xsize= 2 /* top border */ + || (!(map.top & TOPF_XWRAP) && map_view_x0 == 0)) + && (dx < map_canvas_store_twidth - 2 /* bottom border */ + || (!(map.top & TOPF_XWRAP) + && map_view_x0 + map_canvas_store_twidth == map.xsize)) + && (dy >= 2 /* left border */ + || (!(map.top & TOPF_YWRAP) && map_view_y0 == 0)) + && (dy < map_canvas_store_theight - 2 /* right border */ + || (!(map.top & TOPF_YWRAP) + && (map_view_y0 + map_canvas_store_theight - EXTRA_BOTTOM_ROW + == map.ysize)))); + + return r; } } @@ -685,7 +693,7 @@ one go. void move_unit_map_canvas(struct unit *punit, int x0, int y0, int dx, int dy) { static struct timer *anim_timer = NULL; - int dest_x, dest_y; + int dest_x, dest_y, is_real; /* only works for adjacent-square moves */ if ((dx < -1) || (dx > 1) || (dy < -1) || (dy > 1) || @@ -698,8 +706,10 @@ void move_unit_map_canvas(struct unit *p update_unit_info_label(punit); } - dest_x = map_adjust_x(x0+dx); - dest_y = map_adjust_y(y0+dy); + dest_x = x0 + dx; + dest_y = y0 + dy; + is_real = normalize_map_pos(&dest_x, &dest_y); + assert(is_real); if (player_can_see_unit(game.player_ptr, punit) && (tile_visible_mapcanvas(x0, y0) || @@ -815,7 +825,7 @@ void get_center_tile_mapcanvas(int *x, i } /************************************************************************** -... +Center the map on a given tile. **************************************************************************/ void center_tile_mapcanvas(int x, int y) { @@ -825,8 +835,9 @@ void center_tile_mapcanvas(int x, int y) x -= map_canvas_store_theight/2; y -= map_canvas_store_theight/2; - map_view_x0 = map_adjust_x(x); - map_view_y0 = map_adjust_y(y); + map_view_x0 = x; + map_view_y0 = y; + nearest_real_pos(&x, &y); map_view_y0 = (map_view_y0 > map.ysize + EXTRA_BOTTOM_ROW - map_canvas_store_theight) ? @@ -834,17 +845,48 @@ void center_tile_mapcanvas(int x, int y) map_view_y0; } else { int new_map_view_x0, new_map_view_y0; + + new_map_view_x0 = x - map_canvas_store_twidth/2; + new_map_view_y0 = y - map_canvas_store_theight/2; + + nearest_real_pos(&new_map_view_x0, &new_map_view_y0); - new_map_view_x0=map_adjust_x(x-map_canvas_store_twidth/2); - new_map_view_y0=map_adjust_y(y-map_canvas_store_theight/2); - if (new_map_view_y0>map.ysize+EXTRA_BOTTOM_ROW-map_canvas_store_theight) - new_map_view_y0= - map_adjust_y(map.ysize+EXTRA_BOTTOM_ROW-map_canvas_store_theight); + if (!(map.top & TOPF_YWRAP) + && new_map_view_y0 > (map.ysize + EXTRA_BOTTOM_ROW + - map_canvas_store_theight)) { + new_map_view_y0 = (map.ysize + EXTRA_BOTTOM_ROW + - map_canvas_store_theight); + + if (new_map_view_y0 < 0) + new_map_view_y0 = 0; + } + if (!(map.top & TOPF_XWRAP) + && (new_map_view_x0 + > map.xsize - map_canvas_store_twidth)) { + new_map_view_x0 = map.xsize - map_canvas_store_twidth; + + if (new_map_view_x0 < 0) + new_map_view_x0 = 0; + } + map_view_x0=new_map_view_x0; map_view_y0=new_map_view_y0; } + /* Center the overview map. */ + if (map.top & TOPF_XWRAP) + overview_x0 = x - map.xsize/2; + else + overview_x0 = 0; + + if (map.top & TOPF_YWRAP) + overview_y0 = y - map.ysize/2; + else + overview_y0 = 0; + + normalize_map_pos(&overview_x0, &overview_y0); + update_map_canvas_visible(); update_map_canvas_scrollbars(); refresh_overview_viewrect(); @@ -916,30 +958,38 @@ void refresh_overview_canvas(void) gdk_gc_set_foreground( fill_bg_gc, colors_standard[COLOR_STD_BLACK] ); } - /************************************************************************** ... **************************************************************************/ void overview_update_tile(int x, int y) { - int screen_width, pos; + int screen_width, screen_x, screen_y; if (is_isometric) { screen_width = map_canvas_store_twidth + map_canvas_store_theight; } else { screen_width = map_canvas_store_twidth; } - pos = x + map.xsize/2 - (map_view_x0 + screen_width/2); - pos %= map.xsize; - if (pos < 0) - pos += map.xsize; - set_overview_tile_foreground_color(x, y); - gdk_draw_rectangle(overview_canvas_store, fill_bg_gc, TRUE, x*2, y*2, + + /* Update the backing store. */ + gdk_draw_rectangle(overview_canvas_store, fill_bg_gc, TRUE, + 2*x, 2*y, 2, 2); + + /* Update the actual on-screen tile directly. */ - gdk_draw_rectangle(overview_canvas->window, fill_bg_gc, TRUE, pos*2, y*2, + screen_x = x - overview_x0; + if (screen_x < 0) + screen_x += map.xsize; + + screen_y = y - overview_y0; + if (screen_y < 0) + screen_y += map.ysize; + + gdk_draw_rectangle(overview_canvas->window, fill_bg_gc, TRUE, + 2*screen_x, 2*screen_y, 2, 2); } @@ -948,38 +998,47 @@ void overview_update_tile(int x, int y) **************************************************************************/ void refresh_overview_viewrect(void) { - int screen_width, delta; + int screen_width; if (is_isometric) { screen_width = map_canvas_store_twidth + map_canvas_store_theight; } else { screen_width = map_canvas_store_twidth; } - delta = map.xsize/2 - (map_view_x0 + screen_width/2); - if (delta>=0) { - gdk_draw_pixmap( overview_canvas->window, civ_gc, overview_canvas_store, - 0, 0, 2*delta, 0, - overview_canvas_store_width-2*delta, - overview_canvas_store_height ); - gdk_draw_pixmap( overview_canvas->window, civ_gc, overview_canvas_store, - overview_canvas_store_width-2*delta, 0, - 0, 0, - 2*delta, overview_canvas_store_height ); - } else { - gdk_draw_pixmap( overview_canvas->window, civ_gc, overview_canvas_store, - -2*delta, 0, + /* +-+-+ + |1|2| + +-+-+ + |3|4| + +-+-+ */ + + gdk_draw_pixmap(overview_canvas->window, civ_gc, overview_canvas_store, + 2*overview_x0, 2*overview_y0, 0, 0, - overview_canvas_store_width+2*delta, - overview_canvas_store_height ); + overview_canvas_store_width - 2*overview_x0, + overview_canvas_store_height - 2*overview_y0); + + gdk_draw_pixmap(overview_canvas->window, civ_gc, overview_canvas_store, + 0, 2*overview_y0, + overview_canvas_store_width - 2*overview_x0, 0, + 2*overview_x0, + overview_canvas_store_height - 2*overview_y0); + + gdk_draw_pixmap(overview_canvas->window, civ_gc, overview_canvas_store, + overview_x0 * 2, 0, + 0, overview_canvas_store_height - 2*overview_y0, + overview_canvas_store_width - 2*overview_x0, + 2*overview_y0); - gdk_draw_pixmap( overview_canvas->window, civ_gc, overview_canvas_store, + gdk_draw_pixmap(overview_canvas->window, civ_gc, overview_canvas_store, 0, 0, - overview_canvas_store_width+2*delta, 0, - -2*delta, overview_canvas_store_height ); - } + overview_canvas_store_width - 2*overview_x0, + overview_canvas_store_height - 2*overview_y0, + 2 * overview_x0, 2 * overview_y0); gdk_gc_set_foreground( civ_gc, colors_standard[COLOR_STD_WHITE] ); + /* Draw a rectangle on the overview map indicating the visible + portion of the map. */ if (is_isometric) { /* The x's and y's are in overview coordinates. All the extra factor 2's are because one tile in the overview @@ -1012,10 +1071,19 @@ void refresh_overview_viewrect(void) gdk_draw_line(overview_canvas->window, civ_gc, Sx, Sy, Wx, Wy); } else { + int dx, dy; + dx = map_view_x0 - overview_x0; + if (dx < 0) + dx += map.xsize; + + dy = map_view_y0 - overview_y0; + if (dy < 0) + dy += map.ysize; + gdk_draw_rectangle(overview_canvas->window, civ_gc, FALSE, - (overview_canvas_store_width-2*map_canvas_store_twidth)/2, - 2*map_view_y0, - 2*map_canvas_store_twidth, 2*map_canvas_store_theight-1); + 2*dx, 2*dy, + 2*map_canvas_store_twidth, + 2*map_canvas_store_theight); } } @@ -1378,11 +1446,16 @@ void update_map_canvas(int x, int y, int for (y_itr=y; y_itr= map.xsize) *x -= map.xsize; + } + + if (map.top & TOPF_YWRAP) { + while (*y < 0) + *y += map.ysize; + while (*y >= map.ysize) + *y -= map.ysize; + } - return (0 <= *y && *y < map.ysize); + return (((map.top & TOPF_YWRAP) || (0 <= *y && *y < map.ysize)) + && ((map.top & TOPF_XWRAP) || (0 <= *x && *x < map.xsize))); } /************************************************************************** @@ -1328,15 +1339,29 @@ position is normalized. **************************************************************************/ void nearest_real_pos(int *x, int *y) { - if (*y < 0) - *y = 0; - else if (*y >= map.ysize) - *y = map.ysize - 1; - + if (map.top & TOPF_XWRAP) { while (*x < 0) *x += map.xsize; while (*x >= map.xsize) *x -= map.xsize; + } else { + if (*x < 0) + *x = 0; + else if (*x >= map.xsize) + *x = map.xsize - 1; + } + + if (map.top & TOPF_YWRAP) { + while (*y < 0) + *y += map.ysize; + while (*y >= map.ysize) + *y -= map.ysize; + } else { + if (*y < 0) + *y = 0; + else if (*y >= map.ysize) + *y = map.ysize - 1; + } } /************************************************************************** Index: common/map.h =================================================================== RCS file: /home/freeciv/CVS/freeciv/common/map.h,v retrieving revision 1.101 diff -u -p -b -r1.101 map.h --- common/map.h 2001/10/30 10:59:20 1.101 +++ common/map.h 2001/11/01 04:19:51 @@ -151,6 +151,16 @@ struct tile_type { char *helptext; }; +#define TOPF_XWRAP 1 +#define TOPF_YWRAP 2 + +enum topology { + TOP_RECTANGLE = 0, + TOP_XCYLINDER = 1, /* TOPF_XWRAP */ + TOP_YCYLINDER = 2, /* TOPF_YWRAP */ + TOP_TORUS = 3 /* TOPF_XWRAP | TOPF_YWRAP */ +}; + struct civ_map { int xsize, ysize; int seed; @@ -171,6 +181,7 @@ struct civ_map { int have_huts; int have_rivers_overlay; /* only applies if !have_specials */ int num_continents; + enum topology top; struct tile *tiles; struct map_position start_positions[MAX_NUM_NATIONS]; }; @@ -197,12 +208,15 @@ signed short map_get_continent(int x, in void initialize_move_costs(void); void reset_move_costs(int x, int y); -#define map_adjust_x(X) \ +#define map_adjust_x_0(X) \ ((X) < 0 \ ? ((X) % map.xsize != 0 ? (X) % map.xsize + map.xsize : 0) \ : ((X) >= map.xsize \ ? (X) % map.xsize \ : (X))) + +#define map_adjust_x(X) \ + ((map.top & TOPF_XWRAP) ? map_adjust_x_0((X)) : (X)) #define map_adjust_y(Y) \ (((Y)<0) ? 0 : (((Y)>=map.ysize) ? map.ysize-1 : (Y)))