Complete.Org: Mailing Lists: Archives: freeciv-dev: July 2004:
[Freeciv-Dev] Re: (PR#9479) some fs stuff (fwd)
Home

[Freeciv-Dev] Re: (PR#9479) some fs stuff (fwd)

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
To: undisclosed-recipients: ;
Subject: [Freeciv-Dev] Re: (PR#9479) some fs stuff (fwd)
From: "Per I. Mathisen" <per@xxxxxxxxxxx>
Date: Fri, 30 Jul 2004 12:40:19 -0700
Reply-to: rt@xxxxxxxxxxx

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

And here is the remaining common client code (apart from text.c|h
changes).  The diff is not so big anymore.

  - Per

Index: client/control.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/control.c,v
retrieving revision 1.138
diff -u -r1.138 control.c
--- client/control.c    20 Jul 2004 10:13:06 -0000      1.138
+++ client/control.c    30 Jul 2004 19:37:24 -0000
@@ -160,6 +160,7 @@
 
   update_unit_info_label(punit);
   update_menus();
+  if(punit) set_focus_tile(punit->x, punit->y);
 }
 
 /**************************************************************************
@@ -238,6 +239,14 @@
     candidate = find_best_focus_candidate(FALSE);
   }
 
+#if 0
+  /* We have to do this ourselves, and not rely on set_unit_focus(),
+   * because above we change punit_focus directly.
+   */
+  if(punit_old_focus && punit_old_focus!=punit_focus)
+    refresh_tile_mapcanvas(punit_old_focus->x, punit_old_focus->y, FALSE);
+#endif
+
   /* Accept current focus unit as last resort. */
   if (!candidate) {
     candidate = find_best_focus_candidate(TRUE);
Index: client/mapview_common.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/mapview_common.c,v
retrieving revision 1.138
diff -u -r1.138 mapview_common.c
--- client/mapview_common.c     26 Jul 2004 04:05:58 -0000      1.138
+++ client/mapview_common.c     30 Jul 2004 19:37:24 -0000
@@ -32,12 +32,15 @@
 #include "climap.h"
 #include "control.h"
 #include "goto.h"
-#include "mapview_common.h"
 #include "tilespec.h"
 
+#include "mapview_common.h"
+
 struct mapview_canvas mapview_canvas;
 struct overview overview;
 
+static struct map_position focus_tile = { -1, -1 };
+
 /* Arbitrary estimated maximums for width and height of a city description
  * text.  Eventually this may be determined dynamically. */
 #define MAX_CITY_DESC_WIDTH 128
@@ -52,6 +55,29 @@
 static void base_canvas_to_map_pos(int *map_x, int *map_y,
                                   int canvas_x, int canvas_y);
 static void center_tile_overviewcanvas(int map_x, int map_y);
+
+static void get_mapview_corners(int x[4], int y[4]);
+
+void set_focus_tile(int x, int y)
+{
+  struct map_position old = focus_tile;
+
+  assert(is_real_map_pos(x, y));
+  focus_tile.x = x;
+  focus_tile.y = y;
+
+  if (is_real_map_pos(old.x, old.x)) {
+    refresh_tile_mapcanvas(old.x, old.y, TRUE);
+  }
+  refresh_tile_mapcanvas(focus_tile.x, focus_tile.y, TRUE);
+}
+
+void get_focus_tile(int *x, int *y)
+{
+    *x=focus_tile.x;
+    *y=focus_tile.y;
+}
+
 static void get_mapview_corners(int x[4], int y[4]);
 static void redraw_overview(void);
 static void dirty_overview(void);
@@ -787,6 +813,53 @@
   }
 }
 
+void put_terrain(int x, int y, struct canvas *pcanvas,
+                int canvas_x, int canvas_y)
+{
+  struct drawn_sprite drawn_sprites[40];
+  int count = fill_terrain_sprite_array(drawn_sprites, x, y);
+  int i;
+  int unit_width = UNIT_TILE_WIDTH;
+  int unit_height = UNIT_TILE_HEIGHT;
+  int unit_offset_x = 0;
+  int unit_offset_y = 0;
+
+  for (i = 0; i < count; i++) {
+    if (drawn_sprites[i].sprite) {
+      int ox = drawn_sprites[i].offset_x, oy = drawn_sprites[i].offset_y;
+
+      canvas_put_sprite(pcanvas, canvas_x + ox, canvas_y + oy,
+                    drawn_sprites[i].sprite,
+                    unit_offset_x - ox, unit_offset_y - oy,
+                    unit_width - ox, unit_height - oy);
+    }
+  }
+}
+
+void put_city(struct city *pcity, struct canvas *pcanvas,
+             int canvas_x, int canvas_y)
+{
+  struct drawn_sprite drawn_sprites[40];
+  bool solid_bg;
+  int count = fill_city_sprite_array(drawn_sprites, pcity, &solid_bg);
+  int i;
+  int unit_width = UNIT_TILE_WIDTH;
+  int unit_height = UNIT_TILE_HEIGHT;
+  int unit_offset_x = 0;
+  int unit_offset_y = 0;
+
+  for (i = 0; i < count; i++) {
+    if (drawn_sprites[i].sprite) {
+      int ox = drawn_sprites[i].offset_x, oy = drawn_sprites[i].offset_y;
+
+      canvas_put_sprite(pcanvas, canvas_x + ox, canvas_y + oy,
+                    drawn_sprites[i].sprite,
+                    unit_offset_x - ox, unit_offset_y - oy,
+                    unit_width - ox, unit_height - oy);
+    }
+  }
+}
+
 /**************************************************************************
   Draw the given unit onto the canvas store at the given location.
 **************************************************************************/
@@ -1361,6 +1434,43 @@
   }
 }
 
