Complete.Org: Mailing Lists: Archives: freeciv-dev: February 2005:
[Freeciv-Dev] (PR#12140) use sprites to draw the mapview grid
Home

[Freeciv-Dev] (PR#12140) use sprites to draw the mapview grid

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
Subject: [Freeciv-Dev] (PR#12140) use sprites to draw the mapview grid
From: "Jason Short" <jdorje@xxxxxxxxxxxxxxxxxxxxx>
Date: Sat, 5 Feb 2005 21:57:26 -0800
Reply-to: bugs@xxxxxxxxxxx

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

Here is a preliminary patch to use tileset sprites for drawing of the 
mapview grid.

Apply the patch and drop grid.png into data/isotrident.  Then run the 
game and use isotrident.

There are several reasons why we'd want to use sprites for this:

- Hand-editing can give better results (esp. the use of alpha for the 
grid and hand-tweaking the border graphics).

- Using a sprite makes things more consistent (drawing a line may not be 
the same on all platforms).

- It is possible (eventually) to have inset gridlines via sprites 
(currently this works very poorly in iso-view).

- The border-drawing code is really obnoxious and it would be nice to 
remove it.

Eventually we should use sprites for goto lines and other machine-drawn 
decorations.

-jason

? blend.png
? fog
? fog.c
? fog.png
? foo
? terrain1.png
? data/isotrident/foo.png
? data/isotrident/grid.png
? data/isotrident/grid.xcf
? po/en.po
Index: client/mapview_common.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/mapview_common.c,v
retrieving revision 1.176
diff -u -r1.176 mapview_common.c
--- client/mapview_common.c     5 Feb 2005 19:26:38 -0000       1.176
+++ client/mapview_common.c     6 Feb 2005 05:51:41 -0000
@@ -853,19 +853,14 @@
                     canvas_x, canvas_y,
                     pdrawn[i].data.grid.citymode);
       break;
-    case DRAWN_BG:
-      /*** Background color. ***/
-      if (is_isometric) {
-       canvas_fill_sprite_area(pcanvas, sprites.black_tile, COLOR_STD_BLACK,
-                           canvas_x, canvas_y);
-       if (fog) {
-         canvas_fog_sprite_area(pcanvas, sprites.black_tile,
-                                canvas_x, canvas_y);
-       }
-      } else {
-       canvas_put_rectangle(pcanvas, pdrawn[i].data.bg.color,
-                            canvas_x, canvas_y,
-                            NORMAL_TILE_WIDTH, NORMAL_TILE_HEIGHT);
+    case DRAWN_AREA:
+      /*** A colored sprite area. ***/
+      canvas_fill_sprite_area(pcanvas, pdrawn[i].data.area.mask,
+                             pdrawn[i].data.area.color,
+                             canvas_x, canvas_y);
+      if (fog) {
+       canvas_fog_sprite_area(pcanvas, pdrawn[i].data.area.mask,
+                              canvas_x, canvas_y);
       }
       break;
     }
Index: client/tilespec.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/tilespec.c,v
retrieving revision 1.230
diff -u -r1.230 tilespec.c
--- client/tilespec.c   5 Feb 2005 19:26:38 -0000       1.230
+++ client/tilespec.c   6 Feb 2005 05:51:41 -0000
@@ -1458,6 +1458,34 @@
   SET_SPRITE(tx.airbase,    "tx.airbase");
   SET_SPRITE(tx.fog,        "tx.fog");
 
+  for (i = 0; i < EDGE_COUNT; i++) {
+    char *name[EDGE_COUNT] = {"ns", "ew"};
+    int j;
+
+    my_snprintf(buffer, sizeof(buffer), "grid.main.%s", name[i]);
+    sprites.grid.main[i] = load_sprite(buffer);
+
+    my_snprintf(buffer, sizeof(buffer), "grid.city.%s", name[i]);
+    sprites.grid.city[i] = load_sprite(buffer);
+
+    my_snprintf(buffer, sizeof(buffer), "grid.worked.%s", name[i]);
+    sprites.grid.worked[i] = load_sprite(buffer);
+
+    my_snprintf(buffer, sizeof(buffer), "grid.unavailable.%s", name[i]);
+    sprites.grid.unavailable[i] = load_sprite(buffer);
+
+    my_snprintf(buffer, sizeof(buffer), "grid.selected.%s", name[i]);
+    sprites.grid.selected[i] = load_sprite(buffer);
+
+    my_snprintf(buffer, sizeof(buffer), "grid.coastline.%s", name[i]);
+    sprites.grid.coastline[i] = load_sprite(buffer);
+
+    for (j = 0; j < 2; j++) {
+      my_snprintf(buffer, sizeof(buffer), "grid.borders.%c", name[i][j]);
+      sprites.grid.borders[i][j] = load_sprite(buffer);
+    }
+  }
+
   for (i = 0; i < num_index_cardinal; i++) {
     my_snprintf(buffer, sizeof(buffer), "tx.s_river_%s",
                cardinal_index_str(i));
@@ -1942,9 +1970,10 @@
    sprs->data.grid.citymode = (mode),                                      \
    sprs++)
 
-#define ADD_BG(bg_color)                                                   \
-  (sprs->type = DRAWN_BG,                                                  \
-   sprs->data.bg.color = (bg_color),                                       \
+#define ADD_AREA(area_mask, bg_color)                                      \
+  (sprs->type = DRAWN_AREA,                                                \
+   sprs->data.area.mask = (area_mask),                                     \
+   sprs->data.area.color = (bg_color),                                     \
    sprs++)
 
 /**************************************************************************
@@ -2004,7 +2033,7 @@
        ADD_SPRITE(get_unit_nation_flag_sprite(punit),
                   DRAW_FULL, TRUE, flag_offset_x, flag_offset_y);
       } else {
-       ADD_BG(player_color(unit_owner(punit)));
+       ADD_AREA(sprites.black_tile, player_color(unit_owner(punit)));
       }
     }
   }
@@ -2659,6 +2688,98 @@
 
 
 /****************************************************************************
+  Fill in the grid sprites for the given tile, city, and unit.
+****************************************************************************/
+static int fill_grid_sprite_array(struct drawn_sprite *sprs,
+                                 const struct tile *ptile,
+                                 const struct tile_edge *pedge,
+                                 const struct tile_corner *pcorner,
+                                 const struct unit *punit,
+                                 const struct city *pcity,
+                                 bool citymode)
+{
+  struct drawn_sprite *saved_sprs = sprs;
+
+  if (!sprites.grid.main[0]) {
+#if 0
+    if (ptile && tile_get_known(ptile) != TILE_UNKNOWN) {
+      /* Add grid.  In classic view this is done later. */
+      ADD_GRID(ptile, citymode);
+    }
+#endif
+  } else if (pedge) {
+    bool known[EDGE_COUNT], city[EDGE_COUNT];
+    bool worked[EDGE_COUNT], blocked[EDGE_COUNT];
+    int i;
+
+    for (i = 0; i < 2; i++) {
+      struct tile *tile = pedge->tile[i];
+
+      known[i] = tile && tile_get_known(tile) != TILE_UNKNOWN;
+      city[i] = known[i] && player_in_city_radius(game.player_ptr, tile);
+      worked[i] = blocked[i] = FALSE;
+      if (city[i]) {
+       enum city_tile_type ttype;
+       struct city *dummy;
+
+       get_worker_on_map_position(tile, &ttype, &dummy);
+       switch (ttype) {
+       case C_TILE_EMPTY:
+         break;
+       case C_TILE_WORKER:
+         worked[i] = TRUE;
+         break;
+       case C_TILE_UNAVAILABLE:
+         blocked[i] = TRUE;
+         break;
+       }
+      }
+    }
+
+    if ((pedge->tile[0]
+        && map_deco[pedge->tile[0]->index].hilite == HILITE_CITY)
+       || (pedge->tile[1]
+           && map_deco[pedge->tile[1]->index].hilite == HILITE_CITY)) {
+      ADD_SPRITE_SIMPLE(sprites.grid.selected[pedge->type]);
+    } else if (!draw_terrain && draw_coastline
+              && pedge->tile[0] && pedge->tile[1]
+              && known[0] && known[1]
+              && (is_ocean(pedge->tile[0]->terrain)
+                  ^ is_ocean(pedge->tile[1]->terrain))) {
+      ADD_SPRITE_SIMPLE(sprites.grid.coastline[pedge->type]);
+    } else if (draw_map_grid) {
+      if (blocked[0] || blocked[1]) {
+       ADD_SPRITE_SIMPLE(sprites.grid.unavailable[pedge->type]);
+      } else if (worked[0] || worked[1]) {
+       ADD_SPRITE_SIMPLE(sprites.grid.worked[pedge->type]);
+      } else if (city[0] || city[1]) {
+       ADD_SPRITE_SIMPLE(sprites.grid.city[pedge->type]);
+      } else if (known[0] || known[1]) {
+       ADD_SPRITE_SIMPLE(sprites.grid.main[pedge->type]);
+      }
+    }
+
+    if (draw_borders && game.borders > 0 && known[0] && known[1]) {
+      struct player *owner0 = map_get_owner(pedge->tile[0]);
+      struct player *owner1 = map_get_owner(pedge->tile[1]);
+
+      if (owner0 != owner1) {
+       if (owner0) {
+         ADD_AREA(sprites.grid.borders[pedge->type][0],
+                  player_color(owner0));
+       }
+       if (owner1) {
+         ADD_AREA(sprites.grid.borders[pedge->type][1],
+                  player_color(owner1));
+       }
+      }
+    }
+  }
+
+  return sprs - saved_sprs;
+}
+
+/****************************************************************************
   Fill in the sprite array for the given tile, city, and unit.
 
   ptile, if specified, gives the tile.  If specified the terrain and specials
@@ -2700,19 +2821,19 @@
   switch (layer) {
   case LAYER_BACKGROUND:
     if (ptile && tile_get_known(ptile) == TILE_UNKNOWN) {
-      ADD_BG(COLOR_STD_BLACK);
+      ADD_AREA(sprites.black_tile, COLOR_STD_BLACK);
       return sprs - save_sprs;
     }
 
     /* Set up background color. */
     if (solid_color_behind_units) {
       if (do_draw_unit) {
-       ADD_BG(player_color(unit_owner(punit)));
+       ADD_AREA(sprites.black_tile, player_color(unit_owner(punit)));
       } else if (pcity && draw_cities) {
-       ADD_BG(player_color(city_owner(pcity)));
+       ADD_AREA(sprites.black_tile, player_color(city_owner(pcity)));
       }
     } else if (ptile && !draw_terrain) {
-      ADD_BG(COLOR_STD_BACKGROUND);
+      ADD_AREA(sprites.black_tile, COLOR_STD_BACKGROUND);
     }
     break;
 
@@ -2793,9 +2914,9 @@
     break;
 
   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);
+    if (is_isometric) {
+      sprs += fill_grid_sprite_array(sprs, ptile, pedge, pcorner,
+                                    punit, pcity, citymode);
     }
     break;
 
@@ -2876,9 +2997,9 @@
     break;
 
   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);
+    if (!is_isometric) {
+      sprs += fill_grid_sprite_array(sprs, ptile, pedge, pcorner,
+                                    punit, pcity, citymode);
     }
     break;
 
Index: client/tilespec.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/tilespec.h,v
retrieving revision 1.100
diff -u -r1.100 tilespec.h
--- client/tilespec.h   5 Feb 2005 19:26:38 -0000       1.100
+++ client/tilespec.h   6 Feb 2005 05:51:41 -0000
@@ -30,7 +30,7 @@
  * edge.  The tiles are in unspecified order for the moment. */
 struct tile_edge {
   enum {
-    EDGE_NS, EDGE_EW
+    EDGE_NS, EDGE_EW, EDGE_COUNT
   } type;
   struct tile *tile[2];
 };
@@ -45,7 +45,7 @@
   enum {
     DRAWN_SPRITE,      /* Draw a sprite. */
     DRAWN_GRID,                /* Draw the map grid now. */
-    DRAWN_BG            /* Draw a solid BG. */
+    DRAWN_AREA         /* Draw a sprite mask area in a solid color. */
   } type;
 
   union {
@@ -67,8 +67,9 @@
     } grid;
 
     struct {
+      struct Sprite *mask;
       enum color_std color;
-    } bg;
+    } area;
   } data;
 };
 
