Complete.Org: Mailing Lists: Archives: freeciv-dev: July 2005:
[Freeciv-Dev] (PR#13567) a relief layer for the overview
Home

[Freeciv-Dev] (PR#13567) a relief layer for the overview

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
Subject: [Freeciv-Dev] (PR#13567) a relief layer for the overview
From: "Jason Short" <jdorje@xxxxxxxxxxxxxxxxxxxxx>
Date: Sat, 30 Jul 2005 01:12:12 -0700
Reply-to: bugs@xxxxxxxxxxx

<URL: http://bugs.freeciv.org/Ticket/Display.html?id=13567 >

This patch adds a relief layer for the overview.  It is best
demonstrated with a screenshot.  This one has just the relief layer
enabled (all others turned off):

  http://freeciv.org/~jdorje/relief.png

A few caveats:

- Terrain colors are put in a MAX_NUM_TERRAINS (200) sized array.  This
is wasteful but the struct is pretty small.

- Because terrains aren't known until the ruleset is received, but the
tilespec file is closed by this time, we have to make a hash of terrain
colors.  When terrains are received this hash is converted into the
array.  This is basically the way all of tilespec.c works, although I
imagine we could do better.

- I made up the colors on the spot, and I'm not an artist.  For the
"flat" terrains, I opened up amplio and took a color picker to the
terrains.  For jungle/forest/swamp I did the same thing but changed the
green-ish colors to be different; these could use some work.  For hills
and mountains I used a brown->red scale (like a hightmap).  These could
all use some improvement.  See data/misc/colors.tilespec.

Again the idea/design is basically Egor's.

-jason

Index: client/colors_common.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/colors_common.c,v
retrieving revision 1.6
diff -p -u -r1.6 colors_common.c
--- client/colors_common.c      7 Jun 2005 16:18:53 -0000       1.6
+++ client/colors_common.c      30 Jul 2005 08:05:39 -0000
@@ -17,6 +17,7 @@
 
 #include <assert.h>
 
+#include "hash.h"
 #include "log.h"
 #include "shared.h"
 
@@ -40,6 +41,13 @@ struct color_system {
 
   int num_player_colors;
   struct rgbcolor *player_colors;
+
+  /* Terrain colors: we have one color per terrain.  These are stored in a
+   * larger-than-necessary array.  There's also a hash that is used to store
+   * all colors; this is created when the tileset toplevel is read and later
+   * used when the rulesets are received. */
+  struct hash_table *terrain_hash;
+  struct rgbcolor terrain_colors[MAX_NUM_TERRAINS];
 };
 
 char *color_names[] = {
@@ -130,10 +138,53 @@ struct color_system *color_system_read(s
     }
   }
 
+  for (i = 0; i < ARRAY_SIZE(colors->terrain_colors); i++) {
+    struct rgbcolor *rgb = &colors->terrain_colors[i];
+
+    rgb->r = rgb->g = rgb->b = 0;
+    rgb->color = NULL;
+  }
+  colors->terrain_hash = hash_new(hash_fval_string, hash_fcmp_string);
+  for (i = 0; ; i++) {
+    struct rgbcolor *rgb;
+    char *key;
+
+    if (!section_file_lookup(file, "colors.terrains%d.r", i)) {
+      break;
+    }
+    rgb = fc_malloc(sizeof(*rgb));
+    rgb->r = secfile_lookup_int(file, "colors.terrains%d.r", i);
+    rgb->g = secfile_lookup_int(file, "colors.terrains%d.g", i);
+    rgb->b = secfile_lookup_int(file, "colors.terrains%d.b", i);
+    rgb->color = NULL;
+    key = secfile_lookup_str(file, "colors.terrains%d.terrain", i);
+
+    if (!hash_insert(colors->terrain_hash, mystrdup(key), rgb)) {
+      freelog(LOG_ERROR, "warning: already have a color for %s", key);
+    }
+  }
+
   return colors;
 }
 
 /****************************************************************************
+  Called when terrain info is received from the server.
+****************************************************************************/
+void color_system_setup_terrain(struct color_system *colors,
+                               const struct terrain *pterrain)
+{
+  struct rgbcolor *rgb
+    = hash_lookup_data(colors->terrain_hash, pterrain->terrain_name);
+
+  if (rgb) {
+    colors->terrain_colors[pterrain->index] = *rgb;
+  } else {
+    freelog(LOG_ERROR, "No color for terrain '%s'", pterrain->terrain_name);
+    /* Fallback: the color remains black. */
+  }
+}
+
+/****************************************************************************
   Called when the client first starts to free any allocated colors.
 ****************************************************************************/
 void color_system_free(struct color_system *colors)
@@ -151,6 +202,17 @@ void color_system_free(struct color_syst
     }
   }
   free(colors->player_colors);
+  for (i = 0; i < ARRAY_SIZE(colors->terrain_colors); i++) {
+    if (colors->terrain_colors[i].color) {
+      color_free(colors->player_colors[i].color);
+    }
+  }
+  while (hash_num_entries(colors->terrain_hash) > 0) {
+    const char *key = hash_key_by_number(colors->terrain_hash, 0);
+
+    hash_delete_entry(colors->terrain_hash, key);
+    free((void *)key);
+  }
   free(colors);
 }
 
@@ -197,3 +259,22 @@ struct color *get_player_color(const str
     return NULL;
   }
 }
