Complete.Org: Mailing Lists: Archives: freeciv-dev: September 2004:
[Freeciv-Dev] (PR#10135) extension of drawn_sprite
Home

[Freeciv-Dev] (PR#10135) extension of drawn_sprite

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
To: undisclosed-recipients: ;
Subject: [Freeciv-Dev] (PR#10135) extension of drawn_sprite
From: "Jason Short" <jdorje@xxxxxxxxxxxxxxxxxxxxx>
Date: Wed, 15 Sep 2004 16:13:57 -0700
Reply-to: rt@xxxxxxxxxxx

<URL: http://rt.freeciv.org/Ticket/Display.html?id=10135 >

This patch extends drawn_sprite.

1.  The bg_color option for drawing tiles and units is added to it.
2.  fill_xxx_sprite_array have the solid_bg and bg_color parameters removed.
3.  All mapview functions to place drawn sprite lists now use 
put_drawn_sprites().

The advantage of this is that it becomes simple for the mapview to add 
new drawing functions like put_city or put_terrain.  All that's needed 
is to call a tilespec function to get the sprite list, then call 
put_drawn_sprites to draw them.

jason



? drawn_sprites.diff
? ftwl.diff
? settler_recursion_crash
? client/tilespec.diff
Index: client/mapview_common.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/mapview_common.c,v
retrieving revision 1.145
diff -u -r1.145 mapview_common.c
--- client/mapview_common.c     15 Sep 2004 19:49:09 -0000      1.145
+++ client/mapview_common.c     15 Sep 2004 23:09:09 -0000
@@ -755,34 +755,87 @@
 }
 
 /**************************************************************************
-  Draw the given unit onto the canvas store at the given location.
+  Draw an array of drawn sprites onto the canvas.
 **************************************************************************/
-void put_unit(struct unit *punit,
-             struct canvas *pcanvas, int canvas_x, int canvas_y)
+static void put_drawn_sprites(struct canvas *pcanvas,
+                             int canvas_x, int canvas_y,
+                             int count, struct drawn_sprite *pdrawn,
+                             bool fog)
 {
-  struct drawn_sprite drawn_sprites[40];
-  bool solid_bg;
-  int count = fill_unit_sprite_array(drawn_sprites, punit, &solid_bg,
-                                    FALSE, TRUE);
   int i;
 
-  if (!is_isometric && solid_bg) {
-    canvas_put_rectangle(pcanvas, player_color(unit_owner(punit)),
-                        canvas_x, canvas_y,
-                        UNIT_TILE_WIDTH, UNIT_TILE_HEIGHT);
-  }
-
   for (i = 0; i < count; i++) {
-    if (drawn_sprites[i].sprite) {
-      int ox = drawn_sprites[i].offset_x, oy = drawn_sprites[i].offset_y;
+    int ox, oy, dx, dy;
 
-      /* units are never fogged */
-      canvas_put_sprite_full(pcanvas, canvas_x + ox, canvas_y + oy,
-                            drawn_sprites[i].sprite);
+    switch (pdrawn[i].type) {
+    case DRAWN_SPRITE:
+      if (!pdrawn[i].data.sprite.sprite) {
+       /* This can happen, although it should probably be avoided. */
+       break;
+      }
+      ox = pdrawn[i].data.sprite.offset_x;
+      oy = pdrawn[i].data.sprite.offset_y;
+      if (pdrawn[i].data.sprite.style == DRAW_FULL) {
+       dx = UNIT_TILE_WIDTH - NORMAL_TILE_WIDTH;
+       dy = UNIT_TILE_HEIGHT - NORMAL_TILE_HEIGHT;
+      } else {
+       dx = dy = 0;
+      }
+      if (fog && pdrawn[i].data.sprite.foggable) {
+       canvas_put_sprite_fogged(pcanvas,
+                                canvas_x + ox - dx, canvas_y + oy - dy,
+                                pdrawn[i].data.sprite.sprite,
+                                TRUE,
+                                canvas_x, canvas_y);
+      } else {
+       /* We avoid calling canvas_put_sprite_fogged, even though it
+        * should be a valid thing to do, because gui-gtk-2.0 doesn't have
+        * a full implementation. */
+       canvas_put_sprite_full(pcanvas,
+                              canvas_x + ox - dx, canvas_y + oy - dy,
+                              pdrawn[i].data.sprite.sprite);
+      }
+      break;
+    case DRAWN_GRID:
+      /*** Grid (map grid, borders, coastline, etc.) ***/
+      tile_draw_grid(pcanvas,
+                    pdrawn[i].data.grid.map_x, pdrawn[i].data.grid.map_y,
+                    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);
+      }
+      break;
     }
   }
 }
 
+/**************************************************************************
+  Draw the given unit onto the canvas store at the given location.
+**************************************************************************/
+void put_unit(struct unit *punit,
+             struct canvas *pcanvas, int canvas_x, int canvas_y)
+{
+  struct drawn_sprite drawn_sprites[40];
+  int count = fill_unit_sprite_array(drawn_sprites, punit, FALSE, TRUE);
+
+  canvas_y += (UNIT_TILE_HEIGHT - NORMAL_TILE_HEIGHT);
+  put_drawn_sprites(pcanvas, canvas_x, canvas_y,
+                   count, drawn_sprites, FALSE);
+}
+
 /****************************************************************************
   Draw food, shield, and trade output values on the tile.
 
@@ -1175,76 +1228,19 @@
 }
 
 /**************************************************************************
-  Draw an array of drawn sprites onto the canvas.
-**************************************************************************/
-static void put_drawn_sprites(struct canvas *pcanvas,
-                             int canvas_x, int canvas_y,
-                             int count, struct drawn_sprite *pdrawn,
-                             bool fog, int map_x, int map_y, bool citymode)
-{
-  int i;
-
-  for (i = 0; i < count; i++) {
-    int ox = pdrawn[i].offset_x, oy = pdrawn[i].offset_y, dx, dy;
-
-    switch (pdrawn[i].type) {
-    case DRAWN_SPRITE:
-      if (pdrawn[i].style == DRAW_FULL) {
-       dx = UNIT_TILE_WIDTH - NORMAL_TILE_WIDTH;
-       dy = UNIT_TILE_HEIGHT - NORMAL_TILE_HEIGHT;
-      } else {
-       dx = dy = 0;
-      }
-      canvas_put_sprite_fogged(pcanvas,
-                              canvas_x + ox - dx, canvas_y + oy - dy,
-                              pdrawn[i].sprite,
-                              fog && pdrawn[i].foggable,
-                              canvas_x, canvas_y);
-      break;
-    case DRAWN_GRID:
-      /*** Grid (map grid, borders, coastline, etc.) ***/
-      tile_draw_grid(pcanvas, map_x, map_y, canvas_x, canvas_y, citymode);
-      break;
-    }
-  }
-}
-
-/**************************************************************************
   Draw the given map tile at the given canvas position in non-isometric
   view.
 **************************************************************************/
 void put_one_tile(struct canvas *pcanvas, int map_x, int map_y,
                  int canvas_x, int canvas_y, bool citymode)
 {
-  struct drawn_sprite tile_sprs[80];
-  bool solid_bg;
-  enum color_std bg_color;
-  bool is_real = normalize_map_pos(&map_x, &map_y);
-
-  if (is_real && tile_get_known(map_x, map_y) != TILE_UNKNOWN) {
-    int count = fill_tile_sprite_array(tile_sprs, &solid_bg, &bg_color,
-                                      map_x, map_y, citymode);
-    int i = 0;
-
-    if (solid_bg) {
-      canvas_put_rectangle(pcanvas, bg_color, canvas_x, canvas_y,
-                          NORMAL_TILE_WIDTH, NORMAL_TILE_HEIGHT);
-    }
-
-    for (i = 0; i < count; i++) {
-      switch (tile_sprs[i].type) {
-      case DRAWN_SPRITE:
-       canvas_put_sprite_full(pcanvas,
-                              canvas_x + tile_sprs[i].offset_x,
-                              canvas_y + tile_sprs[i].offset_y,
-                              tile_sprs[i].sprite);
-       break;
-      case DRAWN_GRID:
-       /*** Grid (map grid, borders, coastline, etc.) ***/
-       tile_draw_grid(pcanvas, map_x, map_y, canvas_x, canvas_y, citymode);
-       break;
-      }
-    }
+  if (normalize_map_pos(&map_x, &map_y)
+      && tile_get_known(map_x, map_y) != TILE_UNKNOWN) {
+    struct drawn_sprite tile_sprs[80];
+    int count = fill_tile_sprite_array(tile_sprs, map_x, map_y, citymode);
+
+    put_drawn_sprites(pcanvas, canvas_x, canvas_y,
+                     count, tile_sprs, FALSE);
   } else {
     /* tile is unknown */
     canvas_put_rectangle(pcanvas, COLOR_STD_BLACK,
@@ -1389,11 +1385,9 @@
 {
   struct drawn_sprite tile_sprs[80];
   int count;
-  bool solid_bg, fog;
-  enum color_std bg_color;
+  bool fog;
 
-  count = fill_tile_sprite_array(tile_sprs, &solid_bg, &bg_color,
-                                map_x, map_y, citymode);
+  count = fill_tile_sprite_array(tile_sprs, map_x, map_y, citymode);
 
   if (count == -1) { /* tile is unknown */
     canvas_fill_sprite_area(pcanvas, sprites.black_tile, COLOR_STD_BLACK,
@@ -1409,18 +1403,8 @@
 
   fog = tile_get_known(map_x, map_y) == TILE_KNOWN_FOGGED && draw_fog_of_war;
 
-  if (solid_bg) {
-    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);
-    }
-  }
-
   /*** Draw terrain and specials ***/
-  put_drawn_sprites(pcanvas, canvas_x, canvas_y,
-                   count, tile_sprs, fog, map_x, map_y, citymode);
+  put_drawn_sprites(pcanvas, canvas_x, canvas_y, count, tile_sprs, fog);
 }
 
 /**************************************************************************
Index: client/tilespec.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/tilespec.c,v
retrieving revision 1.196
diff -u -r1.196 tilespec.c
--- client/tilespec.c   25 Aug 2004 18:24:18 -0000      1.196
+++ client/tilespec.c   15 Sep 2004 23:09:10 -0000
@@ -1865,17 +1865,29 @@
 }
 
 #define ADD_SPRITE(s, draw_style, draw_fog, x_offset, y_offset)        \
-  (assert(s != NULL),                     \
-   sprs->type = DRAWN_SPRITE,             \
-   sprs->style = draw_style,              \
-   sprs->sprite = s,                      \
-   sprs->foggable = draw_fog,             \
-   sprs->offset_x = x_offset,             \
-   sprs->offset_y = y_offset,             \
+  (assert(s != NULL),                                          \
+   sprs->type = DRAWN_SPRITE,                                  \
+   sprs->data.sprite.style = draw_style,                       \
+   sprs->data.sprite.sprite = s,                               \
+   sprs->data.sprite.foggable = draw_fog,                      \
+   sprs->data.sprite.offset_x = x_offset,                      \
+   sprs->data.sprite.offset_y = y_offset,                      \
    sprs++)
 #define ADD_SPRITE_SIMPLE(s) ADD_SPRITE(s, DRAW_NORMAL, TRUE, 0, 0)
 #define ADD_SPRITE_FULL(s) ADD_SPRITE(s, DRAW_FULL, TRUE, 0, 0)
 
+#define ADD_GRID(x, y, mode)                                               \
+  (sprs->type = DRAWN_GRID,                                                \
+   sprs->data.grid.map_x = (x),                                                
    \
+   sprs->data.grid.map_y = (y),                                                
    \
+   sprs->data.grid.citymode = (mode),                                      \
+   sprs++)
+
+#define ADD_BG(bg_color)                                                   \
+  (sprs->type = DRAWN_BG,                                                  \
+   sprs->data.bg.color = (bg_color),                                       \
+   sprs++)
+
 /**************************************************************************
   Assemble some data that is used in building the tile sprite arrays.
     (map_x, map_y) : the (normalized) map position
@@ -1917,11 +1929,10 @@
   Fill in the sprite array for the unit
 ***********************************************************************/
 int fill_unit_sprite_array(struct drawn_sprite *sprs, struct unit *punit,
-                          bool *solid_bg, bool stack, bool backdrop)
+                          bool stack, bool backdrop)
 {
   struct drawn_sprite *save_sprs = sprs;
   int ihp;
-  *solid_bg = FALSE;
 
   if (is_isometric) {
     if (backdrop) {
@@ -1934,7 +1945,7 @@
        ADD_SPRITE(get_unit_nation_flag_sprite(punit),
                   DRAW_FULL, TRUE, flag_offset_x, flag_offset_y);
       } else {
-       *solid_bg = TRUE;
+       ADD_BG(player_color(unit_owner(punit)));
       }
     }
   }
@@ -2581,7 +2592,6 @@
  5) huts
 ***********************************************************************/
 int fill_tile_sprite_array(struct drawn_sprite *sprs,
-                          bool *solid_bg, enum color_std *bg_color,
                           int map_x, int map_y, bool citymode)
 {
   Terrain_type_id ttype, ttype_near[8];
@@ -2595,24 +2605,19 @@
   bool unit_only = FALSE, city_only = FALSE;
 
   if (tile_get_known(map_x, map_y) == TILE_UNKNOWN) {
-    *solid_bg = TRUE;
-    *bg_color = COLOR_STD_BLACK;
-    return 0;
+    ADD_BG(COLOR_STD_BLACK);
+    return sprs - save_sprs;
   }
 
   /* Set up background color. */
-  *solid_bg = FALSE;
   if (solid_color_behind_units) {
     if (punit && (draw_units || (draw_focus_unit && pfocus == punit))) {
-      *solid_bg = unit_only = TRUE;
-      *bg_color = player_color(unit_owner(punit));
+      ADD_BG(player_color(unit_owner(punit)));
     } else if (pcity && draw_cities) {
-      *solid_bg = city_only = TRUE;
-      *bg_color = player_color(city_owner(pcity));
+      ADD_BG(player_color(city_owner(pcity)));
     }
   } else if (!draw_terrain) {
-    *solid_bg = TRUE;
-    *bg_color = COLOR_STD_BACKGROUND;
+    ADD_BG(COLOR_STD_BACKGROUND);
   }
 
   build_tile_data(map_x, map_y,
@@ -2677,8 +2682,7 @@
 
   if (is_isometric) {
     /* Add grid.  In classic view this is done later. */
-    sprs->type = DRAWN_GRID;
-    sprs++;
+    ADD_GRID(map_x, map_y, citymode);
   }
 
   /* City.  Some city sprites are drawn later. */
@@ -2733,9 +2737,8 @@
       && (draw_units || (punit == pfocus && draw_focus_unit))) {
     bool stacked = (unit_list_size(&map_get_tile(map_x, map_y)->units) > 1);
     bool backdrop = !pcity && !unit_only;
-    bool dummy;
 
-    sprs += fill_unit_sprite_array(sprs, punit, &dummy, stacked, backdrop);
+    sprs += fill_unit_sprite_array(sprs, punit, stacked, backdrop);
   }
 
   if (!unit_only && !city_only) {
@@ -2749,8 +2752,7 @@
 
   if (!is_isometric) {
     /* Add grid.  In iso-view this is done earlier. */
-    sprs->type = DRAWN_GRID;
-    sprs++;
+    ADD_GRID(map_x, map_y, citymode);
   }
 
   return sprs - save_sprs;
Index: client/tilespec.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/tilespec.h,v
retrieving revision 1.85
diff -u -r1.85 tilespec.h
--- client/tilespec.h   3 Sep 2004 04:22:36 -0000       1.85
+++ client/tilespec.h   15 Sep 2004 23:09:10 -0000
@@ -29,20 +29,32 @@
 struct drawn_sprite {
   enum {
     DRAWN_SPRITE,      /* Draw a sprite. */
-    DRAWN_GRID         /* Draw the map grid now. */
+    DRAWN_GRID,                /* Draw the map grid now. */
+    DRAWN_BG            /* Draw a solid BG. */
   } type;
 
-  enum {
-    /* Only applicable in iso-view.  "Full" sprites overlap into the top
-     * half-tile of UNIT_TILE_HEIGHT. */
-    DRAW_NORMAL,
-    DRAW_FULL
-  } style;
-
-  /* These files only apply for DRAWN_SPRITE. */
-  bool foggable;       /* Set to FALSE for sprites that are never fogged. */
-  struct Sprite *sprite;
-  int offset_x, offset_y;      /* offset from tile origin */
+  union {
+    struct {
+      enum {
+       /* Only applicable in iso-view.  "Full" sprites overlap into the top
+        * half-tile of UNIT_TILE_HEIGHT. */
+       DRAW_NORMAL,
+       DRAW_FULL
+      } style;
+      bool foggable;   /* Set to FALSE for sprites that are never fogged. */
+      struct Sprite *sprite;
+      int offset_x, offset_y;  /* offset from tile origin */
+    } sprite;
+
+    struct {
+      int map_x, map_y;
+      bool citymode;
+    } grid;
+
+    struct {
+      enum color_std color;
+    } bg;
+  } data;
 };
 
 const char **get_tileset_list(void);
@@ -68,10 +80,9 @@
 /* Gfx support */
 
 int fill_tile_sprite_array(struct drawn_sprite *sprs,
-                          bool *solid_bg, enum color_std *bg_color,
                           int map_x, int map_y, bool citymode);
 int fill_unit_sprite_array(struct drawn_sprite *sprs, struct unit *punit,
-                          bool *solid_bg, bool stack, bool backdrop);
+                          bool stack, bool backdrop);
 
 enum color_std player_color(struct player *pplayer);
 enum color_std overview_tile_color(int x, int y);

[Prev in Thread] Current Thread [Next in Thread]
  • [Freeciv-Dev] (PR#10135) extension of drawn_sprite, Jason Short <=