@@ -313,6 +314,16 @@
       *darkness[MAX_INDEX_CARDINAL],         /* first unused */
       *river_outlet[4];                /* indexed by enum direction4 */
   } tx;                                /* terrain extra */
+  struct {
+    struct Sprite
+      *main[EDGE_COUNT],
+      *city[EDGE_COUNT],
+      *worked[EDGE_COUNT],
+      *unavailable[EDGE_COUNT],
+      *selected[EDGE_COUNT],
+      *coastline[EDGE_COUNT],
+      *borders[EDGE_COUNT][2];
+  } grid;
 
   struct terrain_drawing_data *terrain[MAX_NUM_TERRAINS];
 };
Index: data/isotrident.tilespec
===================================================================
RCS file: /home/freeciv/CVS/freeciv/data/isotrident.tilespec,v
retrieving revision 1.26
diff -u -r1.26 isotrident.tilespec
--- data/isotrident.tilespec    3 Feb 2005 19:28:41 -0000       1.26
+++ data/isotrident.tilespec    6 Feb 2005 05:51:41 -0000
@@ -54,6 +54,7 @@
   "isotrident/terrain1.spec",
   "isotrident/terrain2.spec",
   "isotrident/tiles.spec",
+  "isotrident/grid.spec",
   "misc/small.spec",
   "trident/units.spec",
   "isotrident/unitextras.spec",
