[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: |
Tue, 4 May 2004 14:44:19 -0700 |
Reply-to: |
rt@xxxxxxxxxxx |
<URL: http://rt.freeciv.org/Ticket/Display.html?id=8622 >
Jason Short wrote:
> http://freeciv.org/~jdorje/civ3.png
> http://freeciv.org/~jdorje/civ3.tar.gz (tileset)
Here's an update of the patch. Very slightly smaller. Still not very
clean.
jason
Index: client/tilespec.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/tilespec.c,v
retrieving revision 1.166
diff -u -r1.166 tilespec.c
--- client/tilespec.c 4 May 2004 18:22:02 -0000 1.166
+++ client/tilespec.c 4 May 2004 21:39:24 -0000
@@ -86,6 +86,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. */
@@ -737,6 +746,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);
@@ -751,7 +780,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_"));
@@ -759,9 +788,12 @@
terrains[i]);
terr->num_layers = secfile_lookup_int(file, "%s.num_layers",
terrains[i]);
- terr->num_layers = MAX(1, terr->num_layers);
+ terr->num_layers = CLIP(1, terr->num_layers, MAX_NUM_LAYERS);
for (l = 0; l < terr->num_layers; l++) {
+ char *match_type;
+ char *match_style;
+
terr->layer[l].is_tall
= secfile_lookup_bool_default(file, FALSE, "%s.layer%d_is_tall",
terrains[i], l);
@@ -771,9 +803,61 @@
terr->layer[l].offset_y
= secfile_lookup_int_default(file, 0, "%s.layer%d_offset_y",
terrains[i], l);
- terr->layer[l].match_type
- = secfile_lookup_int_default(file, 0, "%s.layer%d_match_type",
- terrains[i], l);
+
+ match_style = secfile_lookup_str_default(file, "none",
+ "%s.layer%d_match_style",
+ terrains[i], l);
+ 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;
+ }
+
+ 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 out 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
= secfile_lookup_str_default(file, "single", "%s.layer%d_cell_type",
terrains[i], l);
@@ -1298,15 +1382,13 @@
/* Set up each layer of the drawing. */
for (l = 0; l < draw->num_layers; l++) {
- if (draw->layer[l].match_type == 0) {
+ if (draw->layer[l].match_style == MATCH_NONE) {
/* Load single sprite for this terrain. */
my_snprintf(buffer1, sizeof(buffer1), "t.%s1", draw->name);
draw->layer[l].base = lookup_sprite_tag_alt(buffer1, "", TRUE,
"tile_type",
tt->terrain_name);
} else {
- int j;
-
switch (draw->layer[l].cell_type) {
case CELL_SINGLE:
/* Load 16 cardinally-matched sprites. */
@@ -1320,16 +1402,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);
@@ -1986,14 +2153,13 @@
}
for (l = 0; l < draw->num_layers; l++) {
- if (draw->layer[l].match_type == 0) {
+ if (draw->layer[l].match_style == MATCH_NONE) {
ADD_SPRITE_SIMPLE(draw->layer[l].base);
} else {
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;
@@ -2021,17 +2187,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.66
diff -u -r1.66 tilespec.h
--- client/tilespec.h 29 Apr 2004 15:11:32 -0000 1.66
+++ client/tilespec.h 4 May 2004 21:39:24 -0000
@@ -104,10 +104,16 @@
DIR4_NORTH = 0, DIR4_SOUTH, DIR4_EAST, DIR4_WEST
};
+enum match_style {
+ MATCH_NONE, MATCH_BOOLEAN, MATCH_FULL
+};
+
enum cell_type {
CELL_SINGLE, CELL_RECT
};
+#define MAX_NUM_LAYERS 2
+
struct terrain_drawing_data {
char *name;
char *mine_tag;
@@ -116,13 +122,16 @@
struct {
bool is_tall;
int offset_x, offset_y;
- int match_type;
+
+ enum match_style match_style;
+ 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 */
- } layer[2];
+ struct Sprite **cells;
+ } layer[MAX_NUM_LAYERS];
bool is_blended;
struct Sprite *blend[4]; /* indexed by a direction4 */
Index: data/isotrident.tilespec
===================================================================
RCS file: /home/freeciv/CVS/freeciv/data/isotrident.tilespec,v
retrieving revision 1.16
diff -u -r1.16 isotrident.tilespec
--- data/isotrident.tilespec 1 Apr 2004 23:11:23 -0000 1.16
+++ data/isotrident.tilespec 4 May 2004 21:39:25 -0000
@@ -64,55 +64,74 @@
; 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
-layer1_match_type = 1
+layer0_match_type = "other"
+layer1_match_type = "forest"
[terrain_grassland]
is_blended = 1
num_layers = 1
+layer0_match_type = "other"
[terrain_hills]
is_blended = 1
num_layers = 2
-layer1_match_type = 2
+layer0_match_type = "other"
+layer1_match_type = "hills"
mine_sprite = "tx.mine"
[terrain_jungle]
is_blended = 1
num_layers = 1
+layer0_match_type = "other"
[terrain_mountains]
is_blended = 1
num_layers = 2
-layer1_match_type = 3
+layer0_match_type = "other"
+layer1_match_type = "mountains"
mine_sprite = "tx.mine"
[terrain_ocean]
is_blended = 1
num_layers = 1
-layer0_match_type = 6
+layer0_match_style = "bool"
+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"
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Freeciv-Dev] Re: (PR#8622) civ3-style base terrain graphics,
Jason Short <=
|
|