Complete.Org: Mailing Lists: Archives: freeciv-dev: July 2003:
[Freeciv-Dev] (PR#4576) remove sprite padding for flags
Home

[Freeciv-Dev] (PR#4576) remove sprite padding for flags

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
To: undisclosed-recipients: ;
Subject: [Freeciv-Dev] (PR#4576) remove sprite padding for flags
From: "Jason Short" <jdorje@xxxxxxxxxxxxxxxxxxxxx>
Date: Tue, 15 Jul 2003 21:44:22 -0700
Reply-to: rt@xxxxxxxxxxxxxx

The attached patch removes the necessity for sprite padding for flags in 
iso-view tilesets.  It basically follows the idea put forth in PR#2960, 
but only implements it for flags.

Only gui-gtk is supported; support for other clients will be similar but 
since I can't test most of them I didn't write it.

Because of this it is a bit of a hack.  We introduce a new structure

struct drawn_sprite {
   struct Sprite *sprite;
   int offset_x, offset_y;
}

which the tilespec code can use to specify not only which sprite to 
draw, but where to draw it.  It's a hack because this structure is used 
only in fill_unit_sprite array and not in all of the other 
fill_***_sprite_array functions.  Eventually it should be used 
everywhere, allowing padding on all sprites to be removed (or even 
cropped out, to speed up drawing).

I change the isotrident tileset to simply use the trident flags.

There are some other design issues as well.  This is just a 
demonstration patch; implementing this "properly" will take a larger 
amount of code changes.

IIRC there is a fair amount of code to crop flag sprites for the nation 
selection and player dialog.  This code should all go away once flags 
have no padding.

jason

? rc
Index: client/tilespec.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/tilespec.c,v
retrieving revision 1.120
diff -u -r1.120 tilespec.c
--- client/tilespec.c   2003/07/13 00:47:25     1.120
+++ client/tilespec.c   2003/07/16 04:34:57
@@ -81,6 +81,7 @@
 
 static bool is_mountainous = FALSE;
 static int roadstyle;
+static int flag_offset_x, flag_offset_y;
 
 struct specfile;
 
@@ -617,6 +618,10 @@
                                               "tilespec.is_mountainous");
   roadstyle = secfile_lookup_int_default(file, is_isometric ? 0 : 1,
                                         "tilespec.roadstyle");
+  flag_offset_x = secfile_lookup_int_default(file, 0,
+                                            "tilespec.flag_offset_x");
+  flag_offset_y = secfile_lookup_int_default(file, 0,
+                                            "tilespec.flag_offset_y");
 
   c = secfile_lookup_str_default(file, "10x20", "tilespec.city_names_font");
   city_names_font = mystrdup(c);
@@ -1360,31 +1365,41 @@
   }
 }
 
+#define ADD_SPRITE(s, x_offset, y_offset) \
+  (sprs->sprite = s,                      \
+   sprs->offset_x = x_offset,             \
+   sprs->offset_y = y_offset,             \
+   sprs++)
+
+#define ADD_SPRITE_SIMPLE(s) ADD_SPRITE(s, 0, 0)
+
 /**********************************************************************
   Fill in the sprite array for the unit
 ***********************************************************************/
-int fill_unit_sprite_array(struct Sprite **sprs, struct unit *punit,
-                          int *solid_bg)
+int fill_unit_sprite_array(struct drawn_sprite *sprs,
+                          struct unit *punit, int *solid_bg)
 {
-  struct Sprite **save_sprs=sprs;
+  struct drawn_sprite *save_sprs = sprs;
   int ihp;
   *solid_bg = 0;
 
   if (is_isometric) {
     if (!no_backdrop) {
-      *sprs++ = get_unit_nation_flag_sprite(punit);
+      ADD_SPRITE(get_unit_nation_flag_sprite(punit),
+                flag_offset_x, flag_offset_y);
     }
   } else {
     if (!no_backdrop) {
       if (!solid_color_behind_units) {
-       *sprs++ = get_unit_nation_flag_sprite(punit);
+       ADD_SPRITE(get_unit_nation_flag_sprite(punit),
+                  flag_offset_x, flag_offset_y);
       } else {
        *solid_bg = 1;
       }
     }
   }
 
-  *sprs++ = unit_type(punit)->sprite;
+  ADD_SPRITE_SIMPLE(unit_type(punit)->sprite);
 
   if(punit->activity!=ACTIVITY_IDLE) {
     struct Sprite *s = NULL;
@@ -1436,28 +1451,28 @@
       break;
     }
 
-    *sprs++ = s;
+    ADD_SPRITE_SIMPLE(s);
   }
 
   if (punit->ai.control && punit->activity != ACTIVITY_EXPLORE) {
     if (is_military_unit(punit)) {
-      *sprs++ = sprites.unit.auto_attack;
+      ADD_SPRITE_SIMPLE(sprites.unit.auto_attack);
     } else {
-      *sprs++ = sprites.unit.auto_settler;
+      ADD_SPRITE_SIMPLE(sprites.unit.auto_settler);
     }
   }
 
   if (punit->connecting) {
-    *sprs++ = sprites.unit.connect;
+    ADD_SPRITE_SIMPLE(sprites.unit.connect);
   }
 
   if (punit->activity == ACTIVITY_PATROL) {
-    *sprs++ = sprites.unit.patrol;
+    ADD_SPRITE_SIMPLE(sprites.unit.patrol);
   }
 
   ihp = ((NUM_TILES_HP_BAR-1)*punit->hp) / unit_type(punit)->hp;
   ihp = CLIP(0, ihp, NUM_TILES_HP_BAR-1);