Index: data/isotrident/grid.spec
===================================================================
RCS file: data/isotrident/grid.spec
diff -N data/isotrident/grid.spec
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ data/isotrident/grid.spec   6 Feb 2005 05:51:41 -0000
@@ -0,0 +1,42 @@
+
+[spec]
+
+; Format and options of this spec file:
+options = "+spec3"
+
+[info]
+
+artists = "
+    Jason Dorje Short <jdorje@xxxxxxxxxxx>
+"
+
+[file]
+gfx = "isotrident/grid"
+
+[grid_main]
+
+x_top_left = 1
+y_top_left = 1
+dx = 64
+dy = 32
+pixel_border = 1
+
+tiles = { "row", "column", "tag"
+  0, 0, "grid.main.ew"
+  1, 0, "grid.main.ns"
+  0, 1, "grid.city.ew"
+  1, 1, "grid.city.ns"
+  0, 2, "grid.worked.ew"
+  1, 2, "grid.worked.ns"
+  0, 3, "grid.unavailable.ew"
+  1, 3, "grid.unavailable.ns"
+  0, 4, "grid.selected.ew"
+  1, 4, "grid.selected.ns"
+  0, 5, "grid.coastline.ew"
+  1, 5, "grid.coastline.ns"
+
+  2, 0, "grid.borders.s"
+  2, 1, "grid.borders.n"
+  2, 2, "grid.borders.e"
+  2, 3, "grid.borders.w"
+}

PNG image


[Prev in Thread] Current Thread [Next in Thread]
  • [Freeciv-Dev] (PR#12140) use sprites to draw the mapview grid, Jason Short <=