[Freeciv-Dev] (PR#7612) crop_sprite with a mask
[Top] [All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
<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"
}
|
|