+#ifdef NEVER
+static void tile_draw_focus(struct canvas *pcanvas,
+                           int map_x, int map_y,
+                           int canvas_x, int canvas_y,
+                           bool citymode)
+{
+  const int inset = (is_isometric ? 0 : 1);
+  enum direction8 dir;
+
+  if (citymode) {
+    return;
+  }
+
+  for (dir = 0; dir < 8; dir++) {
+    int start_x, start_y, end_x, end_y, adjc_x, adjc_y;
+
+    /* In non-iso view we draw the rectangle with an inset of 1.  This makes
+     * it easy to distinguish from the map grid.
+     *
+     * In iso-view the inset doesn't work perfectly (see comments about
+     * this elsewhere) so we draw without an inset.  This may cover up the
+     * map grid if it is drawn. */
+    if (get_tile_boundaries(dir, inset, 1, &start_x, &start_y, 
+                            &end_x, &end_y)) {
+
+    /** Focus tile **/
+    if ((map_x == focus_tile.x && map_y == focus_tile.y)
+       || (is_isometric && MAPSTEP(adjc_x, adjc_y, map_x, map_y, dir)
+           && (map_x == focus_tile.x && map_y == focus_tile.y))) {
+      canvas_put_line(pcanvas, COLOR_STD_RED, LINE_NORMAL,
+                     canvas_x + start_x, canvas_y + start_y,
+                     end_x - start_x, end_y - start_y);
+      }
+    }
+  }
+}
+#endif
 
 /****************************************************************************
    Draw the grid lines of the given map tile at the given canvas position
@@ -1619,6 +1729,11 @@
 {
   const int dx = max_desc_width - NORMAL_TILE_WIDTH, dy = max_desc_height;
 
+  canvas_x = 0;
+  canvas_y = 0;
+  width = mapview_canvas.width;
+  height = mapview_canvas.height;
+  
   if (!draw_city_names && !draw_city_productions) {
     return;
   }
Index: client/mapview_common.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/mapview_common.h,v
retrieving revision 1.72
diff -u -r1.72 mapview_common.h
--- client/mapview_common.h     26 Jul 2004 04:05:58 -0000      1.72
+++ client/mapview_common.h     30 Jul 2004 19:37:24 -0000
@@ -22,8 +22,9 @@
 #include "tilespec.h"
 
 struct unit;
+struct city;
 
-struct canvas_store;           /* opaque type, real type is gui-dep */
+struct canvas;         /* opaque type, real type is gui-dep */
 
 struct mapview_canvas {
   int gui_x0, gui_y0;
@@ -147,6 +148,10 @@
              int unit_width, int unit_height);
 void put_unit_full(struct unit *punit, struct canvas *pcanvas,
                   int canvas_x, int canvas_y);
+void put_terrain(int x, int y, struct canvas *pcanvas,
+                int canvas_x, int canvas_y);
+void put_city(struct city *pcity, struct canvas *pcanvas,
+             int canvas_x, int canvas_y);
 
 void put_city_tile_output(struct city *pcity, int city_x, int city_y,
                          struct canvas *pcanvas,
@@ -201,7 +206,8 @@
                         int map_x, int map_y);
 void overview_to_map_pos(int *map_x, int *map_y,
                         int overview_x, int overview_y);
