Complete.Org: Mailing Lists: Archives: freeciv-dev: March 2004:
[Freeciv-Dev] (PR#7612) crop_sprite with a mask
Home

[Freeciv-Dev] (PR#7612) crop_sprite with a mask

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
To: undisclosed-recipients: ;
Subject: [Freeciv-Dev] (PR#7612) crop_sprite with a mask
From: "Jason Short" <jdorje@xxxxxxxxxxxxxxxxxxxxx>
Date: Mon, 22 Mar 2004 14:45:54 -0800
Reply-to: rt@xxxxxxxxxxx

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

> [jdorje - Sat Mar 06 02:59:50 2004]:
> 
> This patch does two things:
> 
> - Crop_sprite takes an additional set of parameters.  This allows the 
> sprite to be cropped with an extra mask.  In effect the new mask becomes 
> the intersection of the old and new mask.
> 
> - Blended (aka dithered) tiles are drawn differently.  Currently we take 
> the terrain we're going to blend with, and draw its sprite using a 
> clipping mask.  So we use 2 masks in the draw stage.  Some GUIs (win32, 
> sdl) have problems with this.  With the new method, when the tileset is 
> loaded the blending sprites are cropped out into separate sprites: four 
> for each terrain.  Then later instead of having special dither code in 
> the GUI we need only add these sprites to the list of drawn_sprites.

Here's a new version with James's win32 fix.  Hopefully this will be the
last version.

Raimar: should this be split into two patches?  One to change
crop_sprite, and another to change the dither code.

jason

Index: client/tilespec.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/tilespec.c,v
retrieving revision 1.151
diff -u -r1.151 tilespec.c
--- client/tilespec.c   22 Mar 2004 19:34:03 -0000      1.151
+++ client/tilespec.c   22 Mar 2004 22:30:43 -0000
@@ -853,7 +853,6 @@
   if (is_isometric) {
     SET_SPRITE(black_tile, "t.black_tile");
     SET_SPRITE(dither_tile, "t.dither_tile");
-    SET_SPRITE(coast_color, "t.coast_color");
   }
 
   /* Load the citizen sprite graphics. */
@@ -1067,7 +1066,8 @@
 
     for (i = 0; i < 4; i++) {
       sprites.tx.darkness[i] = crop_sprite(darkness, offsets[i][0],
-                                          offsets[i][1], W / 2, H / 2);
+                                          offsets[i][1], W / 2, H / 2,
+                                          NULL, 0, 0);
     }
   }
 
@@ -1232,6 +1232,9 @@
                                                    tt->terrain_name);
        }
       }
+      my_snprintf(buffer1, sizeof(buffer1), "t.%s1", draw->name);
+      draw->base = lookup_sprite_tag_alt(buffer1, "", FALSE, "tile_type",
+                                        tt->terrain_name);
       break;
     }
 
@@ -1240,6 +1243,22 @@
     }
   }
 
+  if (draw->is_blended && is_isometric) {
+    /* Set up blending sprites. This only works in iso-view! */
+    const int W = NORMAL_TILE_WIDTH, H = NORMAL_TILE_HEIGHT;
+    const int offsets[4][2] = {
+      {W / 2, 0}, {0, H / 2}, {W / 2, H / 2}, {0, 0}
+    };
+    enum direction4 dir;
+
+    for (dir = 0; dir < 4; dir++) {
+      draw->blend[dir] = crop_sprite(draw->base,
+                                    offsets[dir][0], offsets[dir][1],
+                                    W / 2, H / 2,
+                                    sprites.dither_tile, 0, 0);
+    }
+  }
+
   for (i=0; i<2; i++) {
     char *name = (i != 0) ? tt->special_2_name : tt->special_1_name;
     if (name[0] != '\0') {
@@ -1593,25 +1612,6 @@
   return sprs - save_sprs;
 }
 
-/**********************************************************************
-Only used for isometric view.
-***********************************************************************/
-static struct Sprite *get_dither(int ttype, int ttype_other)
-{
-  if (ttype_other == T_UNKNOWN)
-    return NULL;
-
-  if (!sprites.terrain[ttype]->is_blended) {
-    return NULL;
-  }
-
-  if (is_ocean(ttype_other)) {
-    return sprites.coast_color;
-  }
-
-  return sprites.terrain[ttype_other]->base;
-}
-
 /**************************************************************************
   Add any corner road sprites to the sprite array.
 **************************************************************************/
@@ -1900,20 +1900,59 @@
 }
 
 /****************************************************************************
+  Fill in the sprite array for blended terrain.
+****************************************************************************/
+static int fill_blending_sprite_array(struct drawn_sprite *sprs,
+                                     int map_x, int map_y,
+                                     enum tile_terrain_type *ttype_near)
+{
+  struct drawn_sprite *saved_sprs = sprs;
+
+  if (is_isometric) {
+    enum tile_terrain_type ttype = map_get_terrain(map_x, map_y);
+    enum direction4 dir;
+    const int W = NORMAL_TILE_WIDTH, H = NORMAL_TILE_HEIGHT;
+    const int offsets[4][2] = {
+      {W/2, 0}, {0, H / 2}, {W / 2, H / 2}, {0, 0}
+    };
+
+    /*
+     * 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.
+     */
+    for (dir = 0; dir < 4; dir++) {
+      int x1, y1;
+      enum tile_terrain_type other = ttype_near[DIR4_TO_DIR8[dir]];
+
+      if (!MAPSTEP(x1, y1, map_x, map_y, DIR4_TO_DIR8[dir])
+         || tile_get_known(x1, y1) == TILE_UNKNOWN
+         || other == ttype) {
+       continue;
+      }
+
+      ADD_SPRITE(sprites.terrain[other]->blend[dir],
+                offsets[dir][0], offsets[dir][1]);
+    }
+  }
+
+  return sprs - saved_sprs;
+}
+
+/****************************************************************************
   Add sprites for the base terrain to the sprite list.  This doesn't
   include specials or rivers.
 ****************************************************************************/
 static int fill_terrain_sprite_array(struct drawn_sprite *sprs,
-                                    struct tile *ptile,
-                                    enum tile_terrain_type *ttype_near,
-                                    int *dither_count)
+                                    int map_x, int map_y,
+                                    enum tile_terrain_type *ttype_near)
 {
   struct drawn_sprite *saved_sprs = sprs;
   struct Sprite *sprite;
+  struct tile *ptile = map_get_tile(map_x, map_y);
   enum tile_terrain_type ttype = ptile->terrain;
 
   if (!draw_terrain) {
-    *dither_count = 0;
     return 0;
   }
 
@@ -1926,7 +1965,10 @@
   if (sprites.terrain[ttype]->match_type == 0
       || sprites.terrain[ttype]->is_layered) {
     ADD_SPRITE_SIMPLE(sprites.terrain[ttype]->base);
-    *dither_count = 1;
+  }
+
+  if (sprites.terrain[ttype]->is_layered) {
+    sprs += fill_blending_sprite_array(sprs, map_x, map_y, ttype_near);
   }
 
   if (sprites.terrain[ttype]->match_type != 0) {
@@ -1941,9 +1983,6 @@
                          MATCH(DIR8_EAST), MATCH(DIR8_WEST));
 
       ADD_SPRITE_SIMPLE(sprites.terrain[ttype]->match[tileno]);
-      if (!sprites.terrain[ttype]->is_layered) {
-       *dither_count = 1;
-      }
     } else if (sprites.terrain[ttype]->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
@@ -1975,18 +2014,6 @@
 
        ADD_SPRITE(sprites.terrain[ttype]->cells[array_index][i], x, y);
       }
