There are two remaining MAP_MAX_WIDTH * MAP_MAX_HEIGHT arrays: in
settlers.c.
These present problems when increasing MAP_MAX_WIDTH and
MAP_MAX_HEIGHT. They also break under gen-topologies. And of
course they waste memory in general.
The attached patch replaces them with dynamic arrays, as is used
everywhere else. Autogames are identical and slightly faster
(probably because of the direct memset to territory).
And I say that this will be slower that current code.
current we have static double array (
static nearness territory[MAP_MAX_WIDTH][MAP_MAX_HEIGHT]
and any access from map position is simple , just call territory[x1]
[y1] or minimap[x1][y1].
when we make this change we must made conversion from (x1,y1) ->
index each time when we call TERRITORY(x1, y1) or MINIMAP(x1, y1)
this is make by calling
#define TERRITORY(map_x, map_y) territory[map_pos_to_index(map_x,
map_y)]
#define MINIMAP(map_x, map_y) minimap[map_pos_to_index(map_x, map_y)]
where #define map_pos_to_index(map_x, map_y) \
(CHECK_MAP_POS((map_x), (map_y)), \
(map_x) + (map_y) * map.xsize)
in this way you add one "*" operation when you want get terrain[][]
or minimap[][]
in connection with WARMAP_xxx(x, y) code (the same problem) the
situation will be whorse.
same problem was reported by Gregory in WARMAP code where you made
same replace.
exp:
static void init_warmap(int orig_x, int orig_y, enum unit_move_type
move_type)
{
if (!warmap.cost) {
warmap.cost = fc_malloc(map.xsize * map.ysize * sizeof(*warmap.
cost));
warmap.seacost = fc_malloc(map.xsize * map.ysize
* sizeof(*warmap.seacost));
warmap.vector = fc_malloc(map.xsize * map.ysize
* sizeof(*warmap.vector));
}
init_queue();
switch (move_type) {
case LAND_MOVING:
case HELI_MOVING:
case AIR_MOVING:
whole_map_iterate(x, y) {
WARMAP_COST(x, y) = MAXCOST;
} whole_map_iterate_end;
WARMAP_COST(orig_x, orig_y) = 0;
break;
case SEA_MOVING:
whole_map_iterate(x, y) {
WARMAP_SEACOST(x, y) = MAXCOST;
} whole_map_iterate_end;
WARMAP_SEACOST(orig_x, orig_y) = 0;
break;
default:
freelog(LOG_ERROR, "Bad move_type in init_warmap().");
}
}
where...
#define WARMAP_COST(x, y) (warmap.cost[map_pos_to_index(x, y)])
and whole_map_iterate(x, y) {
WARMAP_COST(x, y) = MAXCOST;
} whole_map_iterate_end;
real is index -> (x, y) -> index
{
int WMI_index; /* We use index positions for cache efficiency. */
for (WMI_index = 0; WMI_index < MAX_MAP_INDEX; WMI_index++) {
int map_x, map_y;
index_to_map_pos(&map_x, &map_y, WMI_index);
{
(warmap.cost[map_pos_to_index(map_x, map_y)]) = MAXCOST;
}
}
}
what happend when we look on index_to_map_pos macro ?
#define index_to_map_pos(pmap_x, pmap_y, index) \
(CHECK_INDEX(index), \
*(pmap_x) = (index) % map.xsize, \
*(pmap_y) = (index) / map.xsize)
but returning to current patch, PLEASE use "index" instead (x, y)
#define INDEXED_TERRITORY(index) territory[index]
#define INDEXED_MINIMAP(index) minimap[index]
or call it direct and add such code
...
index = map_pos_to_index( x, y );
ptile = map.tiles + index;
...
...
if(tile->continent = cont && INDEXED_WARMAP(index) > size_of_my_room
) {
INDEXED_TERRITORY(index) = 0;
}
...
...
etc
using of memset is very good idea and should be used in init_warmap()
if this problem was discused then sorry becouse last days I spend in
bed with high heat.
Rafal