[Freeciv-Dev] Re: (PR#8622) civ3-style base terrain graphics
[Top] [All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
To: |
undisclosed-recipients: ; |
Subject: |
[Freeciv-Dev] Re: (PR#8622) civ3-style base terrain graphics |
From: |
"Jason Short" <jdorje@xxxxxxxxxxxxxxxxxxxxx> |
Date: |
Fri, 25 Jun 2004 08:42:16 -0700 |
Reply-to: |
rt@xxxxxxxxxxx |
<URL: http://rt.freeciv.org/Ticket/Display.html?id=8622 >
This patch fixes the behavior.
Although it still has some hacks, I think it is ready for inclusion.
Fixing these hacks (and generalizing them for hex tilesets) will be
rather hard.
jason
? gmon.out
? data/stdfont.ttf
? data/theme
Index: client/tilespec.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/tilespec.c,v
retrieving revision 1.176
diff -u -r1.176 tilespec.c
--- client/tilespec.c 21 Jun 2004 15:14:43 -0000 1.176
+++ client/tilespec.c 25 Jun 2004 15:39:53 -0000
@@ -85,6 +85,15 @@
static int roadstyle;
static int flag_offset_x, flag_offset_y;
+#define NUM_CORNER_DIRS 4
+#define TILES_PER_CORNER 4
+
+static struct {
+ enum match_style match_style;
+ int count;
+ char **match_types;
+} layers[MAX_NUM_LAYERS];
+
/* Darkness style. Don't reorder this enum since tilesets depend on it. */
static enum {
/* No darkness sprites are drawn. */
@@ -775,6 +784,26 @@
minimap_intro_filename = tilespec_gfx_filename(c);
freelog(LOG_DEBUG, "radar file %s", minimap_intro_filename);
+ /* Terrain layer info. */
+ for (i = 0; i < MAX_NUM_LAYERS; i++) {
+ char *style = secfile_lookup_str_default(file, "none",
+ "layer%d.match_style", i);
+ int j;
+
+ if (mystrcasecmp(style, "full") == 0) {
+ layers[i].match_style = MATCH_FULL;
+ } else if (mystrcasecmp(style, "bool") == 0) {
+ layers[i].match_style = MATCH_BOOLEAN;
+ } else {
+ layers[i].match_style = MATCH_NONE;
+ }
+
+ layers[i].match_types = secfile_lookup_str_vec(file, &layers[i].count,
+ "layer%d.match_types", i);
+ for (j = 0; j < layers[i].count; j++) {
+ layers[i].match_types[j] = mystrdup(layers[i].match_types[j]);
+ }
+ }
/* Terrain drawing info. */
terrains = secfile_get_secnames_prefix(file, "terrain_", &num_terrains);
@@ -789,7 +818,7 @@
for (i = 0; i < num_terrains; i++) {
struct terrain_drawing_data *terr = fc_malloc(sizeof(*terr));
char *cell_type;
- int l;
+ int l, j;
memset(terr, 0, sizeof(*terr));
terr->name = mystrdup(terrains[i] + strlen("terrain_"));
@@ -800,7 +829,7 @@
terr->num_layers = CLIP(1, terr->num_layers, MAX_NUM_LAYERS);
for (l = 0; l < terr->num_layers; l++) {
- char *match_style;
+ char *match_type, *match_style;
terr->layer[l].is_tall
= secfile_lookup_bool_default(file, FALSE, "%s.layer%d_is_tall",
@@ -814,16 +843,55 @@
match_style = secfile_lookup_str_default(file, "none",
"%s.layer%d_match_style",
terrains[i], l);
- if (mystrcasecmp(match_style, "bool") == 0) {
+ if (mystrcasecmp(match_style, "full") == 0) {
+ terr->layer[l].match_style = MATCH_FULL;
+ } else if (mystrcasecmp(match_style, "bool") == 0) {
terr->layer[l].match_style = MATCH_BOOLEAN;
} else {
terr->layer[l].match_style = MATCH_NONE;
}
- if (terr->layer[l].match_style == MATCH_BOOLEAN) {
- terr->layer[l].match_type
- = secfile_lookup_int_default(file, 0, "%s.layer%d_match_type",
- terrains[i], l);
+ match_type = secfile_lookup_str_default(file, NULL,
+ "%s.layer%d_match_type",
+ terrains[i], l);
+ if (match_type) {
+ /* Set match_count */
+ switch (terr->layer[l].match_style) {
+ case MATCH_NONE:
+ terr->layer[l].match_count = 0;
+ break;
+ case MATCH_FULL:
+ terr->layer[l].match_count = layers[l].count;
+ break;
+ case MATCH_BOOLEAN:
+ terr->layer[l].match_count = 2;
+ break;
+ }
+
+ /* Determine our match_type. */
+ for (j = 0; j < layers[l].count; j++) {
+ if (mystrcasecmp(layers[l].match_types[j], match_type) == 0) {
+ break;
+ }
+ }
+ terr->layer[l].match_type = j;
+ if (j >= layers[l].count) {
+ freelog(LOG_ERROR, "Invalid match type given for %s.", terrains[i]);
+ terr->layer[l].match_type = 0;
+ terr->layer[l].match_style = MATCH_NONE;
+ }
+ } else {
+ terr->layer[l].match_style = MATCH_NONE;
+ if (layers[l].match_style != MATCH_NONE) {
+ freelog(LOG_ERROR, "Layer %d has a match_style set; all terrains"
+ " must have a match_type. %s doesn't.", l, terrains[i]);
+ }
+ }
+
+ if (terr->layer[l].match_style == MATCH_NONE
+ && layers[l].match_style == MATCH_FULL) {
+ freelog(LOG_ERROR, "Layer %d has match_type full set; all terrains"
+ " must match this. %s doesn't.", l, terrains[i]);
}
cell_type
@@ -1373,8 +1441,6 @@
"tile_type",
tt->terrain_name);
} else {
- int j;
-
switch (draw->layer[l].cell_type) {
case CELL_SINGLE:
/* Load 16 cardinally-matched sprites. */
@@ -1388,16 +1454,101 @@
draw->layer[l].base = draw->layer[l].match[0];
break;
case CELL_RECT:
- for (i = 0; i < 4; i++) { /* enum direction4 */
- for (j = 0; j < 8; j++) {
+ {
+ const int count = draw->layer[l].match_count;
+ /* N directions (NSEW) * 3 dimensions of matching */
+ /* FIXME: should use exp() or expi() here. */
+ const int number = NUM_CORNER_DIRS * count * count * count;
+
+ draw->layer[l].cells
+ = fc_malloc(number * sizeof(*draw->layer[l].cells));
+
+ for (i = 0; i < number; i++) {
+ int value = i / NUM_CORNER_DIRS;
+ enum direction4 dir = i % NUM_CORNER_DIRS;
const char dirs[4] = "udrl"; /* Matches direction4 ordering */
- my_snprintf(buffer1, sizeof(buffer1), "t.%s_cell_%c%d%d%d",
- draw->name, dirs[i],
- (j >> 2) & 1, (j >> 1) & 1, j & 1);
- draw->layer[l].cells[j][i]
- = lookup_sprite_tag_alt(buffer1, "", TRUE, "tile_type",
- tt->terrain_name);
+ switch (draw->layer[l].match_style) {
+ case MATCH_NONE:
+ assert(0); /* Impossible. */
+ break;
+ case MATCH_BOOLEAN:
+ my_snprintf(buffer1, sizeof(buffer1), "t.%s_cell_%c%d%d%d",
+ draw->name, dirs[dir],
+ (value >> 0) & 1,
+ (value >> 1) & 1,
+ (value >> 2) & 1);
+ draw->layer[l].cells[i]
+ = lookup_sprite_tag_alt(buffer1, "", TRUE, "tile_type",
+ tt->terrain_name);
+ break;
+ case MATCH_FULL:
+ {
+ int n = 0, s = 0, e = 0, w = 0;
+ int v1, v2, v3;
+ int this = draw->layer[l].match_type;
+ struct Sprite *sprite;
+
+ v1 = value % count;
+ value /= count;
+ v2 = value % count;
+ value /= count;
+ v3 = value % count;
+
+ assert(v1 < count && v2 < count && v3 < count);
+
+ /* Assume merged cells. This should be a separate option. */
+ switch (dir) {
+ case DIR4_NORTH:
+ s = this;
+ w = v1;
+ n = v2;
+ e = v3;
+ break;
+ case DIR4_EAST:
+ w = this;
+ n = v1;
+ e = v2;
+ s = v3;
+ break;
+ case DIR4_SOUTH:
+ n = this;
+ e = v1;
+ s = v2;
+ w = v3;
+ break;
+ case DIR4_WEST:
+ e = this;
+ s = v1;
+ w = v2;
+ n = v3;
+ break;
+ }
+ my_snprintf(buffer1, sizeof(buffer1),
+ "t.cellgroup_%s_%s_%s_%s",
+ layers[l].match_types[n],
+ layers[l].match_types[e],
+ layers[l].match_types[s],
+ layers[l].match_types[w]);
+ sprite = load_sprite(buffer1);
+
+ if (sprite) {
+ /* Crop the sprite to separate this cell. */
+ const int W = NORMAL_TILE_WIDTH, H = NORMAL_TILE_HEIGHT;
+ int x[4] = {W / 4, W / 4, 0, W / 2};
+ int y[4] = {H / 2, 0, H / 4, H / 4};
+ int xo[4] = {0, 0, -W / 2, W / 2};
+ int yo[4] = {H / 2, -H / 2, 0, 0};
+
+ sprite = crop_sprite(sprite,
+ x[dir], y[dir], W / 2, H / 2,
+ sprites.black_tile, xo[dir], yo[dir]);
+ }
+
+ draw->layer[l].cells[i] = sprite;
+ break;
+ }
+ }
}
}
my_snprintf(buffer1, sizeof(buffer1), "t.%s1", draw->name);
@@ -2060,14 +2211,16 @@
int match_type = draw->layer[l].match_type;
#define MATCH(dir) \
- ((sprites.terrain[ttype_near[(dir)]]->layer[l].match_type) \
- == match_type)
+ (sprites.terrain[ttype_near[(dir)]]->layer[l].match_type)
if (draw->layer[l].cell_type == CELL_SINGLE) {
int tileno;
- tileno = INDEX_NSEW(MATCH(DIR8_NORTH), MATCH(DIR8_SOUTH),
- MATCH(DIR8_EAST), MATCH(DIR8_WEST));
+ assert(draw->layer[l].match_style == MATCH_BOOLEAN);
+ tileno = INDEX_NSEW(MATCH(DIR8_NORTH) == match_type,
+ MATCH(DIR8_SOUTH) == match_type,
+ MATCH(DIR8_EAST) == match_type,
+ MATCH(DIR8_WEST) == match_type);
ADD_SPRITE(draw->layer[l].match[tileno],
draw->layer[l].is_tall ? DRAW_FULL : DRAW_NORMAL,
@@ -2089,17 +2242,39 @@
};
int i;
- /* put coasts */
- for (i = 0; i < 4; i++) {
+ /* put corner cells */
+ for (i = 0; i < NUM_CORNER_DIRS; i++) {
+ const int count = draw->layer[l].match_count;
+ int array_index = 0;
enum direction8 dir = dir_ccw(DIR4_TO_DIR8[i]);
- int array_index = ((!MATCH(dir_ccw(dir)) ? 4 : 0)
- + (!MATCH(dir) ? 2 : 0)
- + (!MATCH(dir_cw(dir)) ? 1 : 0));
int x = (is_isometric ? iso_offsets[i][0] : noniso_offsets[i][0]);
int y = (is_isometric ? iso_offsets[i][1] : noniso_offsets[i][1]);
+ int m[3] = {MATCH(dir_ccw(dir)), MATCH(dir), MATCH(dir_cw(dir))};
+ struct Sprite *s;
- ADD_SPRITE(draw->layer[l].cells[array_index][i],
- DRAW_NORMAL, TRUE, x, y);
+ switch (draw->layer[l].match_style) {
+ case MATCH_NONE:
+ /* Impossible */
+ assert(0);
+ break;
+ case MATCH_BOOLEAN:
+ assert(count == 2);
+ array_index = array_index * count + (m[2] != match_type);
+ array_index = array_index * count + (m[1] != match_type);
+ array_index = array_index * count + (m[0] != match_type);
+ break;
+ case MATCH_FULL:
+ array_index = array_index * count + m[2];
+ array_index = array_index * count + m[1];
+ array_index = array_index * count + m[0];
+ break;
+ }
+ array_index = array_index * NUM_CORNER_DIRS + i;
+
+ s = draw->layer[l].cells[array_index];
+ if (s) {
+ ADD_SPRITE(s, DRAW_NORMAL, TRUE, x, y);
+ }
}
}
#undef MATCH
Index: client/tilespec.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/tilespec.h,v
retrieving revision 1.71
diff -u -r1.71 tilespec.h
--- client/tilespec.h 21 Jun 2004 15:14:43 -0000 1.71
+++ client/tilespec.h 25 Jun 2004 15:39:53 -0000
@@ -105,7 +105,7 @@
};
enum match_style {
- MATCH_NONE, MATCH_BOOLEAN
+ MATCH_NONE, MATCH_BOOLEAN, MATCH_FULL
};
enum cell_type {
@@ -124,13 +124,13 @@
int offset_x, offset_y;
enum match_style match_style;
- int match_type;
+ int match_type, match_count;
enum cell_type cell_type;
struct Sprite *base;
struct Sprite *match[NUM_DIRECTION_NSEW];
- struct Sprite *cells[8][4]; /* 4 = up down left right */
+ struct Sprite **cells;
} layer[MAX_NUM_LAYERS];
bool is_blended;
Index: data/isotrident.tilespec
===================================================================
RCS file: /home/freeciv/CVS/freeciv/data/isotrident.tilespec,v
retrieving revision 1.19
diff -u -r1.19 isotrident.tilespec
--- data/isotrident.tilespec 11 Jun 2004 16:59:18 -0000 1.19
+++ data/isotrident.tilespec 25 Jun 2004 15:39:53 -0000
@@ -64,59 +64,77 @@
; Terrain info - see README.graphics
+[layer0]
+match_style = "BOOL"
+match_types = "ocean", "other"
+
+[layer1]
+match_style = "BOOL"
+match_types = "forest", "hills", "mountains"
+
[terrain_arctic]
is_blended = 1
num_layers = 1
+layer0_match_type = "other"
mine_sprite = "tx.oil_mine"
[terrain_desert]
is_blended = 1
num_layers = 1
+layer0_match_type = "other"
mine_sprite = "tx.oil_mine"
[terrain_forest]
is_blended = 1
num_layers = 2
+layer0_match_type = "other"
+layer1_match_type = "forest"
layer1_match_style = "bool"
-layer1_match_type = 1
[terrain_grassland]
is_blended = 1
num_layers = 1
+layer0_match_type = "other"
[terrain_hills]
is_blended = 1
num_layers = 2
+layer0_match_type = "other"
+layer1_match_type = "hills"
layer1_match_style = "bool"
-layer1_match_type = 2
mine_sprite = "tx.mine"
[terrain_jungle]
is_blended = 1
num_layers = 1
+layer0_match_type = "other"
[terrain_mountains]
is_blended = 1
num_layers = 2
+layer0_match_type = "other"
+layer1_match_type = "mountains"
layer1_match_style = "bool"
-layer1_match_type = 3
mine_sprite = "tx.mine"
[terrain_ocean]
is_blended = 1
num_layers = 1
layer0_match_style = "bool"
-layer0_match_type = 6
+layer0_match_type = "ocean"
layer0_cell_type = "rect"
[terrain_plains]
is_blended = 1
num_layers = 1
+layer0_match_type = "other"
[terrain_swamp]
is_blended = 1
num_layers = 1
+layer0_match_type = "other"
[terrain_tundra]
is_blended = 1
num_layers = 1
+layer0_match_type = "other"
Index: data/trident.tilespec
===================================================================
RCS file: /home/freeciv/CVS/freeciv/data/trident.tilespec,v
retrieving revision 1.22
diff -u -r1.22 trident.tilespec
--- data/trident.tilespec 6 Jun 2004 06:09:46 -0000 1.22
+++ data/trident.tilespec 25 Jun 2004 15:39:53 -0000
@@ -62,72 +62,76 @@
; Terrain info - see README.graphics
+[layer0]
+match_style = "BOOL"
+match_types = "arctic", "desert", "forest", "grassland", "hills", "jungle",
"mountains", "ocean", "plains", "swamp", "tundra"
+
[terrain_arctic]
is_blended = 0
num_layers = 1
layer0_match_style = "bool"
-layer0_match_type = 1
+layer0_match_type = "arctic"
mine_sprite = "tx.oil_mine"
[terrain_desert]
is_blended = 0
num_layers = 1
layer0_match_style = "bool"
-layer0_match_type = 2
+layer0_match_type = "desert"
mine_sprite = "tx.oil_mine"
[terrain_forest]
is_blended = 0
num_layers = 1
layer0_match_style = "bool"
-layer0_match_type = 3
+layer0_match_type = "forest"
[terrain_grassland]
is_blended = 0
num_layers = 1
layer0_match_style = "bool"
-layer0_match_type = 3
+layer0_match_type = "grassland"
[terrain_hills]
is_blended = 0
num_layers = 1
layer0_match_style = "bool"
-layer0_match_type = 4
+layer0_match_type = "hills"
mine_sprite = "tx.mine"
[terrain_jungle]
is_blended = 0
num_layers = 1
layer0_match_style = "bool"
-layer0_match_type = 5
+layer0_match_type = "jungle"
[terrain_mountains]
is_blended = 0
num_layers = 1
layer0_match_style = "bool"
-layer0_match_type = 6
+layer0_match_type = "mountains"
mine_sprite = "tx.mine"
[terrain_ocean]
is_blended = 0
num_layers = 1
layer0_match_style = "bool"
-layer0_match_type = 7
+layer0_match_type = "ocean"
[terrain_plains]
is_blended = 0
num_layers = 1
layer0_match_style = "bool"
-layer0_match_type = 8
+layer0_match_type = "plains"
[terrain_swamp]
is_blended = 0
num_layers = 1
layer0_match_style = "bool"
-layer0_match_type = 9
+layer0_match_type = "swamp"
[terrain_tundra]
is_blended = 0
num_layers = 1
layer0_match_style = "bool"
-layer0_match_type = 10
+layer0_match_type = "tundra"
Index: data/trident_shields.tilespec
===================================================================
RCS file: /home/freeciv/CVS/freeciv/data/trident_shields.tilespec,v
retrieving revision 1.12
diff -u -r1.12 trident_shields.tilespec
--- data/trident_shields.tilespec 6 Jun 2004 06:09:46 -0000 1.12
+++ data/trident_shields.tilespec 25 Jun 2004 15:39:53 -0000
@@ -65,72 +65,76 @@
; Terrain info - see README.graphics
+[layer0]
+match_style = "BOOL"
+match_types = "arctic", "desert", "forest", "grassland", "hills", "jungle",
"mountains", "ocean", "plains", "swamp", "tundra"
+
[terrain_arctic]
is_blended = 0
num_layers = 1
layer0_match_style = "bool"
-layer0_match_type = 1
+layer0_match_type = "arctic"
mine_sprite = "tx.oil_mine"
[terrain_desert]
is_blended = 0
num_layers = 1
layer0_match_style = "bool"
-layer0_match_type = 2
+layer0_match_type = "desert"
mine_sprite = "tx.oil_mine"
[terrain_forest]
is_blended = 0
num_layers = 1
layer0_match_style = "bool"
-layer0_match_type = 3
+layer0_match_type = "forest"
[terrain_grassland]
is_blended = 0
num_layers = 1
layer0_match_style = "bool"
-layer0_match_type = 3
+layer0_match_type = "grassland"
[terrain_hills]
is_blended = 0
num_layers = 1
layer0_match_style = "bool"
-layer0_match_type = 4
+layer0_match_type = "hills"
mine_sprite = "tx.mine"
[terrain_jungle]
is_blended = 0
num_layers = 1
layer0_match_style = "bool"
-layer0_match_type = 5
+layer0_match_type = "jungle"
[terrain_mountains]
is_blended = 0
num_layers = 1
layer0_match_style = "bool"
-layer0_match_type = 6
+layer0_match_type = "mountains"
mine_sprite = "tx.mine"
[terrain_ocean]
is_blended = 0
num_layers = 1
layer0_match_style = "bool"
-layer0_match_type = 7
+layer0_match_type = "ocean"
[terrain_plains]
is_blended = 0
num_layers = 1
layer0_match_style = "bool"
-layer0_match_type = 8
+layer0_match_type = "plains"
[terrain_swamp]
is_blended = 0
num_layers = 1
layer0_match_style = "bool"
-layer0_match_type = 9
+layer0_match_type = "swamp"
[terrain_tundra]
is_blended = 0
num_layers = 1
layer0_match_style = "bool"
-layer0_match_type = 10
+layer0_match_type = "tundra"
|
|