Complete.Org: Mailing Lists: Archives: freeciv-dev: July 2004:
[Freeciv-Dev] (PR#9379) hex tilesets and rivers
Home

[Freeciv-Dev] (PR#9379) hex tilesets and rivers

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
To: jdorje@xxxxxxxxxxx
Subject: [Freeciv-Dev] (PR#9379) hex tilesets and rivers
From: "Jason Short" <jdorje@xxxxxxxxxxxxxxxxxxxxx>
Date: Thu, 15 Jul 2004 08:59:45 -0700
Reply-to: rt@xxxxxxxxxxx

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

This patch fixes a small problem.  NUM_DIRECTION_CARDINAL was 64 which
is the maximum value it can be.  However when iterating we only want to
go over the number of indices that this tileset uses.  So I renamed
NUM_DIRECTION_CARDINAL as MAX_INDEX_CARDINAL and added a variable
num_index_cardinal.

jason

Index: client/tilespec.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/tilespec.c,v
retrieving revision 1.183
diff -u -r1.183 tilespec.c
--- client/tilespec.c   13 Jul 2004 18:16:53 -0000      1.183
+++ client/tilespec.c   15 Jul 2004 15:58:36 -0000
@@ -88,6 +88,10 @@
 #define NUM_CORNER_DIRS 4
 #define TILES_PER_CORNER 4
 
+static int num_valid_tileset_dirs, num_cardinal_tileset_dirs;
+static int num_index_valid, num_index_cardinal;
+static enum direction8 valid_tileset_dirs[8], cardinal_tileset_dirs[8];
+
 static struct {
   enum match_style match_style;
   int count;
@@ -197,6 +201,64 @@
                                            bool required, const char *what,
                                            const char *name);
 
+/**************************************************************************
+  Return the tileset name of the direction.  This is similar to
+  dir_get_name but you shouldn't change this or all tilesets will break.
+**************************************************************************/
+static const char *dir_get_tileset_name(enum direction8 dir)
+{
+  switch (dir) {
+  case DIR8_NORTH:
+    return "n";
+  case DIR8_NORTHEAST:
+    return "ne";
+  case DIR8_EAST:
+    return "e";
+  case DIR8_SOUTHEAST:
+    return "se";
+  case DIR8_SOUTH:
+    return "s";
+  case DIR8_SOUTHWEST:
+    return "sw";
+  case DIR8_WEST:
+    return "w";
+  case DIR8_NORTHWEST:
+    return "nw";
+  }
+  assert(0);
+  return "";
+}
+
+/****************************************************************************
+  Return TRUE iff the dir is valid in this tileset.
+****************************************************************************/
+static bool is_valid_tileset_dir(enum direction8 dir)
+{
+  if (hex_width > 0) {
+    return dir != DIR8_NORTHEAST && dir != DIR8_SOUTHWEST;
+  } else if (hex_height > 0) {
+    return dir != DIR8_NORTHWEST && dir != DIR8_SOUTHEAST;
+  } else {
+    return TRUE;
+  }
+}
+
+/****************************************************************************
+  Return TRUE iff the dir is cardinal in this tileset.
+
+  "Cardinal", in this sense, means that a tile will share a border with
+  another tile in the direction rather than sharing just a single vertex.
+****************************************************************************/
+static bool is_cardinal_tileset_dir(enum direction8 dir)
+{
+  if (hex_width > 0 || hex_height > 0) {
+    return is_valid_tileset_dir(dir);
+  } else {
+    return (dir == DIR8_NORTH || dir == DIR8_EAST
+           || dir == DIR8_SOUTH || dir == DIR8_WEST);
+  }
+}
+
 /**********************************************************************
   Returns a static list of tilesets available on the system by
   searching all data directories for files matching TILESPEC_SUFFIX.
@@ -687,6 +749,7 @@
   char **spec_filenames, **terrains;
   char *file_capstr;
   bool duplicates_ok, is_hex;
+  enum direction8 dir;
 
   fname = tilespec_fullname(tileset_name);
   freelog(LOG_VERBOSE, "tilespec file is %s", fname);
@@ -738,6 +801,27 @@
     return tilespec_read_toplevel(NULL);
   }
 
+  /* Create arrays of valid and cardinal tileset dirs.  These depend
+   * entirely on the tileset, not the topology.  They are also in clockwise
+   * rotational ordering. */
+  num_valid_tileset_dirs = num_cardinal_tileset_dirs = 0;
+  num_index_valid = num_index_cardinal = 2;
+  dir = DIR8_NORTH;
+  do {
+    if (is_valid_tileset_dir(dir)) {
+      valid_tileset_dirs[num_valid_tileset_dirs] = dir;
+      num_index_valid *= 2;
+      num_valid_tileset_dirs++;
+    }
+    if (is_cardinal_tileset_dir(dir)) {
+      cardinal_tileset_dirs[num_cardinal_tileset_dirs] = dir;
+      num_index_cardinal *= 2;
+      num_cardinal_tileset_dirs++;
+    }
+
+    dir = dir_cw(dir);
+  } while (dir != DIR8_NORTH);
+
   NORMAL_TILE_WIDTH = secfile_lookup_int(file, "tilespec.normal_tile_width");
   NORMAL_TILE_HEIGHT = secfile_lookup_int(file, "tilespec.normal_tile_height");
   if (is_isometric) {
@@ -1006,6 +1090,27 @@
 }
 
 /****************************************************************************
+  Return a directional string for the cardinal directions.  Normally the
+  binary value 1000 will be converted into "n1e0s0w0".  This is in a
+  clockwise ordering.
+****************************************************************************/
+static const char *cardinal_str(int idx)
+{
+  static char c[64];
+  int i;
+
+  c[0] = '\0';
+  for (i = 0; i < num_cardinal_tileset_dirs; i++) {
+    int value = (idx >> i) & 1;
+
+    snprintf(c + strlen(c), sizeof(c) - strlen(c), "%s%d",
+            dir_get_tileset_name(cardinal_tileset_dirs[i]), value);
+  }
+
+  return c;
+}
+
+/****************************************************************************
   Do the same thing as nsew_str, except including all the cardinal and 
   diagonal directions.
   The returned string is a pointer to static memory.
@@ -1314,8 +1419,8 @@
   SET_SPRITE(tx.airbase,    "tx.airbase");
   SET_SPRITE(tx.fog,        "tx.fog");
 
-  for(i=0; i<NUM_DIRECTION_NSEW; i++) {
-    my_snprintf(buffer, sizeof(buffer), "tx.s_river_%s", nsew_str(i));
+  for (i = 0; i < num_index_cardinal; i++) {
+    my_snprintf(buffer, sizeof(buffer), "tx.s_river_%s", cardinal_str(i));
     SET_SPRITE(tx.spec_river[i], buffer);
   }
 
@@ -2543,19 +2648,18 @@
                                         pcity);
 
     if (draw_terrain && contains_special(tspecial, S_RIVER)) {
+      int i;
+
       /* Draw rivers on top of irrigation. */
-      tileno = INDEX_NSEW((contains_special(tspecial_near[DIR8_NORTH],
-                                           S_RIVER)
-                          || is_ocean(ttype_near[DIR8_NORTH])),
-                         (contains_special(tspecial_near[DIR8_SOUTH],
-                                           S_RIVER)
-                          || is_ocean(ttype_near[DIR8_SOUTH])),
-                         (contains_special(tspecial_near[DIR8_EAST],
-                                           S_RIVER)
-                          || is_ocean(ttype_near[DIR8_EAST])),
-                         (contains_special(tspecial_near[DIR8_WEST],
-                                           S_RIVER)
-                          || is_ocean(ttype_near[DIR8_WEST])));
+      tileno = 0;
+      for (i = 0; i < num_cardinal_tileset_dirs; i++) {
+       enum direction8 dir = cardinal_tileset_dirs[i];
+
+       if (contains_special(tspecial_near[dir], S_RIVER)
+           || is_ocean(ttype_near[dir])) {
+         tileno |= 1 << i;
+       }
+      }
       ADD_SPRITE_SIMPLE(sprites.tx.spec_river[tileno]);
     }
   
Index: client/tilespec.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/tilespec.h,v
retrieving revision 1.75
diff -u -r1.75 tilespec.h
--- client/tilespec.h   10 Jul 2004 18:48:17 -0000      1.75
+++ client/tilespec.h   15 Jul 2004 15:58:36 -0000
@@ -81,8 +81,8 @@
 
 
 /* This the way directional indices are now encoded: */
-
 #define NUM_DIRECTION_NSEW             16
+#define MAX_INDEX_CARDINAL             64
 #define NUM_DIRECTION_CW               256
 
 #define BIT_NORTH (0x01)
@@ -269,7 +269,7 @@
       *airbase,
       *fallout,
       *fog,
-      *spec_river[NUM_DIRECTION_NSEW],
+      *spec_river[MAX_INDEX_CARDINAL],
       *darkness[NUM_DIRECTION_NSEW],         /* first unused */
       *river_outlet[4],                /* indexed by enum direction4 */
       /* for non-isometric */
Index: data/isotrident/terrain2.spec
===================================================================
RCS file: /home/freeciv/CVS/freeciv/data/isotrident/terrain2.spec,v
retrieving revision 1.4
diff -u -r1.4 terrain2.spec
--- data/isotrident/terrain2.spec       4 May 2004 18:22:02 -0000       1.4
+++ data/isotrident/terrain2.spec       15 Jul 2004 15:58:37 -0000
@@ -25,22 +25,22 @@
 ; Rivers (as special type), and whether north, south, east, west 
 ; also has river or is ocean:
 
- 2,  0, "tx.s_river_n0s0e0w0"
- 2,  1, "tx.s_river_n1s0e0w0"
- 2,  2, "tx.s_river_n0s0e1w0"
- 2,  3, "tx.s_river_n1s0e1w0"
- 2,  4, "tx.s_river_n0s1e0w0"
- 2,  5, "tx.s_river_n1s1e0w0"
- 2,  6, "tx.s_river_n0s1e1w0"
- 2,  7, "tx.s_river_n1s1e1w0"
- 3,  0, "tx.s_river_n0s0e0w1"
- 3,  1, "tx.s_river_n1s0e0w1"
- 3,  2, "tx.s_river_n0s0e1w1"
- 3,  3, "tx.s_river_n1s0e1w1"
- 3,  4, "tx.s_river_n0s1e0w1"
- 3,  5, "tx.s_river_n1s1e0w1"
- 3,  6, "tx.s_river_n0s1e1w1"
- 3,  7, "tx.s_river_n1s1e1w1"
+ 2,  0, "tx.s_river_n0e0s0w0"
+ 2,  1, "tx.s_river_n1e0s0w0"
+ 2,  2, "tx.s_river_n0e1s0w0"
+ 2,  3, "tx.s_river_n1e1s0w0"
+ 2,  4, "tx.s_river_n0e0s1w0"
+ 2,  5, "tx.s_river_n1e0s1w0"
+ 2,  6, "tx.s_river_n0e1s1w0"
+ 2,  7, "tx.s_river_n1e1s1w0"
+ 3,  0, "tx.s_river_n0e0s0w1"
+ 3,  1, "tx.s_river_n1e0s0w1"
+ 3,  2, "tx.s_river_n0e1s0w1"
+ 3,  3, "tx.s_river_n1e1s0w1"
+ 3,  4, "tx.s_river_n0e0s1w1"
+ 3,  5, "tx.s_river_n1e0s1w1"
+ 3,  6, "tx.s_river_n0e1s1w1"
+ 3,  7, "tx.s_river_n1e1s1w1"
 
 ; Rivers as overlay
 
Index: data/trident/tiles.spec
===================================================================
RCS file: /home/freeciv/CVS/freeciv/data/trident/tiles.spec,v
retrieving revision 1.17
diff -u -r1.17 tiles.spec
--- data/trident/tiles.spec     29 Jun 2004 05:39:52 -0000      1.17
+++ data/trident/tiles.spec     15 Jul 2004 15:58:37 -0000
@@ -205,22 +205,22 @@
 ; Rivers (as special type), and whether north, south, east, west 
 ; also has river or is ocean:
 
- 18,  0, "tx.s_river_n0s0e0w0"
- 18,  1, "tx.s_river_n1s0e0w0"
- 18,  2, "tx.s_river_n0s0e1w0"
- 18,  3, "tx.s_river_n1s0e1w0"
- 18,  4, "tx.s_river_n0s1e0w0"
- 18,  5, "tx.s_river_n1s1e0w0"
- 18,  6, "tx.s_river_n0s1e1w0"
- 18,  7, "tx.s_river_n1s1e1w0"
- 18,  8, "tx.s_river_n0s0e0w1"
- 18,  9, "tx.s_river_n1s0e0w1"
- 18, 10, "tx.s_river_n0s0e1w1"
- 18, 11, "tx.s_river_n1s0e1w1"
- 18, 12, "tx.s_river_n0s1e0w1"
- 18, 13, "tx.s_river_n1s1e0w1"
- 18, 14, "tx.s_river_n0s1e1w1"
- 18, 15, "tx.s_river_n1s1e1w1"
+ 18,  0, "tx.s_river_n0e0s0w0"
+ 18,  1, "tx.s_river_n1e0s0w0"
+ 18,  2, "tx.s_river_n0e1s0w0"
+ 18,  3, "tx.s_river_n1e1s0w0"
+ 18,  4, "tx.s_river_n0e0s1w0"
+ 18,  5, "tx.s_river_n1e0s1w0"
+ 18,  6, "tx.s_river_n0e1s1w0"
+ 18,  7, "tx.s_river_n1e1s1w0"
+ 18,  8, "tx.s_river_n0e0s0w1"
+ 18,  9, "tx.s_river_n1e0s0w1"
+ 18, 10, "tx.s_river_n0e1s0w1"
+ 18, 11, "tx.s_river_n1e1s0w1"
+ 18, 12, "tx.s_river_n0e0s1w1"
+ 18, 13, "tx.s_river_n1e0s1w1"
+ 18, 14, "tx.s_river_n0e1s1w1"
+ 18, 15, "tx.s_river_n1e1s1w1"
 
 ; Ocean, and whether terrain to north, south, east, west 
 ; is more ocean (else shoreline)

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