-
-      /* Short-cut past dithering if all adjacent tiles are the same. */
-      if (!sprites.terrain[ttype]->is_layered) {
-       if (ttype_near[DIR8_NORTH] == ttype
-           && ttype_near[DIR8_SOUTH] == ttype
-           && ttype_near[DIR8_EAST] == ttype
-           && ttype_near[DIR8_WEST] == ttype) {
-         *dither_count = 0;
-       } else {
-         *dither_count = 4;
-       }
-      }
     }
 #undef MATCH
   }
@@ -2010,6 +2037,10 @@
     }
   }
 
+  if (!sprites.terrain[ttype]->is_layered) {
+    sprs += fill_blending_sprite_array(sprs, map_x, map_y, ttype_near);
+  }
+
   return sprs - saved_sprs;
 }
 
@@ -2029,7 +2060,6 @@
  5) huts
 ***********************************************************************/
 int fill_tile_sprite_array_iso(struct drawn_sprite *sprs,
-                              struct Sprite **dither, int *dither_count,
                               int x, int y, bool citymode, bool *solid_bg)
 {
   enum tile_terrain_type ttype, ttype_near[8];
@@ -2040,14 +2070,13 @@
   struct drawn_sprite *save_sprs = sprs;
 
   *solid_bg = FALSE;
-  *dither_count = 0;
 
   if (tile_get_known(x, y) == TILE_UNKNOWN)
     return -1;
 
   build_tile_data(x, y, &ttype, &tspecial, ttype_near, tspecial_near);
 
-  sprs += fill_terrain_sprite_array(sprs, ptile, ttype_near, dither_count);
+  sprs += fill_terrain_sprite_array(sprs, x, y, ttype_near);
 
   if (is_ocean(ttype) && draw_terrain) {
     for (dir = 0; dir < 4; dir++) {
@@ -2125,23 +2154,6 @@
     }
 #endif
   }
-  
-  if (dither) {
-    /*
-     * 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.
-     */
-    for (dir = 0; dir < 4; dir++) {
-      int x1, y1, other;
-
-      if (MAPSTEP(x1, y1, x, y, DIR4_TO_DIR8[dir]))
-        other = (tile_get_known(x1, y1) != TILE_UNKNOWN) ? 
ttype_near[DIR4_TO_DIR8[dir]]:T_UNKNOWN;
-      else
-        other = ttype_near[dir];
-      dither[dir] = get_dither(ttype, other);
-    }
-  }
 
   return sprs - save_sprs;
 }
