[Freeciv-Dev] Re: (PR#10865) mapview layers
[Top] [All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
<URL: http://bugs.freeciv.org/Ticket/Display.html?id=10865 >
Jason Short wrote:
> <URL: http://bugs.freeciv.org/Ticket/Display.html?id=10865 >
>
> Now when I measure it there is no difference in speed. So I will start
> looking at this patch again.
>
> Can anyone else measure this?
Here's another updated patch. I removed the log calls.
In my tests this patch slows drawing on my system from 22.8 FPS to 22.1
FPS with trident and a particular savegame. With isotrident and the
same savegame it drops from 12.9 to 12.2 FPS.
Also attached is the FPS patch I used to get these numbers. Get a map
with all tiles known and then press "c", and it will do extensive FPS
calculations.
-jason
Index: client/citydlg_common.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/citydlg_common.c,v
retrieving revision 1.51
diff -u -r1.51 citydlg_common.c
--- client/citydlg_common.c 30 Nov 2004 08:37:02 -0000 1.51
+++ client/citydlg_common.c 12 Dec 2004 02:44:31 -0000
@@ -173,14 +173,16 @@
get_citydlg_canvas_width(),
get_citydlg_canvas_height());
- citydlg_known_iterate(pcity, city_x, city_y,
- ptile, canvas_x, canvas_y) {
- if (is_isometric) {
- put_one_tile_iso(pcanvas, ptile, canvas_x, canvas_y, TRUE);
- } else {
- put_one_tile(pcanvas, ptile, canvas_x, canvas_y, TRUE);
- }
- } citydlg_known_iterate_end;
+ mapview_layer_iterate(layer) {
+ citydlg_known_iterate(pcity, city_x, city_y,
+ ptile, canvas_x, canvas_y) {
+ if (is_isometric) {
+ put_one_tile_iso(pcanvas, layer, ptile, canvas_x, canvas_y, TRUE);
+ } else {
+ put_one_tile(pcanvas, layer, ptile, canvas_x, canvas_y, TRUE);
+ }
+ } citydlg_known_iterate_end;
+ } mapview_layer_iterate_end;
/* We have to put the output afterwards or it will be covered
* in iso-view. */
Index: client/mapview_common.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/mapview_common.c,v
retrieving revision 1.164
diff -u -r1.164 mapview_common.c
--- client/mapview_common.c 9 Dec 2004 21:28:53 -0000 1.164
+++ client/mapview_common.c 12 Dec 2004 02:44:32 -0000
@@ -873,11 +873,15 @@
struct canvas *pcanvas, int canvas_x, int canvas_y)
{
struct drawn_sprite drawn_sprites[40];
- int count = fill_sprite_array(drawn_sprites, NULL, punit, NULL, FALSE);
canvas_y += (UNIT_TILE_HEIGHT - NORMAL_TILE_HEIGHT);
- put_drawn_sprites(pcanvas, canvas_x, canvas_y,
- count, drawn_sprites, FALSE);
+ mapview_layer_iterate(layer) {
+ int count = fill_sprite_array(drawn_sprites, layer,
+ NULL, punit, NULL, FALSE);
+
+ put_drawn_sprites(pcanvas, canvas_x, canvas_y,
+ count, drawn_sprites, FALSE);
+ } mapview_layer_iterate_end;
}
/**************************************************************************
@@ -888,11 +892,15 @@
struct canvas *pcanvas, int canvas_x, int canvas_y)
{
struct drawn_sprite drawn_sprites[40];
- int count = fill_sprite_array(drawn_sprites, NULL, NULL, pcity, FALSE);
canvas_y += (UNIT_TILE_HEIGHT - NORMAL_TILE_HEIGHT);
- put_drawn_sprites(pcanvas, canvas_x, canvas_y,
- count, drawn_sprites, FALSE);
+ mapview_layer_iterate(layer) {
+ int count = fill_sprite_array(drawn_sprites, layer,
+ NULL, NULL, pcity, FALSE);
+
+ put_drawn_sprites(pcanvas, canvas_x, canvas_y,
+ count, drawn_sprites, FALSE);
+ } mapview_layer_iterate_end;
}
/**************************************************************************
@@ -904,12 +912,16 @@
struct canvas *pcanvas, int canvas_x, int canvas_y)
{
struct drawn_sprite drawn_sprites[40];
- int count = fill_sprite_array(drawn_sprites, ptile, NULL, NULL, FALSE);
/* Use full tile height, even for terrains. */
canvas_y += (UNIT_TILE_HEIGHT - NORMAL_TILE_HEIGHT);
- put_drawn_sprites(pcanvas, canvas_x, canvas_y,
- count, drawn_sprites, FALSE);
+ mapview_layer_iterate(layer) {
+ int count = fill_sprite_array(drawn_sprites, layer,
+ ptile, NULL, NULL, FALSE);
+
+ put_drawn_sprites(pcanvas, canvas_x, canvas_y,
+ count, drawn_sprites, FALSE);
+ } mapview_layer_iterate_end;
}
/****************************************************************************
@@ -1307,24 +1319,17 @@
Draw the given map tile at the given canvas position in non-isometric
view.
**************************************************************************/
-void put_one_tile(struct canvas *pcanvas, struct tile *ptile,
+void put_one_tile(struct canvas *pcanvas, enum mapview_layer layer,
+ struct tile *ptile,
int canvas_x, int canvas_y, bool citymode)
{
- if (tile_get_known(ptile) != TILE_UNKNOWN) {
- struct drawn_sprite tile_sprs[80];
-
- int count = fill_sprite_array(tile_sprs, ptile,
- get_drawable_unit(ptile, citymode),
- map_get_city(ptile), citymode);
+ struct drawn_sprite tile_sprs[80];
+ int count = fill_sprite_array(tile_sprs, layer, ptile,
+ get_drawable_unit(ptile, citymode),
+ map_get_city(ptile), citymode);
- put_drawn_sprites(pcanvas, canvas_x, canvas_y,
- count, tile_sprs, FALSE);
- } else {
- /* tile is unknown */
- canvas_put_rectangle(pcanvas, COLOR_STD_BLACK,
- canvas_x, canvas_y,
- NORMAL_TILE_WIDTH, NORMAL_TILE_HEIGHT);
- }
+ put_drawn_sprites(pcanvas, canvas_x, canvas_y,
+ count, tile_sprs, FALSE);
}
/**************************************************************************
@@ -1332,14 +1337,14 @@
The coordinates have not been normalized, and are not guaranteed to be
real (we have to draw unreal tiles too).
**************************************************************************/
-static void put_tile(struct tile *ptile)
+static void put_tile(struct tile *ptile, enum mapview_layer layer)
{
int canvas_x, canvas_y;
if (tile_to_canvas_pos(&canvas_x, &canvas_y, ptile)) {
freelog(LOG_DEBUG, "putting (%d,%d) at (%d,%d)",
TILE_XY(ptile), canvas_x, canvas_y);
- put_one_tile(mapview_canvas.store, ptile,
+ put_one_tile(mapview_canvas.store, layer, ptile,
canvas_x, canvas_y, FALSE);
}
}
@@ -1457,14 +1462,15 @@
/**************************************************************************
Draw some or all of a tile onto the canvas, in iso-view.
**************************************************************************/
-void put_one_tile_iso(struct canvas *pcanvas, struct tile *ptile,
+void put_one_tile_iso(struct canvas *pcanvas, enum mapview_layer layer,
+ struct tile *ptile,
int canvas_x, int canvas_y, bool citymode)
{
struct drawn_sprite tile_sprs[80];
- int count = fill_sprite_array(tile_sprs, ptile,
+ bool fog = ptile->known == TILE_KNOWN_FOGGED && draw_fog_of_war;
+ int count = fill_sprite_array(tile_sprs, layer, ptile,
get_drawable_unit(ptile, citymode),
ptile->city, citymode);
- bool fog = ptile->known == TILE_KNOWN_FOGGED && draw_fog_of_war;
/*** Draw terrain and specials ***/
put_drawn_sprites(pcanvas, canvas_x, canvas_y, count, tile_sprs, fog);
@@ -1475,7 +1481,7 @@
The coordinates have not been normalized, and are not guaranteed to be
real (we have to draw unreal tiles too).
**************************************************************************/
-static void put_tile_iso(struct tile *ptile)
+static void put_tile_iso(struct tile *ptile, enum mapview_layer layer)
{
int canvas_x, canvas_y;
@@ -1483,7 +1489,7 @@
freelog(LOG_DEBUG, "putting (%d,%d) at (%d,%d)",
TILE_XY(ptile), canvas_x, canvas_y);
- put_one_tile_iso(mapview_canvas.store,
+ put_one_tile_iso(mapview_canvas.store, layer,
ptile, canvas_x, canvas_y,
FALSE);
}
@@ -1547,21 +1553,23 @@
/* FIXME: we don't have to draw black (unknown) tiles since they're already
* cleared. */
- if (is_isometric) {
- gui_rect_iterate(gui_x0, gui_y0, width, height + NORMAL_TILE_HEIGHT / 2,
- ptile) {
- put_tile_iso(ptile);
- } gui_rect_iterate_end;
- } else {
- /* not isometric */
- gui_rect_iterate(gui_x0, gui_y0, width, height, ptile) {
- /*
- * We don't normalize until later because we want to draw
- * black tiles for unreal positions.
- */
- put_tile(ptile);
- } gui_rect_iterate_end;
- }
+ mapview_layer_iterate(layer) {
+ if (is_isometric) {
+ gui_rect_iterate(gui_x0, gui_y0, width, height + NORMAL_TILE_HEIGHT / 2,
+ ptile) {
+ put_tile_iso(ptile, layer);
+ } gui_rect_iterate_end;
+ } else {
+ /* not isometric */
+ gui_rect_iterate(gui_x0, gui_y0, width, height, ptile) {
+ /*
+ * We don't normalize until later because we want to draw
+ * black tiles for unreal positions.
+ */
+ put_tile(ptile, layer);
+ } gui_rect_iterate_end;
+ }
+ } mapview_layer_iterate_end;
/* Draw the goto lines on top of the whole thing. This is done last as
* we want it completely on top.
Index: client/mapview_common.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/mapview_common.h,v
retrieving revision 1.82
diff -u -r1.82 mapview_common.h
--- client/mapview_common.h 9 Dec 2004 21:28:53 -0000 1.82
+++ client/mapview_common.h 12 Dec 2004 02:44:32 -0000
@@ -179,9 +179,11 @@
void put_nuke_mushroom_pixmaps(struct tile *ptile);
-void put_one_tile(struct canvas *pcanvas, struct tile *ptile,
+void put_one_tile(struct canvas *pcanvas, enum mapview_layer layer,
+ struct tile *ptile,
int canvas_x, int canvas_y, bool citymode);
-void put_one_tile_iso(struct canvas *pcanvas, struct tile *ptile,
+void put_one_tile_iso(struct canvas *pcanvas, enum mapview_layer layer,
+ struct tile *ptile,
int canvas_x, int canvas_y, bool citymode);
void tile_draw_grid(struct canvas *pcanvas, struct tile *ptile,
int canvas_x, int canvas_y, bool citymode);
Index: client/tilespec.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/tilespec.c,v
retrieving revision 1.219
diff -u -r1.219 tilespec.c
--- client/tilespec.c 11 Dec 2004 23:07:33 -0000 1.219
+++ client/tilespec.c 12 Dec 2004 02:44:33 -0000
@@ -2444,6 +2444,7 @@
include specials or rivers.
****************************************************************************/
static int fill_terrain_sprite_array(struct drawn_sprite *sprs,
+ int layer,
struct tile *ptile,
Terrain_type_id *ttype_near)
{
@@ -2451,7 +2452,8 @@
struct Sprite *sprite;
Terrain_type_id ttype = ptile->terrain;
struct terrain_drawing_data *draw = sprites.terrain[ttype];
- int l, i, tileno;
+ const int l = layer;
+ int i, tileno;
struct tile *adjc_tile;
if (!draw_terrain) {
@@ -2460,156 +2462,162 @@
/* Skip the normal drawing process. */
if (ptile->spec_sprite && (sprite = load_sprite(ptile->spec_sprite))) {
- ADD_SPRITE_SIMPLE(sprite);
- return 1;
+ if (layer == 0) {
+ ADD_SPRITE_SIMPLE(sprite);
+ return 1;
+ } else {
+ return 0;
+ }
}
- for (l = 0; l < draw->num_layers; l++) {
- if (draw->layer[l].match_style == MATCH_NONE) {
- int count = sprite_vector_size(&draw->layer[l].base);
+ if (l >= draw->num_layers) {
+ return 0;
+ }
- /* Pseudo-random reproducable algorithm to pick a sprite. */
+ if (draw->layer[l].match_style == MATCH_NONE) {
+ int count = sprite_vector_size(&draw->layer[l].base);
+
+ /* Pseudo-random reproducable algorithm to pick a sprite. */
#define LARGE_PRIME 10007
#define SMALL_PRIME 1009
- assert(count < SMALL_PRIME);
- assert((int)(LARGE_PRIME * MAP_INDEX_SIZE) > 0);
- count = ((ptile->index
- * LARGE_PRIME) % SMALL_PRIME) % count;
- ADD_SPRITE(draw->layer[l].base.p[count],
- draw->layer[l].is_tall ? DRAW_FULL : DRAW_NORMAL,
- TRUE, draw->layer[l].offset_x, draw->layer[l].offset_y);
- } else {
- int match_type = draw->layer[l].match_type;
+ assert(count < SMALL_PRIME);
+ assert((int)(LARGE_PRIME * MAP_INDEX_SIZE) > 0);
+ count = ((ptile->index
+ * LARGE_PRIME) % SMALL_PRIME) % count;
+ ADD_SPRITE(draw->layer[l].base.p[count],
+ draw->layer[l].is_tall ? DRAW_FULL : DRAW_NORMAL,
+ TRUE, draw->layer[l].offset_x, draw->layer[l].offset_y);
+ } else {
+ int match_type = draw->layer[l].match_type;
#define MATCH(dir) \
- (sprites.terrain[ttype_near[(dir)]]->num_layers > l \
- ? sprites.terrain[ttype_near[(dir)]]->layer[l].match_type : -1)
+ (sprites.terrain[ttype_near[(dir)]]->num_layers > l
\
+ ? sprites.terrain[ttype_near[(dir)]]->layer[l].match_type : -1)
- if (draw->layer[l].cell_type == CELL_SINGLE) {
- tileno = 0;
- assert(draw->layer[l].match_style == MATCH_BOOLEAN);
- for (i = 0; i < num_cardinal_tileset_dirs; i++) {
- enum direction8 dir = cardinal_tileset_dirs[i];
+ if (draw->layer[l].cell_type == CELL_SINGLE) {
+ tileno = 0;
+ assert(draw->layer[l].match_style == MATCH_BOOLEAN);
+ for (i = 0; i < num_cardinal_tileset_dirs; i++) {
+ enum direction8 dir = cardinal_tileset_dirs[i];
- if (MATCH(dir) == match_type) {
- tileno |= 1 << i;
- }
+ if (MATCH(dir) == match_type) {
+ tileno |= 1 << i;
}
+ }
- ADD_SPRITE(draw->layer[l].match[tileno],
- draw->layer[l].is_tall ? DRAW_FULL : DRAW_NORMAL,
- TRUE, draw->layer[l].offset_x, draw->layer[l].offset_y);
- } else if (draw->layer[l].cell_type == CELL_RECT) {
- /* Divide the tile up into four rectangular cells. Now each of these
- * cells covers one corner, and each is adjacent to 3 different
- * tiles. For each cell we pixk a sprite based upon the adjacent
- * terrains at each of those tiles. Thus we have 8 different sprites
- * for each of the 4 cells (32 sprites total).
- *
- * These arrays correspond to the direction4 ordering. */
- const int W = NORMAL_TILE_WIDTH, H = NORMAL_TILE_HEIGHT;
- const int iso_offsets[4][2] = {
- {W / 4, 0}, {W / 4, H / 2}, {W / 2, H / 4}, {0, H / 4}
- };
- const int noniso_offsets[4][2] = {
- {0, 0}, {W / 2, H / 2}, {W / 2, 0}, {0, H / 2}
- };
- int i;
+ ADD_SPRITE(draw->layer[l].match[tileno],
+ draw->layer[l].is_tall ? DRAW_FULL : DRAW_NORMAL,
+ TRUE, draw->layer[l].offset_x, draw->layer[l].offset_y);
+ } else if (draw->layer[l].cell_type == CELL_RECT) {
+ /* Divide the tile up into four rectangular cells. Now each of these
+ * cells covers one corner, and each is adjacent to 3 different
+ * tiles. For each cell we pixk a sprite based upon the adjacent
+ * terrains at each of those tiles. Thus we have 8 different sprites
+ * for each of the 4 cells (32 sprites total).
+ *
+ * These arrays correspond to the direction4 ordering. */
+ const int W = NORMAL_TILE_WIDTH, H = NORMAL_TILE_HEIGHT;
+ const int iso_offsets[4][2] = {
+ {W / 4, 0}, {W / 4, H / 2}, {W / 2, H / 4}, {0, H / 4}
+ };
+ const int noniso_offsets[4][2] = {
+ {0, 0}, {W / 2, H / 2}, {W / 2, 0}, {0, H / 2}
+ };
+ int i;
+
+ /* put corner cells */
+ for (i = 0; i < NUM_CORNER_DIRS; i++) {
+ const int count = draw->layer[l].match_count;
+ int array_index = 0;
+ enum direction8 dir = dir_ccw(DIR4_TO_DIR8[i]);
+ int x = (is_isometric ? iso_offsets[i][0] : noniso_offsets[i][0]);
+ int y = (is_isometric ? iso_offsets[i][1] : noniso_offsets[i][1]);
+ int m[3] = {MATCH(dir_ccw(dir)), MATCH(dir), MATCH(dir_cw(dir))};
+ struct Sprite *s;
+
+ switch (draw->layer[l].match_style) {
+ case MATCH_NONE:
+ /* Impossible */
+ assert(0);
+ break;
+ case MATCH_BOOLEAN:
+ assert(count == 2);
+ array_index = array_index * count + (m[2] != match_type);
+ array_index = array_index * count + (m[1] != match_type);
+ array_index = array_index * count + (m[0] != match_type);
+ break;
+ case MATCH_FULL:
+ if (m[0] == -1 || m[1] == -1 || m[2] == -1) {
+ break;
+ }
+ array_index = array_index * count + m[2];
+ array_index = array_index * count + m[1];
+ array_index = array_index * count + m[0];
+ break;
+ }
+ array_index = array_index * NUM_CORNER_DIRS + i;
- /* put corner cells */
- for (i = 0; i < NUM_CORNER_DIRS; i++) {
- const int count = draw->layer[l].match_count;
- int array_index = 0;
- enum direction8 dir = dir_ccw(DIR4_TO_DIR8[i]);
- int x = (is_isometric ? iso_offsets[i][0] : noniso_offsets[i][0]);
- int y = (is_isometric ? iso_offsets[i][1] : noniso_offsets[i][1]);
- int m[3] = {MATCH(dir_ccw(dir)), MATCH(dir), MATCH(dir_cw(dir))};
- struct Sprite *s;
-
- switch (draw->layer[l].match_style) {
- case MATCH_NONE:
- /* Impossible */
- assert(0);
- break;
- case MATCH_BOOLEAN:
- assert(count == 2);
- array_index = array_index * count + (m[2] != match_type);
- array_index = array_index * count + (m[1] != match_type);
- array_index = array_index * count + (m[0] != match_type);
- break;
- case MATCH_FULL:
- if (m[0] == -1 || m[1] == -1 || m[2] == -1) {
- break;
- }
- array_index = array_index * count + m[2];
- array_index = array_index * count + m[1];
- array_index = array_index * count + m[0];
- break;
- }
- array_index = array_index * NUM_CORNER_DIRS + i;
-
- s = draw->layer[l].cells[array_index];
- if (s) {
- ADD_SPRITE(s, DRAW_NORMAL, TRUE, x, y);
- }
+ s = draw->layer[l].cells[array_index];
+ if (s) {
+ ADD_SPRITE(s, DRAW_NORMAL, TRUE, x, y);
}
}
-#undef MATCH
}
+#undef MATCH
+ }
- /* Add blending on top of the first layer. */
- if (l == 0 && draw->is_blended) {
- sprs += fill_blending_sprite_array(sprs, ptile, ttype_near);
- }
+ /* Add blending on top of the first layer. */
+ if (l == 0 && draw->is_blended) {
+ sprs += fill_blending_sprite_array(sprs, ptile, ttype_near);
+ }
- /* Add darkness on top of the first layer. Note that darkness is always
- * drawn, even in citymode, etc. */
- if (l == 0) {
+ /* Add darkness on top of the first layer. Note that darkness is always
+ * drawn, even in citymode, etc. */
+ if (l == 0) {
#define UNKNOWN(dir) \
- ((adjc_tile = mapstep(ptile, (dir))) \
- && tile_get_known(adjc_tile) == TILE_UNKNOWN)
+ ((adjc_tile = mapstep(ptile, (dir))) \
+ && tile_get_known(adjc_tile) == TILE_UNKNOWN)
- switch (darkness_style) {
- case DARKNESS_NONE:
- break;
- case DARKNESS_ISORECT:
- for (i = 0; i < 4; i++) {
- const int W = NORMAL_TILE_WIDTH, H = NORMAL_TILE_HEIGHT;
- int offsets[4][2] = {{W / 2, 0}, {0, H / 2}, {W / 2, H / 2}, {0, 0}};
-
- if (UNKNOWN(DIR4_TO_DIR8[i])) {
- ADD_SPRITE(sprites.tx.darkness[i], DRAW_NORMAL, TRUE,
- offsets[i][0], offsets[i][1]);
- }
+ switch (darkness_style) {
+ case DARKNESS_NONE:
+ break;
+ case DARKNESS_ISORECT:
+ for (i = 0; i < 4; i++) {
+ const int W = NORMAL_TILE_WIDTH, H = NORMAL_TILE_HEIGHT;
+ int offsets[4][2] = {{W / 2, 0}, {0, H / 2}, {W / 2, H / 2}, {0, 0}};
+
+ if (UNKNOWN(DIR4_TO_DIR8[i])) {
+ ADD_SPRITE(sprites.tx.darkness[i], DRAW_NORMAL, TRUE,
+ offsets[i][0], offsets[i][1]);
}
- break;
- case DARKNESS_CARD_SINGLE:
- for (i = 0; i < num_cardinal_tileset_dirs; i++) {
- if (UNKNOWN(cardinal_tileset_dirs[i])) {
- ADD_SPRITE_SIMPLE(sprites.tx.darkness[i]);
- }
+ }
+ break;
+ case DARKNESS_CARD_SINGLE:
+ for (i = 0; i < num_cardinal_tileset_dirs; i++) {
+ if (UNKNOWN(cardinal_tileset_dirs[i])) {
+ ADD_SPRITE_SIMPLE(sprites.tx.darkness[i]);
}
- break;
- case DARKNESS_CARD_FULL:
- /* We're looking to find the INDEX_NSEW for the directions that
- * are unknown. We want to mark unknown tiles so that an unreal
- * tile will be given the same marking as our current tile - that
- * way we won't get the "unknown" dither along the edge of the
- * map. */
- tileno = 0;
- for (i = 0; i < num_cardinal_tileset_dirs; i++) {
- if (UNKNOWN(cardinal_tileset_dirs[i])) {
- tileno |= 1 << i;
- }
+ }
+ break;
+ case DARKNESS_CARD_FULL:
+ /* We're looking to find the INDEX_NSEW for the directions that
+ * are unknown. We want to mark unknown tiles so that an unreal
+ * tile will be given the same marking as our current tile - that
+ * way we won't get the "unknown" dither along the edge of the
+ * map. */
+ tileno = 0;
+ for (i = 0; i < num_cardinal_tileset_dirs; i++) {
+ if (UNKNOWN(cardinal_tileset_dirs[i])) {
+ tileno |= 1 << i;
}
+ }
- if (tileno != 0) {
- ADD_SPRITE_SIMPLE(sprites.tx.darkness[tileno]);
- }
- break;
+ if (tileno != 0) {
+ ADD_SPRITE_SIMPLE(sprites.tx.darkness[tileno]);
}
-#undef UNKNOWN
+ break;
}
+#undef UNKNOWN
}
return sprs - saved_sprs;
@@ -2632,7 +2640,8 @@
citymode specifies whether this is part of a citydlg. If so some drawing
is done differently.
****************************************************************************/
-int fill_sprite_array(struct drawn_sprite *sprs, struct tile *ptile,
+int fill_sprite_array(struct drawn_sprite *sprs, enum mapview_layer layer,
+ struct tile *ptile,
struct unit *punit, struct city *pcity,
bool citymode)
{
@@ -2642,155 +2651,199 @@
struct unit *pfocus = get_unit_in_focus();
struct drawn_sprite *save_sprs = sprs;
- if (ptile && tile_get_known(ptile) == TILE_UNKNOWN) {
- return sprs - save_sprs;
+ if (ptile && tile_get_known(ptile) != TILE_UNKNOWN) {
+ build_tile_data(ptile,
+ &ttype, &tspecial, ttype_near, tspecial_near);
}
- /* Set up background color. */
- if (solid_color_behind_units) {
- if (punit && (draw_units || (draw_focus_unit && pfocus == punit))) {
- ADD_BG(player_color(unit_owner(punit)));
- } else if (pcity && draw_cities) {
- ADD_BG(player_color(city_owner(pcity)));
+ switch (layer) {
+ case LAYER_BACKGROUND:
+ if (ptile && tile_get_known(ptile) == TILE_UNKNOWN) {
+ ADD_BG(COLOR_STD_BLACK);
+ return sprs - save_sprs;
}
- } else if (!draw_terrain) {
- if (ptile) {
+
+ /* Set up background color. */
+ if (solid_color_behind_units) {
+ if (punit && (draw_units || (draw_focus_unit && pfocus == punit))) {
+ ADD_BG(player_color(unit_owner(punit)));
+ } else if (pcity && draw_cities) {
+ ADD_BG(player_color(city_owner(pcity)));
+ }
+ } else if (ptile && !draw_terrain) {
ADD_BG(COLOR_STD_BACKGROUND);
}
- }
+ break;
- /* Terrain and specials. */
- if (ptile) {
- build_tile_data(ptile,
- &ttype, &tspecial, ttype_near, tspecial_near);
-
- sprs += fill_terrain_sprite_array(sprs, ptile, ttype_near);
-
- if (is_ocean(ttype) && draw_terrain) {
- for (dir = 0; dir < 4; dir++) {
- if (contains_special(tspecial_near[DIR4_TO_DIR8[dir]], S_RIVER)) {
- ADD_SPRITE_SIMPLE(sprites.tx.river_outlet[dir]);
+ case LAYER_TERRAIN1:
+ case LAYER_TERRAIN2:
+ /* Terrain and specials. These are drawn in multiple layers so that
+ * upper layers will cover layers underneath. */
+ if (ptile && tile_get_known(ptile) != TILE_UNKNOWN) {
+ assert(MAX_NUM_LAYERS == 2);
+ sprs += fill_terrain_sprite_array(sprs,
+ (layer == LAYER_TERRAIN1) ? 0 : 1,
+ ptile, ttype_near);
+ }
+ break;
+
+ case LAYER_WATER:
+ if (ptile && tile_get_known(ptile) != TILE_UNKNOWN) {
+ if (is_ocean(ttype) && draw_terrain) {
+ for (dir = 0; dir < 4; dir++) {
+ if (contains_special(tspecial_near[DIR4_TO_DIR8[dir]], S_RIVER)) {
+ ADD_SPRITE_SIMPLE(sprites.tx.river_outlet[dir]);
+ }
}
}
- }
- sprs += fill_irrigation_sprite_array(sprs, tspecial, tspecial_near,
- pcity);
+ sprs += fill_irrigation_sprite_array(sprs, tspecial, tspecial_near,
+ pcity);
- if (draw_terrain && contains_special(tspecial, S_RIVER)) {
- int i;
+ if (draw_terrain && contains_special(tspecial, S_RIVER)) {
+ int i;
- /* Draw rivers on top of irrigation. */
- tileno = 0;
- for (i = 0; i < num_cardinal_tileset_dirs; i++) {
- enum direction8 dir = cardinal_tileset_dirs[i];
+ /* Draw rivers on top of irrigation. */
+ tileno = 0;
+ for (i = 0; i < num_cardinal_tileset_dirs; i++) {
+ enum direction8 dir = cardinal_tileset_dirs[i];
- if (contains_special(tspecial_near[dir], S_RIVER)
- || is_ocean(ttype_near[dir])) {
- tileno |= 1 << i;
+ if (contains_special(tspecial_near[dir], S_RIVER)
+ || is_ocean(ttype_near[dir])) {
+ tileno |= 1 << i;
+ }
}
+ ADD_SPRITE_SIMPLE(sprites.tx.spec_river[tileno]);
}
- ADD_SPRITE_SIMPLE(sprites.tx.spec_river[tileno]);
}
-
- sprs += fill_road_rail_sprite_array(sprs,
- tspecial, tspecial_near, pcity);
+ break;
- if (draw_specials) {
- if (contains_special(tspecial, S_SPECIAL_1)) {
- ADD_SPRITE_SIMPLE(sprites.terrain[ttype]->special[0]);
- } else if (contains_special(tspecial, S_SPECIAL_2)) {
- ADD_SPRITE_SIMPLE(sprites.terrain[ttype]->special[1]);
+ case LAYER_ROADS:
+ if (ptile && tile_get_known(ptile) != TILE_UNKNOWN) {
+ sprs += fill_road_rail_sprite_array(sprs,
+ tspecial, tspecial_near, pcity);
+ }
+ break;
+
+ case LAYER_SPECIAL1:
+ if (ptile && tile_get_known(ptile) != TILE_UNKNOWN) {
+ if (draw_specials) {
+ if (contains_special(tspecial, S_SPECIAL_1)) {
+ ADD_SPRITE_SIMPLE(sprites.terrain[ttype]->special[0]);
+ } else if (contains_special(tspecial, S_SPECIAL_2)) {
+ ADD_SPRITE_SIMPLE(sprites.terrain[ttype]->special[1]);
+ }
}
- }
- if (draw_fortress_airbase && contains_special(tspecial, S_FORTRESS)
- && sprites.tx.fortress_back) {
- ADD_SPRITE_SIMPLE(sprites.tx.fortress_back);
- }
-
- if (draw_mines && contains_special(tspecial, S_MINE)
- && sprites.terrain[ttype]->mine) {
- ADD_SPRITE_SIMPLE(sprites.terrain[ttype]->mine);
- }
-
- if (draw_specials && contains_special(tspecial, S_HUT)) {
- ADD_SPRITE_SIMPLE(sprites.tx.village);
- }
- }
+ if (draw_fortress_airbase && contains_special(tspecial, S_FORTRESS)
+ && sprites.tx.fortress_back) {
+ ADD_SPRITE_SIMPLE(sprites.tx.fortress_back);
+ }
- if (ptile && is_isometric) {
- /* Add grid. In classic view this is done later. */
- ADD_GRID(ptile, citymode);
- }
+ if (draw_mines && contains_special(tspecial, S_MINE)
+ && sprites.terrain[ttype]->mine) {
+ ADD_SPRITE_SIMPLE(sprites.terrain[ttype]->mine);
+ }
- /* City. Some city sprites are drawn later. */
- if (pcity && draw_cities) {
- if (!solid_color_behind_units) {
- ADD_SPRITE(get_city_nation_flag_sprite(pcity),
- DRAW_FULL, TRUE, flag_offset_x, flag_offset_y);
- }
- ADD_SPRITE_FULL(get_city_sprite(pcity));
- if (pcity->client.occupied) {
- ADD_SPRITE_FULL(get_city_occupied_sprite(pcity));
- }
- if (!is_isometric && city_got_citywalls(pcity)) {
- /* In iso-view the city wall is a part of the city sprite. */
- ADD_SPRITE_SIMPLE(get_city_wall_sprite(pcity));
- }
- if (pcity->client.unhappy) {
- ADD_SPRITE_FULL(sprites.city.disorder);
+ if (draw_specials && contains_special(tspecial, S_HUT)) {
+ ADD_SPRITE_SIMPLE(sprites.tx.village);
+ }
}
- }
+ break;
- if (ptile) {
- if (draw_fortress_airbase && contains_special(tspecial, S_AIRBASE)) {
- ADD_SPRITE_FULL(sprites.tx.airbase);
+ case LAYER_GRID1:
+ if (ptile && tile_get_known(ptile) != TILE_UNKNOWN && is_isometric) {
+ /* Add grid. In classic view this is done later. */
+ ADD_GRID(ptile, citymode);
+ }
+ break;
+
+ case LAYER_CITY1:
+ /* City. Some city sprites are drawn later. */
+ if (pcity && draw_cities) {
+ if (!solid_color_behind_units) {
+ ADD_SPRITE(get_city_nation_flag_sprite(pcity),
+ DRAW_FULL, TRUE, flag_offset_x, flag_offset_y);
+ }
+ ADD_SPRITE_FULL(get_city_sprite(pcity));
+ if (pcity->client.occupied) {
+ ADD_SPRITE_FULL(get_city_occupied_sprite(pcity));
+ }
+ if (!is_isometric && city_got_citywalls(pcity)) {
+ /* In iso-view the city wall is a part of the city sprite. */
+ ADD_SPRITE_SIMPLE(get_city_wall_sprite(pcity));
+ }
+ if (pcity->client.unhappy) {
+ ADD_SPRITE_FULL(sprites.city.disorder);
+ }
}
+ break;
- if (draw_pollution && contains_special(tspecial, S_POLLUTION)) {
- ADD_SPRITE_SIMPLE(sprites.tx.pollution);
- }
- if (draw_pollution && contains_special(tspecial, S_FALLOUT)) {
- ADD_SPRITE_SIMPLE(sprites.tx.fallout);
- }
- }
+ case LAYER_SPECIAL2:
+ if (ptile && tile_get_known(ptile) != TILE_UNKNOWN) {
+ if (draw_fortress_airbase && contains_special(tspecial, S_AIRBASE)) {
+ ADD_SPRITE_FULL(sprites.tx.airbase);
+ }
- if (!is_isometric && draw_fog_of_war
- && ptile && tile_get_known(ptile) == TILE_KNOWN_FOGGED) {
- /* Fogging in non-iso is done this way. */
- ADD_SPRITE_SIMPLE(sprites.tx.fog);
- }
+ if (draw_pollution && contains_special(tspecial, S_POLLUTION)) {
+ ADD_SPRITE_SIMPLE(sprites.tx.pollution);
+ }
+ if (draw_pollution && contains_special(tspecial, S_FALLOUT)) {
+ ADD_SPRITE_SIMPLE(sprites.tx.fallout);
+ }
+ }
+ break;
- /* City size. Drawing this under fog makes it hard to read. */
- if (pcity && draw_cities) {
- if (pcity->size >= 10) {
- ADD_SPRITE(sprites.city.size_tens[pcity->size / 10], DRAW_FULL,
+ case LAYER_FOG:
+ if (!is_isometric && draw_fog_of_war
+ && ptile && tile_get_known(ptile) == TILE_KNOWN_FOGGED) {
+ /* Fogging in non-iso is done this way. */
+ ADD_SPRITE_SIMPLE(sprites.tx.fog);
+ }
+ break;
+
+ case LAYER_CITY2:
+ /* City size. Drawing this under fog makes it hard to read. */
+ if (pcity && draw_cities) {
+ if (pcity->size >= 10) {
+ ADD_SPRITE(sprites.city.size_tens[pcity->size / 10], DRAW_FULL,
+ FALSE, 0, 0);
+ }
+ ADD_SPRITE(sprites.city.size[pcity->size % 10], DRAW_FULL,
FALSE, 0, 0);
}
- ADD_SPRITE(sprites.city.size[pcity->size % 10], DRAW_FULL,
- FALSE, 0, 0);
- }
-
- if (punit && (draw_units || (punit == pfocus && draw_focus_unit))) {
- bool stacked = ptile && (unit_list_size(&ptile->units) > 1);
- bool backdrop = !pcity;
-
- sprs += fill_unit_sprite_array(sprs, punit, stacked, backdrop);
- }
+ break;
- if (ptile) {
- if (is_isometric && draw_fortress_airbase
- && contains_special(tspecial, S_FORTRESS)) {
- /* Draw fortress front in iso-view (non-iso view only has a fortress
- * back). */
- ADD_SPRITE_FULL(sprites.tx.fortress);
+ case LAYER_UNIT:
+ if (punit && (draw_units || (punit == pfocus && draw_focus_unit))) {
+ bool stacked = ptile && (unit_list_size(&ptile->units) > 1);
+ bool backdrop = !pcity;
+
+ sprs += fill_unit_sprite_array(sprs, punit, stacked, backdrop);
+ }
+ break;
+
+ case LAYER_SPECIAL3:
+ if (ptile && tile_get_known(ptile) != TILE_UNKNOWN) {
+ if (is_isometric && draw_fortress_airbase
+ && contains_special(tspecial, S_FORTRESS)) {
+ /* Draw fortress front in iso-view (non-iso view only has a fortress
+ * back). */
+ ADD_SPRITE_FULL(sprites.tx.fortress);
+ }
}
- }
+ break;
- if (ptile && !is_isometric) {
- /* Add grid. In iso-view this is done earlier. */
- ADD_GRID(ptile, citymode);
+ case LAYER_GRID2:
+ if (ptile && tile_get_known(ptile) != TILE_UNKNOWN && !is_isometric) {
+ /* Add grid. In iso-view this is done earlier. */
+ ADD_GRID(ptile, citymode);
+ }
+ break;
+
+ case LAYER_COUNT:
+ assert(0);
+ break;
}
return sprs - save_sprs;
Index: client/tilespec.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/tilespec.h,v
retrieving revision 1.92
diff -u -r1.92 tilespec.h
--- client/tilespec.h 3 Dec 2004 09:39:39 -0000 1.92
+++ client/tilespec.h 12 Dec 2004 02:44:33 -0000
@@ -57,6 +57,38 @@
} data;
};
+/* Items on the mapview are drawn in layers. Each entry below represents
+ * one layer. The names are basically arbitrary and just correspond to
+ * groups of elements in fill_sprite_array(). Callers of fill_sprite_array
+ * must call it once for each layer. */
+enum mapview_layer {
+ LAYER_BACKGROUND,
+ LAYER_TERRAIN1,
+ LAYER_TERRAIN2,
+ LAYER_WATER,
+ LAYER_ROADS,
+ LAYER_SPECIAL1,
+ LAYER_GRID1,
+ LAYER_CITY1,
+ LAYER_SPECIAL2,
+ LAYER_FOG,
+ LAYER_CITY2,
+ LAYER_UNIT,
+ LAYER_SPECIAL3,
+ LAYER_GRID2,
+ LAYER_COUNT
+};
+
+#define mapview_layer_iterate(layer) \
+{ \
+ enum mapview_layer layer; \
+ \
+ for (layer = 0; layer < LAYER_COUNT; layer++) { \
+
+#define mapview_layer_iterate_end \
+ } \
+}
+
const char **get_tileset_list(void);
bool tilespec_read_toplevel(const char *tileset_name);
@@ -79,7 +111,8 @@
/* Gfx support */
-int fill_sprite_array(struct drawn_sprite *sprs, struct tile *ptile,
+int fill_sprite_array(struct drawn_sprite *sprs, enum mapview_layer layer,
+ struct tile *ptile,
struct unit *punit, struct city *pcity,
bool citymode);
Index: client/mapview_common.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/mapview_common.c,v
retrieving revision 1.164
diff -u -r1.164 mapview_common.c
--- client/mapview_common.c 9 Dec 2004 21:28:53 -0000 1.164
+++ client/mapview_common.c 12 Dec 2004 02:32:02 -0000
@@ -507,6 +507,8 @@
double timing_sec = (double)smooth_center_slide_msec / 1000.0, mytime;
static struct timer *anim_timer;
int frames = 0;
+ static int total_frames = 0;
+ static double total_time = 0;
gui_distance_vector(&diff_x, &diff_y, start_x, start_y, gui_x0, gui_y0);
anim_timer = renew_timer_start(anim_timer, TIMER_USER, TIMER_ACTIVE);
@@ -522,8 +524,11 @@
} while (mytime < timing_sec);
mytime = read_timer_seconds(anim_timer);
- freelog(LOG_DEBUG, "Got %d frames in %f seconds: %f FPS.",
- frames, mytime, (double)frames / mytime);
+ total_frames += frames;
+ total_time += mytime;
+ freelog(LOG_NORMAL, "Got %d frames in %f seconds: %f FPS (average %f).",
+ frames, mytime, (double)frames / mytime,
+ (double)total_frames / total_time);
} else {
base_set_mapview_origin(gui_x0, gui_y0);
}
Index: client/gui-gtk-2.0/menu.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-gtk-2.0/menu.c,v
retrieving revision 1.57
diff -u -r1.57 menu.c
--- client/gui-gtk-2.0/menu.c 25 Nov 2004 06:57:17 -0000 1.57
+++ client/gui-gtk-2.0/menu.c 12 Dec 2004 02:32:02 -0000
@@ -353,6 +353,10 @@
break;
case MENU_VIEW_CENTER_VIEW:
center_on_unit();
+ while (1) {
+ struct tile *ptile = rand_map_pos();
+ center_tile_mapcanvas(ptile);
+ }
break;
}
}
- [Freeciv-Dev] Re: (PR#10865) mapview layers,
Jason Short <=
|
|