Complete.Org:
Mailing Lists:
Archives:
freeciv-dev:
September 2004: [Freeciv-Dev] (PR#10393) map_to_tile_pos extensions |
![]() |
[Freeciv-Dev] (PR#10393) map_to_tile_pos extensions[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
<URL: http://rt.freeciv.org/Ticket/Display.html?id=10393 > In PR#10047 I made some additional changes removing is_real_map_pos and normalize_map_pos. However these were premature since it was impossible to debug these changes alongside the rest of the PR#10047 junk. So now... This patch changes map_pos_to_tile and native_pos_to_tile to do wrapping. Thus map_pos_to_tile replaces normalize_map_pos and is_normal_map_pos in most (but not all) callers. This allows the code to become simpler. A common example is where if (normalize_map_pos(&x, &y)) { ptile = map_pos_to_tile(x, y); /* ... */ } is replaced by if ((ptile = map_pos_to_tile(x, y))) { /* ... */ } which is slightly shorter and avoids duplicating the function call. A better example is the one I gave earlier from mapgen.c, where native_pos_to_tile becomes very useful. I ran autogames from all generators and found them to be unchanged under the patch. I only timed one of them and found an 8% speedup (with DEBUG). This is almost certainly because of the inlining done in iterate_outward_dxy (this macro was erronously made inefficient in the earlier patch). The patch also removes a shadowed variable in road_bonus(). jason Index: client/mapview_common.c =================================================================== RCS file: /home/freeciv/CVS/freeciv/client/mapview_common.c,v retrieving revision 1.149 diff -u -r1.149 mapview_common.c --- client/mapview_common.c 29 Sep 2004 02:24:19 -0000 1.149 +++ client/mapview_common.c 30 Sep 2004 06:27:26 -0000 @@ -1861,10 +1861,10 @@ dest_x = src_tile->x + dx; dest_y = src_tile->y + dy; - if (!normalize_map_pos(&dest_x, &dest_y)) { + dest_tile = map_pos_to_tile(dest_x, dest_y); + if (!dest_tile) { return; } - dest_tile = map_pos_to_tile(dest_x, dest_y); if (tile_visible_mapcanvas(src_tile) || tile_visible_mapcanvas(dest_tile)) { Index: client/mapview_common.h =================================================================== RCS file: /home/freeciv/CVS/freeciv/client/mapview_common.h,v retrieving revision 1.77 diff -u -r1.77 mapview_common.h --- client/mapview_common.h 29 Sep 2004 02:24:19 -0000 1.77 +++ client/mapview_common.h 30 Sep 2004 06:27:26 -0000 @@ -114,10 +114,10 @@ _map_x = GRI_x_itr; \ _map_y = GRI_y_itr; \ } \ - if (!normalize_map_pos(&_map_x, &_map_y)) { \ + ptile = map_pos_to_tile(_map_x, _map_y); \ + if (!ptile) { \ continue; \ - } \ - ptile = map_pos_to_tile(_map_x, _map_y); + } #define gui_rect_iterate_end \ } \ Index: client/gui-gtk/mapctrl.c =================================================================== RCS file: /home/freeciv/CVS/freeciv/client/gui-gtk/mapctrl.c,v retrieving revision 1.100 diff -u -r1.100 mapctrl.c --- client/gui-gtk/mapctrl.c 29 Sep 2004 02:24:20 -0000 1.100 +++ client/gui-gtk/mapctrl.c 30 Sep 2004 06:27:26 -0000 @@ -369,10 +369,10 @@ return TRUE; /* Double-clicks? Triple-clicks? No thanks! */ overview_to_map_pos(&xtile, &ytile, ev->x, ev->y); - if (!normalize_map_pos(&xtile, &ytile)) { + ptile = map_pos_to_tile(xtile, ytile); + if (!ptile) { return TRUE; } - ptile = map_pos_to_tile(xtile, ytile); if (can_client_change_view() && ev->button == 3) { center_tile_mapcanvas(ptile); Index: client/gui-xaw/mapctrl.c =================================================================== RCS file: /home/freeciv/CVS/freeciv/client/gui-xaw/mapctrl.c,v retrieving revision 1.89 diff -u -r1.89 mapctrl.c --- client/gui-xaw/mapctrl.c 29 Sep 2004 20:06:49 -0000 1.89 +++ client/gui-xaw/mapctrl.c 30 Sep 2004 06:27:26 -0000 @@ -274,10 +274,10 @@ } overview_to_map_pos(&map_x, &map_y, event->xbutton.x, event->xbutton.y); - if (!normalize_map_pos(&map_x, &map_y)) { + ptile = map_pos_to_tile(map_x, map_y); + if (!ptile) { return; } - ptile = map_pos_to_tile(map_x, map_y); if(ev->button==Button1) do_map_click(ptile, SELECT_POPUP); Index: common/city.c =================================================================== RCS file: /home/freeciv/CVS/freeciv/common/city.c,v retrieving revision 1.248 diff -u -r1.248 city.c --- common/city.c 29 Sep 2004 02:24:22 -0000 1.248 +++ common/city.c 30 Sep 2004 06:27:27 -0000 @@ -107,11 +107,7 @@ x = city_tile->x + city_map_x - CITY_MAP_SIZE / 2; y = city_tile->y + city_map_y - CITY_MAP_SIZE / 2; - if (normalize_map_pos(&x, &y)) { - return map_pos_to_tile(x, y); - } else { - return NULL; - } + return map_pos_to_tile(x, y); } /************************************************************************** Index: common/map.c =================================================================== RCS file: /home/freeciv/CVS/freeciv/common/map.c,v retrieving revision 1.198 diff -u -r1.198 map.c --- common/map.c 29 Sep 2004 02:24:23 -0000 1.198 +++ common/map.c 30 Sep 2004 06:27:28 -0000 @@ -381,11 +381,34 @@ DIRSTEP(x, y, dir); x += ptile->x; y += ptile->y; - if (!normalize_map_pos(&x, &y)) { + + return map_pos_to_tile(x, y); +} + +/**************************************************************************** + Return the tile for the given native position, with wrapping. + + This is a backend function used by map_pos_to_tile and native_pos_to_tile. + It is called extremely often so it is made inline. +****************************************************************************/ +static inline struct tile *base_native_pos_to_tile(int nat_x, int nat_y) +{ + /* If the position is out of range in a non-wrapping direction, it is + * unreal. */ + if (!((topo_has_flag(TF_WRAPX) || (nat_x >= 0 && nat_x < map.xsize)) + && (topo_has_flag(TF_WRAPY) || (nat_y >= 0 && nat_y < map.ysize)))) { return NULL; } - return map_pos_to_tile(x, y); + /* Wrap in X and Y directions, as needed. */ + if (topo_has_flag(TF_WRAPX)) { + nat_x = FC_WRAP(nat_x, map.xsize); + } + if (topo_has_flag(TF_WRAPY)) { + nat_y = FC_WRAP(nat_y, map.ysize); + } + + return map.tiles + native_pos_to_index(nat_x, nat_y); } /**************************************************************************** @@ -393,10 +416,15 @@ ****************************************************************************/ struct tile *map_pos_to_tile(int map_x, int map_y) { - int index = map_pos_to_index(map_x, map_y); + int nat_x, nat_y; + + if (!map.tiles) { + return NULL; + } - CHECK_INDEX(index); - return map.tiles + index; + /* Normalization is best done in native coordinates. */ + MAP_TO_NATIVE_POS(&nat_x, &nat_y, map_x, map_y); + return base_native_pos_to_tile(nat_x, nat_y); } /**************************************************************************** @@ -404,10 +432,11 @@ ****************************************************************************/ struct tile *native_pos_to_tile(int nat_x, int nat_y) { - int index = native_pos_to_index(nat_x, nat_y); + if (!map.tiles) { + return NULL; + } - CHECK_INDEX(index); - return map.tiles + index; + return base_native_pos_to_tile(nat_x, nat_y); } /**************************************************************************** @@ -415,8 +444,17 @@ ****************************************************************************/ struct tile *index_to_tile(int index) { - CHECK_INDEX(index); - return map.tiles + index; + if (!map.tiles) { + return NULL; + } + + if (index >= 0 && index < MAX_MAP_INDEX) { + return map.tiles + index; + } else { + /* Unwrapped index coordinates are impossible, so the best we can do is + * return NULL. */ + return NULL; + } } /************************************************************************** @@ -1387,9 +1425,10 @@ **************************************************************************/ bool is_normal_map_pos(int x, int y) { - int x1 = x, y1 = y; + int nat_x, nat_y; - return (normalize_map_pos(&x1, &y1) && (x1 == x) && (y1 == y)); + MAP_TO_NATIVE_POS(&nat_x, &nat_y, x, y); + return nat_x >= 0 && nat_x < map.xsize && nat_y >= 0 && nat_y < map.ysize; } /************************************************************************** @@ -1402,29 +1441,15 @@ **************************************************************************/ bool normalize_map_pos(int *x, int *y) { - int nat_x, nat_y; + struct tile *ptile = map_pos_to_tile(*x, *y); - /* Normalization is best done in native coordinatees. */ - MAP_TO_NATIVE_POS(&nat_x, &nat_y, *x, *y); - - /* If the position is out of range in a non-wrapping direction, it is - * unreal. */ - if (!((topo_has_flag(TF_WRAPX) || (nat_x >= 0 && nat_x < map.xsize)) - && (topo_has_flag(TF_WRAPY) || (nat_y >= 0 && nat_y < map.ysize)))) { + if (ptile) { + *x = ptile->x; + *y = ptile->y; + return TRUE; + } else { return FALSE; } - - /* Wrap in X and Y directions, as needed. */ - if (topo_has_flag(TF_WRAPX)) { - nat_x = FC_WRAP(nat_x, map.xsize); - } - if (topo_has_flag(TF_WRAPY)) { - nat_y = FC_WRAP(nat_y, map.ysize); - } - - /* Now transform things back to map coordinates. */ - NATIVE_TO_MAP_POS(x, y, nat_x, nat_y); - return TRUE; } /************************************************************************** @@ -1444,10 +1469,6 @@ } NATIVE_TO_MAP_POS(&x, &y, nat_x, nat_y); - if (!normalize_map_pos(&x, &y)) { - assert(FALSE); - } - return map_pos_to_tile(x, y); } Index: common/map.h =================================================================== RCS file: /home/freeciv/CVS/freeciv/common/map.h,v retrieving revision 1.218 diff -u -r1.218 map.h --- common/map.h 29 Sep 2004 02:24:23 -0000 1.218 +++ common/map.h 30 Sep 2004 06:27:28 -0000 @@ -461,7 +461,7 @@ if (_is_border && !normalize_map_pos(&_x_itr, &_y_itr)) { \ continue; \ } \ - tile_itr = map_pos_to_tile(_x_itr, _y_itr); + tile_itr = map.tiles + map_pos_to_index(_x_itr, _y_itr); #define iterate_outward_dxy_end \ } \ Index: server/gamehand.c =================================================================== RCS file: /home/freeciv/CVS/freeciv/server/gamehand.c,v retrieving revision 1.142 diff -u -r1.142 gamehand.c --- server/gamehand.c 29 Sep 2004 02:24:23 -0000 1.142 +++ server/gamehand.c 30 Sep 2004 06:27:29 -0000 @@ -231,8 +231,7 @@ do { x = p.tile->x + myrand(2 * game.dispersion + 1) - game.dispersion; y = p.tile->y + myrand(2 * game.dispersion + 1) - game.dispersion; - } while (!(normalize_map_pos(&x, &y) - && (ptile = map_pos_to_tile(x, y)) + } while (!((ptile = map_pos_to_tile(x, y)) && map_get_continent(p.tile) == map_get_continent(ptile) && !is_ocean(map_get_terrain(ptile)) && !is_non_allied_unit_tile(ptile, pplayer))); Index: server/settlers.c =================================================================== RCS file: /home/freeciv/CVS/freeciv/server/settlers.c,v retrieving revision 1.204 diff -u -r1.204 settlers.c --- server/settlers.c 29 Sep 2004 02:24:24 -0000 1.204 +++ server/settlers.c 30 Sep 2004 06:27:29 -0000 @@ -559,20 +559,19 @@ bool has_road[12], is_slow[12]; int dx[12] = {-1, 0, 1, -1, 1, -1, 0, 1, 0, -2, 2, 0}; int dy[12] = {-1, -1, -1, 0, 0, 1, 1, 1, -2, 0, 0, 2}; - bool is_border = is_border_tile(ptile, 2); assert(special == S_ROAD || special == S_RAILROAD); for (i = 0; i < 12; i++) { - int x1 = ptile->x + dx[i], y1 = ptile->y + dy[i]; - if (is_border && !normalize_map_pos(&x1, &y1)) { + struct tile *tile1 = map_pos_to_tile(ptile->x + dx[i], ptile->y + dy[i]); + + if (!tile1) { has_road[i] = FALSE; is_slow[i] = FALSE; /* FIXME: should be TRUE? */ } else { - struct tile *ptile = map_pos_to_tile(x1, y1); - struct tile_type *ptype = get_tile_type(ptile->terrain); + struct tile_type *ptype = get_tile_type(tile1->terrain); - has_road[i] = tile_has_special(ptile, special); + has_road[i] = tile_has_special(tile1, special); /* If TRUE, this value indicates that this tile does not need * a road connector. This is set for terrains which cannot have @@ -580,7 +579,7 @@ is_slow[i] = (ptype->road_time == 0 || ptype->road_time > 5); if (!has_road[i]) { - unit_list_iterate(ptile->units, punit) { + unit_list_iterate(tile1->units, punit) { if (punit->activity == ACTIVITY_ROAD || punit->activity == ACTIVITY_RAILROAD) { /* If a road is being built here, consider as if it's already Index: server/stdinhand.c =================================================================== RCS file: /home/freeciv/CVS/freeciv/server/stdinhand.c,v retrieving revision 1.352 diff -u -r1.352 stdinhand.c --- server/stdinhand.c 29 Sep 2004 02:24:24 -0000 1.352 +++ server/stdinhand.c 30 Sep 2004 06:27:30 -0000 @@ -2146,6 +2146,7 @@ } } else if (strcmp(arg[0], "city") == 0) { int x, y; + struct tile *ptile; struct city *pcity; if (ntokens != 3) { @@ -2156,11 +2157,11 @@ cmd_reply(CMD_DEBUG, caller, C_SYNTAX, _("Value 2 & 3 must be integer.")); goto cleanup; } - if (!is_normal_map_pos(x, y)) { + if (!(ptile = map_pos_to_tile(x, y))) { cmd_reply(CMD_DEBUG, caller, C_SYNTAX, _("Bad map coordinates.")); goto cleanup; } - pcity = map_get_city(map_pos_to_tile(x, y)); + pcity = ptile->city; if (!pcity) { cmd_reply(CMD_DEBUG, caller, C_SYNTAX, _("No city at this coordinate.")); goto cleanup; @@ -2176,6 +2177,7 @@ } } else if (strcmp(arg[0], "units") == 0) { int x, y; + struct tile *ptile; if (ntokens != 3) { cmd_reply(CMD_DEBUG, caller, C_SYNTAX, usage); @@ -2185,11 +2187,11 @@ cmd_reply(CMD_DEBUG, caller, C_SYNTAX, _("Value 2 & 3 must be integer.")); goto cleanup; } - if (!is_normal_map_pos(x, y)) { + if (!(ptile = map_pos_to_tile(x, y))) { cmd_reply(CMD_DEBUG, caller, C_SYNTAX, _("Bad map coordinates.")); goto cleanup; } - unit_list_iterate(map_pos_to_tile(x, y)->units, punit) { + unit_list_iterate(ptile->units, punit) { if (punit->debug) { punit->debug = FALSE; cmd_reply(CMD_DEBUG, caller, C_OK, _("%s's %s no longer debugged."), Index: server/unithand.c =================================================================== RCS file: /home/freeciv/CVS/freeciv/server/unithand.c,v retrieving revision 1.307 diff -u -r1.307 unithand.c --- server/unithand.c 29 Sep 2004 02:24:24 -0000 1.307 +++ server/unithand.c 30 Sep 2004 06:27:30 -0000 @@ -73,12 +73,13 @@ void handle_unit_goto(struct player *pplayer, int unit_id, int x, int y) { struct unit *punit = player_find_unit_by_id(pplayer, unit_id); + struct tile *ptile = map_pos_to_tile(x, y); - if (!is_normal_map_pos(x, y) || !punit) { + if (!ptile || !punit) { return; } - punit->goto_tile = map_pos_to_tile(x, y); + punit->goto_tile = ptile; set_unit_activity(punit, ACTIVITY_GOTO); @@ -535,13 +536,12 @@ void handle_unit_move(struct player *pplayer, int unit_id, int x, int y) { struct unit *punit = player_find_unit_by_id(pplayer, unit_id); - struct tile *ptile; + struct tile *ptile = map_pos_to_tile(x, y); - if (!is_normal_map_pos(x, y) || !punit) { + if (!ptile || !punit) { return; } - ptile = map_pos_to_tile(x, y); if (!is_tiles_adjacent(punit->tile, ptile)) { return; } @@ -1559,12 +1559,13 @@ int y) { struct unit *punit = player_find_unit_by_id(pplayer, unit_id); + struct tile *ptile = map_pos_to_tile(x, y); - if (!punit || !is_normal_map_pos(x, y)) { + if (!punit || !ptile) { return; } - (void) do_paradrop(punit, map_pos_to_tile(x, y)); + (void) do_paradrop(punit, ptile); } /************************************************************************** Index: server/generator/mapgen.c =================================================================== RCS file: /home/freeciv/CVS/freeciv/server/generator/mapgen.c,v retrieving revision 1.11 diff -u -r1.11 mapgen.c --- server/generator/mapgen.c 29 Sep 2004 02:24:24 -0000 1.11 +++ server/generator/mapgen.c 30 Sep 2004 06:27:31 -0000 @@ -1200,7 +1200,7 @@ const struct gen234_state *const pstate) { - int xn, yn, x, y; + int xn, yn; assert((pstate->e - pstate->w) > 0); assert((pstate->e - pstate->w) < map.xsize); @@ -1210,11 +1210,7 @@ xn = pstate->w + myrand(pstate->e - pstate->w); yn = pstate->n + myrand(pstate->s - pstate->n); - NATIVE_TO_MAP_POS(&x, &y, xn, yn); - if (!normalize_map_pos(&x, &y)) { - die("Invalid map operation."); - } - return map_pos_to_tile(x, y); + return native_pos_to_tile(xn, yn); } /************************************************************************** @@ -1357,23 +1353,13 @@ for (yn = pstate->n, xn = pstate->w; yn < pstate->s && xn < pstate->e; yn++, xn++) { - int map_x, map_y, map_x0, map_y0; - struct tile *tile1, *tile0; - - NATIVE_TO_MAP_POS(&map_x0, &map_y0, xn, yn); - NATIVE_TO_MAP_POS(&map_x, &map_y, - xn + ptile->nat_x - pstate->w, - yn + ptile->nat_y - pstate->n); + struct tile *tile0 = native_pos_to_tile(xn, yn); + struct tile *tile1 = native_pos_to_tile(xn + ptile->nat_x - pstate->w, + yn + ptile->nat_y - pstate->n); - if (!normalize_map_pos(&map_x0, &map_y0)) { - assert(0); + if (!tile0 || !tile1) { return FALSE; } - tile0 = map_pos_to_tile(map_x0, map_y0); - if (!normalize_map_pos(&map_x, &map_y)) { - return FALSE; - } - tile1 = map_pos_to_tile(map_x, map_y); if (hmap(tile0) != 0 && is_near_land(tile1)) { return FALSE; } @@ -1381,23 +1367,13 @@ for (yn = pstate->n; yn < pstate->s; yn++) { for (xn = pstate->w; xn < pstate->e; xn++) { - int map_x, map_y, map_x0, map_y0; - struct tile *tile1, *tile0; - - NATIVE_TO_MAP_POS(&map_x0, &map_y0, xn, yn); - NATIVE_TO_MAP_POS(&map_x, &map_y, - xn + ptile->nat_x - pstate->w, - yn + ptile->nat_y - pstate->n); + struct tile *tile0 = native_pos_to_tile(xn, yn); + struct tile *tile1 = native_pos_to_tile(xn + ptile->nat_x - pstate->w, + yn + ptile->nat_y - pstate->n); - if (!normalize_map_pos(&map_x0, &map_y0)) { - assert(0); + if (!tile0 || !tile1) { return FALSE; } - tile0 = map_pos_to_tile(map_x0, map_y0); - if (!normalize_map_pos(&map_x, &map_y)) { - return FALSE; - } - tile1 = map_pos_to_tile(map_x, map_y); if (hmap(tile0) != 0 && is_near_land(tile1)) { return FALSE; } @@ -1407,17 +1383,9 @@ for (yn = pstate->n; yn < pstate->s; yn++) { for (xn = pstate->w; xn < pstate->e; xn++) { if (hmap(native_pos_to_tile(xn, yn)) != 0) { - int map_x, map_y; - struct tile *tile1; - - NATIVE_TO_MAP_POS(&map_x, &map_y, - xn + ptile->nat_x - pstate->w, - yn + ptile->nat_y - pstate->n); - - if (!normalize_map_pos(&map_x, &map_y)) { - assert(0); - } - tile1 = map_pos_to_tile(map_x, map_y); + struct tile *tile1 + = native_pos_to_tile(xn + ptile->nat_x - pstate->w, + yn + ptile->nat_y - pstate->n); checkmass--; if (checkmass <= 0) { Index: server/generator/utilities.c =================================================================== RCS file: /home/freeciv/CVS/freeciv/server/generator/utilities.c,v retrieving revision 1.7 diff -u -r1.7 utilities.c --- server/generator/utilities.c 29 Sep 2004 02:24:24 -0000 1.7 +++ server/generator/utilities.c 30 Sep 2004 06:27:31 -0000 @@ -137,17 +137,6 @@ } whole_map_iterate_end; } } -bool normalize_nat_pos(int *x, int *y) -{ - int map_x, map_y; - bool return_value; - - NATIVE_TO_MAP_POS(&map_x, &map_y, *x, *y); - return_value = normalize_map_pos(&map_x, &map_y); - MAP_TO_NATIVE_POS(x, y, map_x, map_y); - - return return_value; -} bool is_normal_nat_pos(int x, int y) { Index: server/generator/utilities.h =================================================================== RCS file: /home/freeciv/CVS/freeciv/server/generator/utilities.h,v retrieving revision 1.3 diff -u -r1.3 utilities.h --- server/generator/utilities.h 29 Sep 2004 02:24:24 -0000 1.3 +++ server/generator/utilities.h 30 Sep 2004 06:27:31 -0000 @@ -48,16 +48,15 @@ for (i = -___dist; i <= ___dist; i++) { \ ___x = _center_tile->nat_x + (___Xaxe ? i : 0); \ ___y = _center_tile->nat_y + (___Xaxe ? 0 : i); \ - if(!normalize_nat_pos(&___x, &___y)) { \ + iter_tile = native_pos_to_tile(___x, ___y); \ + if (!iter_tile) { \ continue; \ - }; \ - iter_tile = native_pos_to_tile(___x, ___y); + } #define iterate_axe_end \ } \ } -bool normalize_nat_pos(int *x, int *y); bool is_normal_nat_pos(int x, int y); /* int maps tools */
|