[Freeciv-Dev] (PR#9379) hex tilesets and rivers
[Top] [All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
<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)
|
|