@@ -2169,7 +2181,7 @@
 {
   enum tile_terrain_type ttype, ttype_near[8];
   enum tile_special_type tspecial, tspecial_near[8];
-  int dir, tileno, dither_count;
+  int dir, tileno;
   struct tile *ptile;
   struct city *pcity;
   struct unit *pfocus;
@@ -2210,7 +2222,7 @@
   build_tile_data(abs_x0, abs_y0, 
                  &ttype, &tspecial, ttype_near, tspecial_near);
 
-  sprs += fill_terrain_sprite_array(sprs, ptile, ttype_near, &dither_count);
+  sprs += fill_terrain_sprite_array(sprs, abs_x0, abs_y0, ttype_near);
 
   if (!draw_terrain) {
     *solid_bg = TRUE;
@@ -2634,7 +2646,8 @@
     assert(ss->ref_count == 0);
     ensure_big_sprite(ss->sf);
     ss->sprite =
-       crop_sprite(ss->sf->big_sprite, ss->x, ss->y, ss->width, ss->height);
+      crop_sprite(ss->sf->big_sprite, ss->x, ss->y, ss->width, ss->height,
+                 NULL, -1, -1);
   }
 
   /* Track the reference count so we know when to free the sprite. */
Index: client/tilespec.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/tilespec.h,v
retrieving revision 1.56
diff -u -r1.56 tilespec.h
--- client/tilespec.h   8 Mar 2004 02:15:58 -0000       1.56
+++ client/tilespec.h   22 Mar 2004 22:30:43 -0000
@@ -53,7 +53,6 @@
 /* Gfx support */
 
 int fill_tile_sprite_array_iso(struct drawn_sprite *sprs,
-                              struct Sprite **dither, int *dither_count,
                               int x, int y, bool citymode, bool *solid_bg);
 int fill_tile_sprite_array(struct drawn_sprite *sprs, int abs_x0, int abs_y0,
                           bool citymode, bool *solid_bg,
@@ -111,6 +110,7 @@
   struct Sprite *base;
   struct Sprite *match[NUM_DIRECTION_NSEW];
   struct Sprite *cells[8][4]; /* 4 = up down left right */
+  struct Sprite *blend[4]; /* indexed by a direction4 */
   struct Sprite *special[2];
   struct Sprite *mine;
 };
@@ -124,8 +124,7 @@
     *right_arrow,
 
     *black_tile,      /* only used for isometric view */
-    *dither_tile,     /* only used for isometric view */
-    *coast_color;     /* only used for isometric view */
+    *dither_tile;     /* only used for isometric view */
 
   struct {
     /* Each citizen type has up to MAX_NUM_CITIZEN_SPRITES different
Index: client/gui-gtk/graphics.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-gtk/graphics.c,v
retrieving revision 1.52
diff -u -r1.52 graphics.c
--- client/gui-gtk/graphics.c   24 Feb 2004 05:20:25 -0000      1.52
+++ client/gui-gtk/graphics.c   22 Mar 2004 22:30:43 -0000
@@ -167,9 +167,11 @@
 ***************************************************************************/
 struct Sprite *crop_sprite(struct Sprite *source,
                           int x, int y,
-                          int width, int height)
+                          int width, int height,
+                          struct Sprite *mask,
+                          int mask_offset_x, int mask_offset_y)
 {
-  GdkPixmap *mypixmap, *mask = NULL;
+  GdkPixmap *mypixmap, *mymask = NULL;
 
   mypixmap = gdk_pixmap_new(root_window, width, height, -1);
 
@@ -177,14 +179,30 @@
                  width, height);
 
   if (source->has_mask) {
-    mask = gdk_pixmap_new(mask_bitmap, width, height, 1);
-    gdk_draw_rectangle(mask, mask_bg_gc, TRUE, 0, 0, -1, -1 );
+    mymask = gdk_pixmap_new(mask_bitmap, width, height, 1);
+    gdk_draw_rectangle(mymask, mask_bg_gc, TRUE, 0, 0, -1, -1 );
 
-    gdk_draw_pixmap(mask, mask_fg_gc, source->mask,
+    gdk_draw_pixmap(mymask, mask_fg_gc, source->mask,
                    x, y, 0, 0, width, height);
   }
 
-  return ctor_sprite_mask(mypixmap, mask, width, height);
+  if (mask) {
+    if (mymask) {
+      gdk_gc_set_function(mask_fg_gc, GDK_AND);
+      gdk_draw_pixmap(mymask, mask_fg_gc, mask->mask,
+                     x - mask_offset_x, y - mask_offset_y,
+                     0, 0, width, height);
+      gdk_gc_set_function(mask_fg_gc, GDK_OR);
+    } else {
+      mymask = gdk_pixmap_new(NULL, width, height, 1);
+      gdk_draw_rectangle(mymask, mask_bg_gc, TRUE, 0, 0, -1, -1);
+
+      gdk_draw_pixmap(mymask, mask_fg_gc, source->mask,
+                       x, y, 0, 0, width, height);
+    }
+  }
+
+  return ctor_sprite_mask(mypixmap, mymask, width, height);
 }
 
 /****************************************************************************
@@ -629,5 +647,5 @@
 
   sprite_get_bounding_box(s, &x1, &y1, &x2, &y2);
 
-  return crop_sprite(s, x1, y1, x2 - x1 + 1, y2 - y1 + 1);
+  return crop_sprite(s, x1, y1, x2 - x1 + 1, y2 - y1 + 1, NULL, -1, -1);
 }
Index: client/gui-gtk/mapview.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-gtk/mapview.c,v
retrieving revision 1.208
diff -u -r1.208 mapview.c
--- client/gui-gtk/mapview.c    15 Mar 2004 05:35:28 -0000      1.208
+++ client/gui-gtk/mapview.c    22 Mar 2004 22:30:43 -0000
@@ -993,81 +993,6 @@
 }
 
 /**************************************************************************
-Blend the tile with neighboring tiles.
-Only used for isometric view.
-**************************************************************************/
-static void dither_tile(GdkDrawable *pixmap, struct Sprite **dither,
-                       int canvas_x, int canvas_y,
-                       int offset_x, int offset_y,
-                       int width, int height, bool fog)
-{
-  if (!width || !height)
-    return;
-
-  gdk_gc_set_clip_mask(civ_gc, sprites.dither_tile->mask);
-  gdk_gc_set_clip_origin(civ_gc, canvas_x, canvas_y);
-  assert(offset_x == 0 || offset_x == NORMAL_TILE_WIDTH/2);
-  assert(offset_y == 0 || offset_y == NORMAL_TILE_HEIGHT/2);
-  assert(width == NORMAL_TILE_WIDTH || width == NORMAL_TILE_WIDTH/2);
-  assert(height == NORMAL_TILE_HEIGHT || height == NORMAL_TILE_HEIGHT/2);
-
-  /* north */
-  if (dither[0]
-      && (offset_x != 0 || width == NORMAL_TILE_WIDTH)
-      && (offset_y == 0)) {
-    gdk_draw_pixmap(pixmap, civ_gc, dither[0]->pixmap,
-                   NORMAL_TILE_WIDTH/2, 0,
-                   canvas_x + NORMAL_TILE_WIDTH/2, canvas_y,
-                   NORMAL_TILE_WIDTH/2, NORMAL_TILE_HEIGHT/2);
-  }
-
-  /* south */
-  if (dither[1] && offset_x == 0
-      && (offset_y == NORMAL_TILE_HEIGHT/2 || height == NORMAL_TILE_HEIGHT)) {
-    gdk_draw_pixmap(pixmap, civ_gc, dither[1]->pixmap,
-                   0, NORMAL_TILE_HEIGHT/2,
-                   canvas_x,
-                   canvas_y + NORMAL_TILE_HEIGHT/2,
-                   NORMAL_TILE_WIDTH/2, NORMAL_TILE_HEIGHT/2);
-  }
-
-  /* east */
-  if (dither[2]
-      && (offset_x != 0 || width == NORMAL_TILE_WIDTH)
-      && (offset_y != 0 || height == NORMAL_TILE_HEIGHT)) {
-    gdk_draw_pixmap(pixmap, civ_gc, dither[2]->pixmap,
-                   NORMAL_TILE_WIDTH/2, NORMAL_TILE_HEIGHT/2,
-                   canvas_x + NORMAL_TILE_WIDTH/2,
-                   canvas_y + NORMAL_TILE_HEIGHT/2,
-                   NORMAL_TILE_WIDTH/2, NORMAL_TILE_HEIGHT/2);
-  }
-
-  /* west */
-  if (dither[3] && offset_x == 0 && offset_y == 0) {
-    gdk_draw_pixmap(pixmap, civ_gc, dither[3]->pixmap,
-                   0, 0,
-                   canvas_x,
-                   canvas_y,
-                   NORMAL_TILE_WIDTH/2, NORMAL_TILE_HEIGHT/2);
-  }
-
-  gdk_gc_set_clip_mask(civ_gc, NULL);
-
-  if (fog) {
-    gdk_gc_set_clip_origin(fill_tile_gc, canvas_x, canvas_y);
-    gdk_gc_set_clip_mask(fill_tile_gc, sprites.dither_tile->mask);
-    gdk_gc_set_foreground(fill_tile_gc, colors_standard[COLOR_STD_BLACK]);
-    gdk_gc_set_stipple(fill_tile_gc, black50);
-
-    gdk_draw_rectangle(pixmap, fill_tile_gc, TRUE,
-                      canvas_x+offset_x, canvas_y+offset_y,
-                      MIN(width, MAX(0, NORMAL_TILE_WIDTH-offset_x)),
-                      MIN(height, MAX(0, NORMAL_TILE_HEIGHT-offset_y)));
-    gdk_gc_set_clip_mask(fill_tile_gc, NULL);
-  }
-}
-
-/**************************************************************************
 Only used for isometric view.
 **************************************************************************/
 static void pixmap_put_tile_iso(GdkDrawable *pm, int x, int y,
@@ -1078,18 +1003,17 @@
                                enum draw_type draw)
 {
   struct drawn_sprite tile_sprs[80];
-  struct Sprite *dither[4];
   struct city *pcity;
   struct unit *punit, *pfocus;
   enum tile_special_type special;
-  int count, i = 0, dither_count;
+  int count, i;
   bool solid_bg, fog, tile_hilited;
   struct canvas canvas_store = {pm};
 
   if (!width || !(height || height_unit))
     return;
 
-  count = fill_tile_sprite_array_iso(tile_sprs, dither, &dither_count,
+  count = fill_tile_sprite_array_iso(tile_sprs,
                                     x, y, citymode, &solid_bg);
 
   if (count == -1) { /* tile is unknown */
@@ -1133,19 +1057,8 @@
     }
   }
 
-  /*** Draw and dither base terrain ***/
-  if (dither_count > 0) {
-    for (i = 0; i < dither_count; i++) {
-      pixmap_put_drawn_sprite(pm, canvas_x, canvas_y, &tile_sprs[i],
-                             offset_x, offset_y, width, height, fog);
-    }
-
-    dither_tile(pm, dither, canvas_x, canvas_y,
-               offset_x, offset_y, width, height, fog);
-  }
-
-  /*** Rest of terrain and specials ***/
-  for (; i<count; i++) {
+  /*** Draw terrain and specials ***/
+  for (i = 0; i < count; i++) {
     if (tile_sprs[i].sprite)
       pixmap_put_drawn_sprite(pm, canvas_x, canvas_y, &tile_sprs[i],
                              offset_x, offset_y, width, height, fog);
Index: client/gui-gtk/plrdlg.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-gtk/plrdlg.c,v
retrieving revision 1.51
diff -u -r1.51 plrdlg.c
--- client/gui-gtk/plrdlg.c     31 Jan 2004 17:52:40 -0000      1.51
+++ client/gui-gtk/plrdlg.c     22 Mar 2004 22:30:43 -0000
@@ -382,7 +382,7 @@
   assert(flag_w >= MIN_DIMENSION && flag_h >= MIN_DIMENSION);
   
   /* croping */
-  croped = crop_sprite(flag, start_x, start_y, flag_w, flag_h);
+  croped = crop_sprite(flag, start_x, start_y, flag_w, flag_h, NULL, -1, -1);
 
   /* scaling */
   newflag_h = GTK_CLIST(players_list)->row_height;
Index: client/gui-gtk-2.0/graphics.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-gtk-2.0/graphics.c,v
retrieving revision 1.23
diff -u -r1.23 graphics.c
--- client/gui-gtk-2.0/graphics.c       24 Feb 2004 05:20:25 -0000      1.23
+++ client/gui-gtk-2.0/graphics.c       22 Mar 2004 22:30:44 -0000
@@ -168,9 +168,11 @@
 ***************************************************************************/
 struct Sprite *crop_sprite(struct Sprite *source,
                           int x, int y,
-                          int width, int height)
+                          int width, int height,
+                          struct Sprite *mask,
+                          int mask_offset_x, int mask_offset_y)
 {
-  GdkPixmap *mypixmap, *mask = NULL;
+  GdkPixmap *mypixmap, *mymask = NULL;
 
   mypixmap = gdk_pixmap_new(root_window, width, height, -1);
 
@@ -178,14 +180,30 @@
                    width, height);
 
   if (source->has_mask) {
-    mask = gdk_pixmap_new(NULL, width, height, 1);
-    gdk_draw_rectangle(mask, mask_bg_gc, TRUE, 0, 0, -1, -1);
+    mymask = gdk_pixmap_new(NULL, width, height, 1);
+    gdk_draw_rectangle(mymask, mask_bg_gc, TRUE, 0, 0, -1, -1);
 
-    gdk_draw_drawable(mask, mask_fg_gc, source->mask,
+    gdk_draw_drawable(mymask, mask_fg_gc, source->mask,
                      x, y, 0, 0, width, height);
   }
 
-  return ctor_sprite_mask(mypixmap, mask, width, height);
+  if (mask) {
+    if (mymask) {
+      gdk_gc_set_function(mask_fg_gc, GDK_AND);
+      gdk_draw_drawable(mymask, mask_fg_gc, mask->mask,
+                       x - mask_offset_x, y - mask_offset_y,
+                       0, 0, width, height);
+      gdk_gc_set_function(mask_fg_gc, GDK_OR);
+    } else {
+      mymask = gdk_pixmap_new(NULL, width, height, 1);
+      gdk_draw_rectangle(mymask, mask_bg_gc, TRUE, 0, 0, -1, -1);
+
+      gdk_draw_drawable(mymask, mask_fg_gc, source->mask,
+                       x, y, 0, 0, width, height);
+    }
+  }
+
+  return ctor_sprite_mask(mypixmap, mymask, width, height);
 }
 
 /****************************************************************************
@@ -516,7 +534,7 @@
 
   sprite_get_bounding_box(s, &x1, &y1, &x2, &y2);
 
-  return crop_sprite(s, x1, y1, x2 - x1 + 1, y2 - y1 + 1);
+  return crop_sprite(s, x1, y1, x2 - x1 + 1, y2 - y1 + 1, NULL, -1, -1);
 }
 
 /*********************************************************************
Index: client/gui-gtk-2.0/mapview.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-gtk-2.0/mapview.c,v
retrieving revision 1.107
diff -u -r1.107 mapview.c
--- client/gui-gtk-2.0/mapview.c        15 Mar 2004 05:35:28 -0000      1.107
+++ client/gui-gtk-2.0/mapview.c        22 Mar 2004 22:30:44 -0000
@@ -1074,81 +1074,6 @@
 }
 
 /**************************************************************************
-Blend the tile with neighboring tiles.
-Only used for isometric view.
-**************************************************************************/
-static void dither_tile(GdkDrawable *pixmap, struct Sprite **dither,
-                       int canvas_x, int canvas_y,
-                       int offset_x, int offset_y,
-                       int width, int height, bool fog)
-{
-  if (!width || !height)
-    return;
-
-  gdk_gc_set_clip_mask(civ_gc, sprites.dither_tile->mask);
-  gdk_gc_set_clip_origin(civ_gc, canvas_x, canvas_y);
-  assert(offset_x == 0 || offset_x == NORMAL_TILE_WIDTH/2);
-  assert(offset_y == 0 || offset_y == NORMAL_TILE_HEIGHT/2);
-  assert(width == NORMAL_TILE_WIDTH || width == NORMAL_TILE_WIDTH/2);
-  assert(height == NORMAL_TILE_HEIGHT || height == NORMAL_TILE_HEIGHT/2);
-
-  /* north */
-  if (dither[0]
-      && (offset_x != 0 || width == NORMAL_TILE_WIDTH)
-      && (offset_y == 0)) {
-    gdk_draw_drawable(pixmap, civ_gc, dither[0]->pixmap,
-                     NORMAL_TILE_WIDTH/2, 0,
-                     canvas_x + NORMAL_TILE_WIDTH/2, canvas_y,
-                     NORMAL_TILE_WIDTH/2, NORMAL_TILE_HEIGHT/2);
-  }
-
-  /* south */
-  if (dither[1] && offset_x == 0
-      && (offset_y == NORMAL_TILE_HEIGHT/2 || height == NORMAL_TILE_HEIGHT)) {
-    gdk_draw_drawable(pixmap, civ_gc, dither[1]->pixmap,
-                     0, NORMAL_TILE_HEIGHT/2,
-                     canvas_x,
-                     canvas_y + NORMAL_TILE_HEIGHT/2,
-                     NORMAL_TILE_WIDTH/2, NORMAL_TILE_HEIGHT/2);
-  }
-
-  /* east */
-  if (dither[2]
-      && (offset_x != 0 || width == NORMAL_TILE_WIDTH)
-      && (offset_y != 0 || height == NORMAL_TILE_HEIGHT)) {
-    gdk_draw_drawable(pixmap, civ_gc, dither[2]->pixmap,
-                     NORMAL_TILE_WIDTH/2, NORMAL_TILE_HEIGHT/2,
-                     canvas_x + NORMAL_TILE_WIDTH/2,
-                     canvas_y + NORMAL_TILE_HEIGHT/2,
-                     NORMAL_TILE_WIDTH/2, NORMAL_TILE_HEIGHT/2);
-  }
-
-  /* west */
-  if (dither[3] && offset_x == 0 && offset_y == 0) {
-    gdk_draw_drawable(pixmap, civ_gc, dither[3]->pixmap,
-                     0, 0,
-                     canvas_x,
-                     canvas_y,
-                     NORMAL_TILE_WIDTH/2, NORMAL_TILE_HEIGHT/2);
-  }
-
-  gdk_gc_set_clip_mask(civ_gc, NULL);
-
-  if (fog) {
-    gdk_gc_set_clip_origin(fill_tile_gc, canvas_x, canvas_y);
-    gdk_gc_set_clip_mask(fill_tile_gc, sprites.dither_tile->mask);
-    gdk_gc_set_foreground(fill_tile_gc, colors_standard[COLOR_STD_BLACK]);
-    gdk_gc_set_stipple(fill_tile_gc, black50);
-
-    gdk_draw_rectangle(pixmap, fill_tile_gc, TRUE,
-                      canvas_x+offset_x, canvas_y+offset_y,
-                      MIN(width, MAX(0, NORMAL_TILE_WIDTH-offset_x)),
-                      MIN(height, MAX(0, NORMAL_TILE_HEIGHT-offset_y)));
-    gdk_gc_set_clip_mask(fill_tile_gc, NULL);
-  }
-}
-
-/**************************************************************************
 Only used for isometric view.
 **************************************************************************/
 static void pixmap_put_tile_iso(GdkDrawable *pm, int x, int y,
@@ -1159,18 +1084,17 @@
                                enum draw_type draw)
 {
   struct drawn_sprite tile_sprs[80];
-  struct Sprite *dither[4];
   struct city *pcity;
   struct unit *punit, *pfocus;
   enum tile_special_type special;
-  int count, i = 0, dither_count;
+  int count, i;
   bool solid_bg, fog, tile_hilited;
   struct canvas canvas_store = {pm};
 
   if (!width || !(height || height_unit))
     return;
 
-  count = fill_tile_sprite_array_iso(tile_sprs, dither, &dither_count,
+  count = fill_tile_sprite_array_iso(tile_sprs,
                                     x, y, citymode, &solid_bg);
 
   if (count == -1) { /* tile is unknown */
@@ -1214,19 +1138,8 @@
     }
   }
 
-  /*** Draw and dither base terrain ***/
-  if (dither_count > 0) {
-    for (i = 0; i < dither_count; i++) {
-      pixmap_put_drawn_sprite(pm, canvas_x, canvas_y, &tile_sprs[i],
-                             offset_x, offset_y, width, height, fog);
-    }
-
-    dither_tile(pm, dither, canvas_x, canvas_y,
-               offset_x, offset_y, width, height, fog);
-  }
-
-  /*** Rest of terrain and specials ***/
-  for (; i<count; i++) {
+  /*** Draw terrain and specials ***/
+  for (i = 0; i < count; i++) {
     if (tile_sprs[i].sprite)
       pixmap_put_drawn_sprite(pm, canvas_x, canvas_y, &tile_sprs[i],
                              offset_x, offset_y, width, height, fog);
Index: client/gui-win32/graphics.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-win32/graphics.c,v
retrieving revision 1.16
diff -u -r1.16 graphics.c
--- client/gui-win32/graphics.c 24 Feb 2004 05:20:25 -0000      1.16
+++ client/gui-win32/graphics.c 22 Mar 2004 22:30:44 -0000
@@ -160,9 +160,10 @@
 /**************************************************************************
 
 **************************************************************************/
-struct Sprite *
-crop_sprite(struct Sprite *source,
-                           int x, int y, int width, int height)
+struct Sprite *crop_sprite(struct Sprite *source,
+                          int x, int y, int width, int height,
+                          struct Sprite *mask,
+                          int mask_offset_x, int mask_offset_y)
 {
   SPRITE *mysprite;
   HDC hdc;
@@ -218,6 +219,20 @@
       DeleteObject(bigmask);
     }
 
+  if (mask && mask->has_mask) {
+    bigmask = BITMAP2HBITMAP(&mask->mask);
+    SelectObject(hdcbig, bigmask);
+    if (!smallmask) {
+      smallmask=CreateBitmap(width,height,1,1,NULL);
+      SelectObject(hdcsmall,smallmask);
+    }
+    BitBlt(hdcsmall, 0, 0, width, height, hdcbig,
+          x - mask_offset_x, y - mask_offset_y, SRCPAINT);
+    
+    SelectObject(hdcbig, bigbitmap);
+    DeleteObject(bigmask);
+  }
+
   mysprite=fc_malloc(sizeof(struct Sprite));
   mysprite->cache_id=0;
   mysprite->width=width;
@@ -235,8 +250,7 @@
   ReleaseDC(root_window,hdc);
   if (smallmask) DeleteObject(smallmask);
   DeleteObject(smallbitmap);
-     
-   
+
   return mysprite;
 }
 
@@ -448,11 +462,11 @@
 /**************************************************************************
 
 **************************************************************************/
-void  draw_sprite_part_with_mask(struct Sprite *sprite,
-                                struct Sprite *sprite_mask,
-                                HDC hdc,
-                                int x, int y,int w, int h,
-                                int xsrc, int ysrc)
+static void draw_sprite_part_with_mask(struct Sprite *sprite,
+                                      struct Sprite *sprite_mask,
+                                      HDC hdc,
+                                      int x, int y,int w, int h,
+                                      int xsrc, int ysrc)
 {
   HDC hdccomp;
   HDC hdcmask;
Index: client/gui-win32/graphics.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-win32/graphics.h,v
retrieving revision 1.7
diff -u -r1.7 graphics.h
--- client/gui-win32/graphics.h 8 Mar 2004 07:20:50 -0000       1.7
+++ client/gui-win32/graphics.h 22 Mar 2004 22:30:44 -0000
@@ -45,11 +45,6 @@
 void draw_sprite(struct Sprite *sprite,HDC hdc,int x, int y);
 void draw_sprite_part(struct Sprite *sprite,HDC hdc,
                       int x, int y, int w, int h,int xsrc,int ysrc);
-void draw_sprite_part_with_mask(struct Sprite *sprite,
-                               struct Sprite *sprite_mask,
-                               HDC hdc,
-                               int x, int y, int w, int h,
-                               int xsrc, int ysrc);
 void init_fog_bmp(void);
 void draw_fog_part(HDC hdc,int x, int y,int w, int h,
                   int xsrc, int ysrc);
Index: client/gui-win32/mapview.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-win32/mapview.c,v
retrieving revision 1.105
diff -u -r1.105 mapview.c
--- client/gui-win32/mapview.c  17 Mar 2004 09:10:57 -0000      1.105
+++ client/gui-win32/mapview.c  22 Mar 2004 22:30:44 -0000
@@ -713,72 +713,6 @@
 }
 
 /**************************************************************************
-
-**************************************************************************/
-static void dither_tile(HDC hdc, struct Sprite **dither,
-                        int canvas_x, int canvas_y,
-                        int offset_x, int offset_y,
-                        int width, int height, bool fog)
-{
-  if (!width || !height)
-    return;
-  
-  assert(offset_x == 0 || offset_x == NORMAL_TILE_WIDTH/2);
-  assert(offset_y == 0 || offset_y == NORMAL_TILE_HEIGHT/2);
-  assert(width == NORMAL_TILE_WIDTH || width == NORMAL_TILE_WIDTH/2);
-  assert(height == NORMAL_TILE_HEIGHT || height == NORMAL_TILE_HEIGHT/2);
-  
-  /* north */
-  if (dither[0]
-      && (offset_x != 0 || width == NORMAL_TILE_WIDTH)
-      && (offset_y == 0)) {
-    draw_sprite_part_with_mask(dither[0],sprites.dither_tile,hdc,
-                              canvas_x + NORMAL_TILE_WIDTH/2, canvas_y,
-                              NORMAL_TILE_WIDTH/2, NORMAL_TILE_HEIGHT/2,
-                              NORMAL_TILE_WIDTH/2, 0);
-  }
-
-  /* south */
-  if (dither[1] && offset_x == 0
-      && (offset_y == NORMAL_TILE_HEIGHT/2 || height == NORMAL_TILE_HEIGHT)) {
-    draw_sprite_part_with_mask(dither[1],sprites.dither_tile,hdc,
-                              canvas_x,
-                              canvas_y + NORMAL_TILE_HEIGHT/2,
-                              NORMAL_TILE_WIDTH/2, NORMAL_TILE_HEIGHT/2,
-                              0, NORMAL_TILE_HEIGHT/2);
-  }
-
-  /* east */
-  if (dither[2]
-      && (offset_x != 0 || width == NORMAL_TILE_WIDTH)
-      && (offset_y != 0 || height == NORMAL_TILE_HEIGHT)) {
-    draw_sprite_part_with_mask(dither[2],sprites.dither_tile,hdc,
-                              canvas_x + NORMAL_TILE_WIDTH/2,
-                              canvas_y + NORMAL_TILE_HEIGHT/2,
-                              NORMAL_TILE_WIDTH/2, NORMAL_TILE_HEIGHT/2,
-                              NORMAL_TILE_WIDTH/2, NORMAL_TILE_HEIGHT/2);
-  }
-
-  /* west */
-  if (dither[3] && offset_x == 0 && offset_y == 0) {
-    draw_sprite_part_with_mask(dither[3],sprites.dither_tile,hdc,
-                              canvas_x,
-                              canvas_y,
-                              NORMAL_TILE_WIDTH/2, NORMAL_TILE_HEIGHT/2,
-                              0,0);
-  }
-
-
-  if (fog) {
-    draw_fog_part(hdc,canvas_x+offset_x, canvas_y+offset_y,
-                 MIN(width, MAX(0, NORMAL_TILE_WIDTH-offset_x)),
-                 MIN(height, MAX(0, NORMAL_TILE_HEIGHT-offset_y)),
-                 offset_x,offset_y);
-  }
-
-}
-
-/**************************************************************************
 Only used for isometric view.
 **************************************************************************/
 static void pixmap_put_overlay_tile_draw(HDC hdc,
@@ -1014,19 +948,17 @@
                                 enum draw_type draw)
 {
   struct drawn_sprite tile_sprs[80];
-  struct Sprite *dither[4];
   struct city *pcity;
   struct unit *punit, *pfocus;
   struct canvas canvas_store={hdc,NULL};
   enum tile_special_type special;
-  int count, i = 0, dither_count;
+  int count, i;
   bool fog, solid_bg, is_real;
 
   if (!width || !(height || height_unit))
     return;
 
-  count = fill_tile_sprite_array_iso(tile_sprs, dither, &dither_count,
-                                     x, y, citymode, &solid_bg);
+  count = fill_tile_sprite_array_iso(tile_sprs, x, y, citymode, &solid_bg);
 
   if (count == -1) { /* tile is unknown */
     pixmap_put_black_tile_iso(hdc, canvas_x, canvas_y,
@@ -1060,19 +992,8 @@
     SelectObject(hdc,oldbrush);
   }
 
-  /*** Draw and dither base terrain ***/
-  if (dither_count > 0) {
-    for (i = 0; i < dither_count; i++) {
-      pixmap_put_drawn_sprite(hdc, canvas_x, canvas_y, &tile_sprs[i],
-                             offset_x, offset_y, width, height, fog);
-    }
-
-    dither_tile(hdc, dither, canvas_x, canvas_y,
-                  offset_x, offset_y, width, height, fog);
-  }
-  
-  /*** Rest of terrain and specials ***/
-  for (; i<count; i++) {
+  /*** Draw terrain and specials ***/
+  for (i = 0; i < count; i++) {
     if (tile_sprs[i].sprite)
       pixmap_put_drawn_sprite(hdc, canvas_x, canvas_y, &tile_sprs[i],
                                    offset_x, offset_y, width, height, fog);
Index: client/gui-xaw/graphics.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-xaw/graphics.c,v
retrieving revision 1.51
diff -u -r1.51 graphics.c
--- client/gui-xaw/graphics.c   24 Feb 2004 05:20:25 -0000      1.51
+++ client/gui-xaw/graphics.c   22 Mar 2004 22:30:44 -0000
@@ -165,9 +165,12 @@
 return newly allocated sprite cropped from source
 ***************************************************************************/
 struct Sprite *crop_sprite(struct Sprite *source,
-                          int x, int y, int width, int height)
+                          int x, int y, int width, int height,
+                          struct Sprite *mask,
+                          int mask_offset_x, int mask_offset_y)
 {
-  Pixmap mypixmap;
+  Pixmap mypixmap, mymask;
+  GC plane_gc;
 
   mypixmap = XCreatePixmap(display, root_window,
                           width, height, display_depth);
@@ -175,16 +178,33 @@
            x, y, width, height, 0, 0);
 
   if (source->has_mask) {
-    GC plane_gc;
-    Pixmap mask;
+    mymask = XCreatePixmap(display, root_window, width, height, 1);
 
-    mask = XCreatePixmap(display, root_window, width, height, 1);
+    plane_gc = XCreateGC(display, mymask, 0, NULL);
+    XCopyArea(display, source->mask, mymask, plane_gc, 
+             x, y, width, height, 0, 0);
+    XFreeGC(display, plane_gc);
+
+    if (mask) {
+      XGCValues values;
+
+      values.function = GXand;
+
+      plane_gc = XCreateGC(display, mymask, GCFunction, &values);
+      XCopyArea(display, mask->mask, mymask, plane_gc,
+               x - mask_offset_x, y - mask_offset_y, width, height, 0, 0);
+      XFreeGC(display, plane_gc);
+    }
+
+    return ctor_sprite_mask(mypixmap, mymask, width, height);
+  } else if (mask) {
+    mymask = XCreatePixmap(display, root_window, width, height, 1);
 
-    plane_gc = XCreateGC(display, mask, 0, NULL);
-    XCopyArea(display, source->mask, mask, plane_gc, 
+    plane_gc = XCreateGC(display, mymask, 0, NULL);
+    XCopyArea(display, source->mask, mymask, plane_gc, 
              x, y, width, height, 0, 0);
     XFreeGC(display, plane_gc);
-    return ctor_sprite_mask(mypixmap, mask, width, height);
+    return ctor_sprite_mask(mypixmap, mymask, width, height);
   } else {
     return ctor_sprite(mypixmap, width, height);
   }
Index: client/include/graphics_g.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/include/graphics_g.h,v
retrieving revision 1.9
diff -u -r1.9 graphics_g.h
--- client/include/graphics_g.h 24 Feb 2004 05:20:25 -0000      1.9
+++ client/include/graphics_g.h 22 Mar 2004 22:30:44 -0000
@@ -29,7 +29,9 @@
 
 struct Sprite *load_gfxfile(const char *filename);
 struct Sprite *crop_sprite(struct Sprite *source,
-                          int x, int y, int width, int height);
+                          int x, int y, int width, int height,
+                          struct Sprite *mask,
+                          int mask_offset_x, int mask_offset_y);
 void get_sprite_dimensions(struct Sprite *sprite, int *width, int *height);
 void free_sprite(struct Sprite *s);
 
Index: data/isotrident.tilespec
===================================================================
RCS file: /home/freeciv/CVS/freeciv/data/isotrident.tilespec,v
retrieving revision 1.12
diff -u -r1.12 isotrident.tilespec
--- data/isotrident.tilespec    27 Feb 2004 18:31:39 -0000      1.12
+++ data/isotrident.tilespec    22 Mar 2004 22:30:44 -0000
@@ -102,7 +102,7 @@
 
 ; ocean has special handling
 [terrain_ocean]
-is_blended = 0
+is_blended = 1
 is_layered = 0
 match_type = 6
 cell_type = "rect"
Index: data/trident.tilespec
===================================================================
RCS file: /home/freeciv/CVS/freeciv/data/trident.tilespec,v
retrieving revision 1.18
diff -u -r1.18 trident.tilespec
--- data/trident.tilespec       27 Feb 2004 00:14:00 -0000      1.18
+++ data/trident.tilespec       22 Mar 2004 22:30:44 -0000
@@ -122,7 +122,7 @@
 [terrain_unknown]
 is_blended = 0
 is_layered = 0
-match_type = 11
+match_type = 0
 
 [terrain_t_river]
 is_blended = 0
Index: data/isotrident/terrain1.spec
===================================================================
RCS file: /home/freeciv/CVS/freeciv/data/isotrident/terrain1.spec,v
retrieving revision 1.3
diff -u -r1.3 terrain1.spec
--- data/isotrident/terrain1.spec       18 Mar 2004 20:00:24 -0000      1.3
+++ data/isotrident/terrain1.spec       22 Mar 2004 22:30:45 -0000
@@ -53,8 +53,6 @@
 
   9,    0, "t.jungle1"
 
-  10,   0, "t.ocean1"
-
 ; Terrain special resources:
 
  0,   2, "ts.oasis"
@@ -136,7 +134,8 @@
   0, 0, "tx.darkness"
   0, 1, "tx.fog"
   0, 2, "t.black_tile"
-  0, 3, "t.coast_color"
+  0, 2, "t.unknown1"
+  0, 3, "t.ocean1"
 
   0, 4, "user.attention"
 }

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