-  *sprs++ = sprites.unit.hp_bar[ihp];
+  ADD_SPRITE_SIMPLE(sprites.unit.hp_bar[ihp]);
 
   return sprs - save_sprs;
 }
@@ -2026,7 +2041,14 @@
   if (solid_color_behind_units) {
     punit = get_drawable_unit(abs_x0, abs_y0, citymode);
     if (punit && (draw_units || (draw_focus_unit && pfocus == punit))) {
-      sprs += fill_unit_sprite_array(sprs, punit, solid_bg);
+      struct drawn_sprite my_sprs[40];
+      int count = fill_unit_sprite_array(my_sprs, punit, solid_bg), i;
+
+      for (i = 0; i < count; i++) {
+       /* HACK: transform drawn_sprite into sprite. */
+       assert(my_sprs[i].offset_x == 0 && my_sprs[i].offset_y == 0);
+       *sprs++ = my_sprs[i].sprite;
+      }
       *pplayer = unit_owner(punit);
       if (unit_list_size(&ptile->units) > 1)  
        *sprs++ = sprites.unit.stack;
@@ -2167,10 +2189,17 @@
       if ((!focus_unit_hidden || pfocus != punit) &&
          (draw_units || (draw_focus_unit && !focus_unit_hidden
                          && punit == pfocus))) {
-       int dummy;
+       int dummy, count, i;
+       struct drawn_sprite my_sprs[40];
 
        no_backdrop = (pcity != NULL);
-       sprs += fill_unit_sprite_array(sprs, punit, &dummy);
+       count = fill_unit_sprite_array(my_sprs, punit, &dummy);
+
+       for (i = 0; i < count; i++) {
+         /* HACK: transform drawn_sprite into sprite. */
+         assert(my_sprs[i].offset_x == 0 && my_sprs[i].offset_y == 0);
+         *sprs++ = my_sprs[i].sprite;
+       }
        no_backdrop = FALSE;
        if (unit_list_size(&ptile->units) > 1) {  
          *sprs++ = sprites.unit.stack;
Index: client/tilespec.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/tilespec.h,v
retrieving revision 1.44
diff -u -r1.44 tilespec.h
--- client/tilespec.h   2003/04/09 20:47:43     1.44
+++ client/tilespec.h   2003/07/16 04:34:57
@@ -28,6 +28,11 @@
 struct unit;
 struct player;
 
+struct drawn_sprite {
+  struct Sprite *sprite;
+  int offset_x, offset_y;      /* offset from tile origin */
+};
+
 const char **get_tileset_list(void);
 
 void tilespec_read_toplevel(const char *tileset_name);
@@ -55,7 +60,8 @@
                               int *solid_bg);
 int fill_tile_sprite_array(struct Sprite **sprs, int abs_x0, int abs_y0,
                           bool citymode, int *solid_bg, struct player 
**pplayer);
-int fill_unit_sprite_array(struct Sprite **sprs, struct unit *punit, int 
*solid_bg);
+int fill_unit_sprite_array(struct drawn_sprite *sprs,
+                          struct unit *punit, int *solid_bg);
 int fill_city_sprite_array_iso(struct Sprite **sprs, struct city *pcity);
 
 enum color_std player_color(struct player *pplayer);
Index: client/gui-gtk/mapview.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-gtk/mapview.c,v
retrieving revision 1.171
diff -u -r1.171 mapview.c
--- client/gui-gtk/mapview.c    2003/07/11 20:11:42     1.171
+++ client/gui-gtk/mapview.c    2003/07/16 04:34:57
@@ -639,22 +639,22 @@
                            int canvas_x, int canvas_y)
 {
   int solid_bg;
+  struct drawn_sprite sprites[40];
+  int count = fill_unit_sprite_array(sprites, punit, &solid_bg);
 
   if (is_isometric) {
-    struct Sprite *sprites[40];
-    int count = fill_unit_sprite_array(sprites, punit, &solid_bg);
     int i;
 
     assert(!solid_bg);
     for (i=0; i<count; i++) {
-      if (sprites[i]) {
-       pixmap_put_overlay_tile(pm, canvas_x, canvas_y, sprites[i]);
+      if (sprites[i].sprite) {
+       pixmap_put_overlay_tile(pm,
+                               canvas_x + sprites[i].offset_x,
+                               canvas_y + sprites[i].offset_y,
+                               sprites[i].sprite);
       }
     }
   } else { /* is_isometric */
-    struct Sprite *sprites[40];
-    int count = fill_unit_sprite_array(sprites, punit, &solid_bg);
-
     if (count) {
       int i = 0;
 
@@ -665,13 +665,19 @@
                           canvas_x, canvas_y,
                           UNIT_TILE_WIDTH, UNIT_TILE_HEIGHT);
       } else {
-       pixmap_put_overlay_tile(pm, canvas_x, canvas_y, sprites[0]);
+       pixmap_put_overlay_tile(pm,
+                               canvas_x + sprites[i].offset_x,
+                               canvas_y + sprites[i].offset_y,
+                               sprites[0].sprite);
        i++;
       }
 
       for (; i<count; i++) {
-       if (sprites[i])
-         pixmap_put_overlay_tile(pm, canvas_x, canvas_y, sprites[i]);
+       if (sprites[i].sprite)
+         pixmap_put_overlay_tile(pm, 
+                                 canvas_x + sprites[i].offset_x,
+                                 canvas_y + sprites[i].offset_y,
+                                 sprites[i].sprite);
       }
     }
   }
@@ -685,16 +691,20 @@
                                 int offset_x, int offset_y_unit,
                                 int width, int height_unit)
 {
-  struct Sprite *sprites[40];
+  struct drawn_sprite sprites[40];
   int dummy;
   int count = fill_unit_sprite_array(sprites, punit, &dummy);
   int i;
 
   for (i=0; i<count; i++) {
-    if (sprites[i]) {
-      pixmap_put_overlay_tile_draw(pm, canvas_x, canvas_y, sprites[i],
-                                  offset_x, offset_y_unit,
-                                  width, height_unit, 0);
+    if (sprites[i].sprite) {
+      int ox = sprites[i].offset_x, oy = sprites[i].offset_y;
+      pixmap_put_overlay_tile_draw(pm,
+                                  canvas_x + ox, canvas_y + oy,
+                                  sprites[i].sprite,
+                                  offset_x - ox,
+                                  offset_y_unit - oy,
+                                  width - ox, height_unit - oy, 0);
     }
   }
 }
@@ -911,7 +921,7 @@
 **************************************************************************/
 void put_unit_gpixmap(struct unit *punit, GtkPixcomm *p)
 {
-  struct Sprite *sprites[40];
+  struct drawn_sprite sprites[40];
   int solid_bg;
   int count = fill_unit_sprite_array(sprites, punit, &solid_bg);
 
@@ -924,8 +934,10 @@
     }
 
     for (i=0;i<count;i++) {
-      if (sprites[i])
-        put_overlay_tile_gpixmap(p, 0, 0, sprites[i]);
+      if (sprites[i].sprite)
+        put_overlay_tile_gpixmap(p,
+                                sprites[i].offset_x, sprites[i].offset_y,
+                                sprites[i].sprite);
     }
   }
 
Index: data/isotrident.tilespec
===================================================================
RCS file: /home/freeciv/CVS/freeciv/data/isotrident.tilespec,v
retrieving revision 1.8
diff -u -r1.8 isotrident.tilespec
--- data/isotrident.tilespec    2003/02/02 00:15:53     1.8
+++ data/isotrident.tilespec    2003/07/16 04:34:57
@@ -24,6 +24,10 @@
 ; Use roadstyle 0 (old iso style)
 roadstyle = 0
 
+; offset the flags by this amount when drawing units
+flag_offset_x = 17
+flag_offset_y = 11
+
 ; Font to use to draw city names:
 city_names_font = "9x15bold"
 
@@ -45,7 +49,7 @@
   "isotrident/tiles.spec",
   "isotrident/small.spec",
   "isotrident/units.spec",
-  "isotrident/flags.spec",
+  "trident/flags.spec",
   "misc/buildings.spec",
   "misc/space.spec",
 ;  "misc/techs.spec",

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