-
+void set_focus_tile(int x, int y);
+void get_focus_tile(int *x, int *y);
 void refresh_overview_canvas(void);
 void overview_update_tile(int x, int y);
 void set_overview_dimensions(int width, int height);
Index: client/tilespec.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/tilespec.c,v
retrieving revision 1.192
diff -u -r1.192 tilespec.c
--- client/tilespec.c   28 Jul 2004 16:45:03 -0000      1.192
+++ client/tilespec.c   30 Jul 2004 19:37:25 -0000
@@ -1882,6 +1882,62 @@
 #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)
 
+/**********************************************************************
+  Fill in the sprite array for the city
+***********************************************************************/
+int fill_city_sprite_array(struct drawn_sprite *sprs,
+                          struct city *pcity, bool *solid_bg)
+{
+  struct drawn_sprite *save_sprs = sprs;
+
+  *solid_bg = FALSE;
+
+  if (!solid_color_behind_units) {
+    ADD_SPRITE(get_city_nation_flag_sprite(pcity), DRAW_FULL, TRUE,
+              flag_offset_x, flag_offset_y);
+  } else {
+    *solid_bg = TRUE;
+  }
+
+  if (pcity->client.occupied) {
+    ADD_SPRITE_SIMPLE(get_city_occupied_sprite(pcity));
+  }
+
+  ADD_SPRITE_SIMPLE(get_city_sprite(pcity));
+
+  if (city_got_citywalls(pcity)) {
+    ADD_SPRITE_SIMPLE(get_city_wall_sprite(pcity));
+  }
+
+  if (map_has_special(pcity->x, pcity->y, S_POLLUTION)) {
+    ADD_SPRITE_SIMPLE(sprites.tx.pollution);
+  }
+  if (map_has_special(pcity->x, pcity->y, S_FALLOUT)) {
+    ADD_SPRITE_SIMPLE(sprites.tx.fallout);
+  }
+
+  if (pcity->client.unhappy) {
+    ADD_SPRITE_SIMPLE(sprites.city.disorder);
+  }
+
+  if (tile_get_known(pcity->x, pcity->y) == TILE_KNOWN_FOGGED
+      && draw_fog_of_war) {
+    ADD_SPRITE_SIMPLE(sprites.tx.fog);
+  }
+
+  /* Put the size sprites last, so that they are not obscured
+   * (and because they can be hard to read if fogged).
+   */
+  if (pcity->size >= 10) {
+    assert(pcity->size < 100);
+    ADD_SPRITE_SIMPLE(sprites.city.size_tens[pcity->size / 10]);
+  }
+
+  ADD_SPRITE_SIMPLE(sprites.city.size[pcity->size % 10]);
+
+  return sprs - save_sprs;
+}
+
 /**************************************************************************
   Assemble some data that is used in building the tile sprite arrays.
     (map_x, map_y) : the (normalized) map position
@@ -2427,7 +2483,7 @@
   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,
+static int fill_terrain_sprite_array0(struct drawn_sprite *sprs,
                                     int map_x, int map_y,
                                     enum tile_terrain_type *ttype_near)
 {
@@ -2640,15 +2696,12 @@
   build_tile_data(map_x, map_y,
                  &ttype, &tspecial, ttype_near, tspecial_near);
 
-  /* Terrain and specials. */
-  if (!unit_only && !city_only) {
-    sprs += fill_terrain_sprite_array(sprs, map_x, map_y, ttype_near);
+  sprs += fill_terrain_sprite_array0(sprs, map_x, map_y, ttype_near);
 
-    if (is_ocean(ttype) && draw_terrain) {
-      for (dir = 0; dir < 4; dir++) {
-       if (contains_special(tspecial_near[DIR4_TO_DIR8[dir]], S_RIVER)) {
-         ADD_SPRITE_SIMPLE(sprites.tx.river_outlet[dir]);
-       }
+  if (is_ocean(ttype) && draw_terrain) {
+    for (dir = 0; dir < 4; dir++) {
+      if (contains_special(tspecial_near[DIR4_TO_DIR8[dir]], S_RIVER)) {
+       ADD_SPRITE_SIMPLE(sprites.tx.river_outlet[dir]);
       }
     }
 
@@ -2751,13 +2804,103 @@
               FALSE, 0, 0);
   }
 
-  if (punit && !city_only
-      && (draw_units || (punit == pfocus && draw_focus_unit))) {
+  if (punit && (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;
+    bool backdrop = !pcity;
+
+    sprs += fill_unit_sprite_array(sprs, punit, solid_bg, stacked, backdrop);
+  }
+
+  if (draw_fortress_airbase && contains_special(tspecial, S_FORTRESS)) {
+    ADD_SPRITE_FULL(sprites.tx.fortress);
+  }
+
+  return sprs - save_sprs;
+}
+
+int fill_terrain_sprite_array(struct drawn_sprite *sprs, int x, int y)
+{
+  enum tile_terrain_type ttype, ttype_near[8];
+  enum tile_special_type tspecial, tspecial_near[8];
+  struct drawn_sprite *save_sprs = sprs;
+
+  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_array0(sprs, x, y, ttype_near);
+  return sprs - save_sprs;
+}
+
+/**********************************************************************
+  Fill in the sprite array for the tile at position (abs_x0,abs_y0)
+
+The sprites are drawn in the following order:
+ 1) basic terrain type
+ 2) river
+ 3) irritation
+ 4) road/railroad
+ 5) specials
+ 6) mine
+ 7) hut
+ 8) fortress
+ 9) airbase
+10) pollution
+11) fallout
+12) FoW
+***********************************************************************/
+#if 0
+int fill_tile_sprite_array(struct drawn_sprite *sprs, int abs_x0, int abs_y0,
+                          bool citymode, bool *solid_bg,
+                          enum color_std *bg_color)
+{
+  enum tile_terrain_type ttype, ttype_near[8];
+  enum tile_special_type tspecial, tspecial_near[8];
+  int dir, tileno;
+  struct tile *ptile;
+  struct city *pcity;
+  struct unit *pfocus;
+  struct unit *punit;
+  struct drawn_sprite *save_sprs = sprs;
+
+  *solid_bg = FALSE;
+  *bg_color = COLOR_STD_BACKGROUND;
+
+  ptile=map_get_tile(abs_x0, abs_y0);
+
+  if (tile_get_known(abs_x0, abs_y0) == TILE_UNKNOWN) {
+    return 0;
+  }
+
+  pcity=map_get_city(abs_x0, abs_y0);
+  pfocus=get_unit_in_focus();
 
-    sprs += fill_unit_sprite_array(sprs, punit, &dummy, stacked, backdrop);
+  if (solid_color_behind_units) {
+    punit = get_drawable_unit(abs_x0, abs_y0, citymode);
+    if (punit && (draw_units || (draw_focus_unit && pfocus == punit))) {
+      bool stacked = (unit_list_size(&ptile->units) > 1);
+
+      sprs += fill_unit_sprite_array(sprs, punit, solid_bg,
+                                    stacked, TRUE);
+
+      *bg_color = player_color(unit_owner(punit));
+      return sprs - save_sprs;
+    }
+
+    if (pcity && draw_cities) {
+      sprs += fill_city_sprite_array(sprs, pcity, solid_bg);
+      *bg_color = player_color(city_owner(pcity));
+      return sprs - save_sprs;
+    }
+  }
+  build_tile_data(abs_x0, abs_y0, 
+                 &ttype, &tspecial, ttype_near, tspecial_near);
+
+  sprs += fill_terrain_sprite_array0(sprs, abs_x0, abs_y0, ttype_near);
+
+  if (!draw_terrain) {
+    *solid_bg = TRUE;
   }
 
   if (!unit_only && !city_only) {
@@ -2777,6 +2920,7 @@
 
   return sprs - save_sprs;
 }
+#endif
 
 /**********************************************************************
   Set city tiles sprite values; should only happen after
Index: client/tilespec.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/tilespec.h,v
retrieving revision 1.82
diff -u -r1.82 tilespec.h
--- client/tilespec.h   28 Jul 2004 16:45:03 -0000      1.82
+++ client/tilespec.h   30 Jul 2004 19:37:25 -0000
@@ -72,6 +72,12 @@
                           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);
+int fill_city_sprite_array_iso(struct drawn_sprite *sprs,
+                              struct city *pcity);
+int fill_terrain_sprite_array(struct drawn_sprite *sprs, int abs_x0,
+                             int abs_y0);
+int fill_city_sprite_array(struct drawn_sprite *sprs,
+                          struct city *pcity, bool *solid_bg);
 
 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]