+
+/****************************************************************************
+  Return a pointer to the given "terrain" color.
+
+  Each terrain has a color associated.  This is usually used to draw the
+  overview.
+****************************************************************************/
+struct color *get_terrain_color(const struct tileset *t,
+                               const struct terrain *pterrain)
+{
+  if (pterrain) {
+    struct color_system *colors = get_color_system(t);
+
+    return ensure_color(&colors->terrain_colors[pterrain->index]);
+  } else {
+    assert(0);
+    return NULL;
+  }
+}
Index: client/colors_common.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/colors_common.h,v
retrieving revision 1.6
diff -p -u -r1.6 colors_common.h
--- client/colors_common.h      7 Jun 2005 16:18:53 -0000       1.6
+++ client/colors_common.h      30 Jul 2005 08:05:39 -0000
@@ -69,9 +69,13 @@ enum color_std {
 struct color *get_color(const struct tileset *t, enum color_std color);
 struct color *get_player_color(const struct tileset *t,
                               const struct player *pplayer);
+struct color *get_terrain_color(const struct tileset *t,
+                               const struct terrain *pterrain);
 
 /* Functions used by the tileset to allocate the color system. */
 struct color_system *color_system_read(struct section_file *file);
+void color_system_setup_terrain(struct color_system *colors,
+                               const struct terrain *pterrain);
 void color_system_free(struct color_system *colors);
 
 #endif /* FC__COLORS_COMMON_H */
Index: client/options.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/options.c,v
retrieving revision 1.135
diff -p -u -r1.135 options.c
--- client/options.c    30 Jul 2005 06:39:37 -0000      1.135
+++ client/options.c    30 Jul 2005 08:05:39 -0000
@@ -223,6 +223,10 @@ static client_option common_options[] = 
                  N_("Background layer"),
                  N_("The background layer of the overview shows ocean, "
                     "land, and fog."), COC_OVERVIEW),
+  GEN_BOOL_OPTION(overview.layers[OLAYER_RELIEF],
+                 N_("Terrain relief map layer"),
+                 N_("The relief layer shows all terrains on the map."),
+                 COC_OVERVIEW),
   GEN_BOOL_OPTION(overview.layers[OLAYER_BORDERS],
                  N_("Borders layer"),
                  N_("The borders layer of the overview shows which tiles "
Index: client/overview_common.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/overview_common.c,v
retrieving revision 1.14
diff -p -u -r1.14 overview_common.c
--- client/overview_common.c    30 Jul 2005 06:39:37 -0000      1.14
+++ client/overview_common.c    30 Jul 2005 08:05:39 -0000
@@ -141,6 +141,9 @@ static struct color *overview_tile_color
       return get_player_color(tileset, owner);
     }
   }
+  if (overview.layers[OLAYER_RELIEF] && ptile->terrain != T_UNKNOWN) {
+    return get_terrain_color(tileset, ptile->terrain);
+  }
   if (overview.layers[OLAYER_BACKGROUND] && ptile->terrain != T_UNKNOWN) {
     if (is_ocean(ptile->terrain)) {
       if (client_tile_get_known(ptile) == TILE_KNOWN_FOGGED
Index: client/overview_common.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/overview_common.h,v
retrieving revision 1.5
diff -p -u -r1.5 overview_common.h
--- client/overview_common.h    30 Jul 2005 06:39:37 -0000      1.5
+++ client/overview_common.h    30 Jul 2005 08:05:39 -0000
@@ -20,6 +20,7 @@
 
 enum overview_layers {
   OLAYER_BACKGROUND,
+  OLAYER_RELIEF,
   OLAYER_BORDERS,
   OLAYER_UNITS,
   OLAYER_CITIES,
Index: client/tilespec.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/tilespec.c,v
retrieving revision 1.318
diff -p -u -r1.318 tilespec.c
--- client/tilespec.c   24 Jul 2005 00:19:29 -0000      1.318
+++ client/tilespec.c   30 Jul 2005 08:05:43 -0000
@@ -2594,6 +2594,8 @@ void tileset_setup_tile_type(struct tile
   }
 
   t->sprites.terrain[pterrain->index] = draw;
+
+  color_system_setup_terrain(t->color_system, pterrain);
 }
 
 /**********************************************************************
Index: common/fc_types.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/fc_types.h,v
retrieving revision 1.30
diff -p -u -r1.30 fc_types.h
--- common/fc_types.h   28 Jul 2005 17:59:06 -0000      1.30
+++ common/fc_types.h   30 Jul 2005 08:05:43 -0000
@@ -78,6 +78,7 @@ struct connection;
 struct government;
 struct nation_type;
 struct player;
+struct terrain;
 struct tile;
 struct unit;
 struct impr_type;
Index: data/misc/colors.tilespec
===================================================================
RCS file: /home/freeciv/CVS/freeciv/data/misc/colors.tilespec,v
retrieving revision 1.2
diff -p -u -r1.2 colors.tilespec
--- data/misc/colors.tilespec   7 Jun 2005 16:18:54 -0000       1.2
+++ data/misc/colors.tilespec   30 Jul 2005 08:05:46 -0000
@@ -18,6 +18,20 @@ player = {"r", "g", "b"
   198, 198, 198  ; race13
 }
 
+terrains = {"r", "g", "b", "terrain"
+  255, 255, 255, "Glacier"
+   10, 123,   2, "Grassland"
+  138, 168,  60, "Plains"
+   74,  74,  74, "Tundra"
+   44,  64,  44, "Swamp"
+  212, 179, 101, "Desert"
+   54, 162,  38, "Jungle"
+   43, 107,  19, "Forest"
+  142, 121,  63, "Hills"
+  167,  77,  38, "Mountains"
+    0,   0, 200, "Ocean"
+}
+
 ; Mapview
 mapview_unknown = {"r", "g", "b"
     0,     0,   0
@@ -63,6 +77,7 @@ overview_enemyunit = {"r", "g", "b"
     255,   0,   0
 }
 overview_ocean = {"r", "g", "b"
+; Generic ocean, not the same as the Ocean terrain (see "terrains" above)
     0,     0, 200
 }
 overview_foggedocean = {"r", "g", "b"

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