Complete.Org: Mailing Lists: Archives: freeciv-dev: December 2004:
[Freeciv-Dev] (PR#10865) mapview layers
Home

[Freeciv-Dev] (PR#10865) mapview layers

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
Subject: [Freeciv-Dev] (PR#10865) mapview layers
From: "Jason Short" <jdorje@xxxxxxxxxxxxxxxxxxxxx>
Date: Thu, 16 Dec 2004 11:31:24 -0800
Reply-to: bugs@xxxxxxxxxxx

<URL: http://bugs.freeciv.org/Ticket/Display.html?id=10865 >

Here's an updated patch.  I believe this is ready to be committed.

-jason

? diff.diff
Index: client/citydlg_common.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/citydlg_common.c,v
retrieving revision 1.52
diff -u -r1.52 citydlg_common.c
--- client/citydlg_common.c     16 Dec 2004 18:59:28 -0000      1.52
+++ client/citydlg_common.c     16 Dec 2004 19:30:20 -0000
@@ -173,10 +173,12 @@
                       get_citydlg_canvas_width(),
                       get_citydlg_canvas_height());
 
-  citydlg_known_iterate(pcity, city_x, city_y,
-                       ptile, canvas_x, canvas_y) {
-    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) {
+      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.166
diff -u -r1.166 mapview_common.c
--- client/mapview_common.c     16 Dec 2004 18:59:28 -0000      1.166
+++ client/mapview_common.c     16 Dec 2004 19:30:21 -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;
 }
 
 /****************************************************************************
@@ -1416,11 +1428,12 @@
 /**************************************************************************
   Draw some or all of a tile onto the canvas.
 **************************************************************************/
-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)
 {
   struct drawn_sprite tile_sprs[80];
-  int count = fill_sprite_array(tile_sprs, ptile,
+  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
@@ -1486,16 +1499,18 @@
   canvas_put_rectangle(mapview_canvas.store, COLOR_STD_BLACK,
                       canvas_x, canvas_y, width, height);
 
-  gui_rect_iterate(gui_x0, gui_y0, width,
-                  height + (is_isometric ? (NORMAL_TILE_HEIGHT / 2) : 0),
-                  ptile) {
-    int cx, cy;
-
-    if (tile_get_known(ptile) != TILE_UNKNOWN
-       && tile_to_canvas_pos(&cx, &cy, ptile)) {
-      put_one_tile(mapview_canvas.store, ptile, cx, cy, FALSE);
-    }
-  } gui_rect_iterate_end;
+  mapview_layer_iterate(layer) {
+    gui_rect_iterate(gui_x0, gui_y0, width,
+                    height + (is_isometric ? (NORMAL_TILE_HEIGHT / 2) : 0),
+                    ptile) {
+      int cx, cy;
+
+      if (tile_get_known(ptile) != TILE_UNKNOWN
+         && tile_to_canvas_pos(&cx, &cy, ptile)) {
+       put_one_tile(mapview_canvas.store, layer, ptile, cx, cy, FALSE);
+      }
+    } 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.83
diff -u -r1.83 mapview_common.h
--- client/mapview_common.h     16 Dec 2004 18:59:28 -0000      1.83
+++ client/mapview_common.h     16 Dec 2004 19:30:21 -0000
@@ -179,7 +179,8 @@
 
 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 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.220
diff -u -r1.220 tilespec.c
--- client/tilespec.c   15 Dec 2004 07:58:44 -0000      1.220
+++ client/tilespec.c   16 Dec 2004 19:30:21 -0000
@@ -2447,6 +2447,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)
 {
@@ -2454,7 +2455,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) {
@@ -2463,156 +2465,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;
@@ -2635,7 +2643,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)
 {
@@ -2645,155 +2654,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 (fogstyle == 1 && draw_fog_of_war
-      && ptile && tile_get_known(ptile) == TILE_KNOWN_FOGGED) {
-    /* With fogstyle 1, fog 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 (fogstyle == 1 && draw_fog_of_war
+       && ptile && tile_get_known(ptile) == TILE_KNOWN_FOGGED) {
+      /* With fogstyle 1, fog 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.93
diff -u -r1.93 tilespec.h
--- client/tilespec.h   15 Dec 2004 07:58:44 -0000      1.93
+++ client/tilespec.h   16 Dec 2004 19:30:22 -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);
 

[Prev in Thread] Current Thread [Next in Thread]