Complete.Org: Mailing Lists: Archives: freeciv-dev: September 2004:
[Freeciv-Dev] (PR#9988) multiple sprites for one terrain
Home

[Freeciv-Dev] (PR#9988) multiple sprites for one terrain

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
To: undisclosed-recipients: ;
Subject: [Freeciv-Dev] (PR#9988) multiple sprites for one terrain
From: "Jason Short" <jdorje@xxxxxxxxxxxxxxxxxxxxx>
Date: Wed, 8 Sep 2004 14:24:54 -0700
Reply-to: rt@xxxxxxxxxxx

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

This patch does two things.

- It fixes a bug whereby is_tall was ignored for unmatched terrains. 
This is a very small change.

- It adds a sprite_vector and uses it to allow multiple sprites for the 
base terrain.  If multiple sprites are present one will be chosen via a 
random-looking but reproducable algorithm.  This is helpful with the 
civ3 graphics because there are multiple graphics for lots of terrains, 
including oceans and forests.  Of course any tileset can use it, 
particularly to get some differentiation to large regions of ocean.

With these two fixes I can get civ3 forests to more or less work.  See 
http://freeciv.org/~jdorje/forest.png.

jason

Index: client/tilespec.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/tilespec.c,v
retrieving revision 1.196
diff -u -r1.196 tilespec.c
--- client/tilespec.c   25 Aug 2004 18:24:18 -0000      1.196
+++ client/tilespec.c   8 Sep 2004 21:21:11 -0000
@@ -1610,12 +1610,27 @@
 
   /* Set up each layer of the drawing. */
   for (l = 0; l < draw->num_layers; l++) {
+    sprite_vector_init(&draw->layer[l].base);
+    sprite_vector_reserve(&draw->layer[l].base, 1);
     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);
+      for (i = 0; ; i++) {
+       struct Sprite *sprite;
+
+       my_snprintf(buffer1, sizeof(buffer1), "t.%s%d", draw->name, i + 1);
+       sprite = load_sprite(buffer1);
+       if (!sprite) {
+         break;
+       }
+       sprite_vector_reserve(&draw->layer[l].base, i + 1);
+       draw->layer[l].base.p[i] = sprite;
+      }
+      if (i == 0) {
+       /* TRANS: obscure tileset error. */
+       freelog(LOG_FATAL, _("Missing base sprite tag \"%s1\"."),
+               draw->name);
+       exit(EXIT_FAILURE);
+      }
     } else {
       switch (draw->layer[l].cell_type) {
       case CELL_SINGLE:
@@ -1627,7 +1642,7 @@
                                                          "tile_type",
                                                          tt->terrain_name);
        }
-       draw->layer[l].base = draw->layer[l].match[0];
+       draw->layer[l].base.p[0] = draw->layer[l].match[0];
        break;
       case CELL_RECT:
        {
@@ -1728,7 +1743,7 @@
          }
        }
        my_snprintf(buffer1, sizeof(buffer1), "t.%s1", draw->name);
-       draw->layer[l].base
+       draw->layer[l].base.p[0]
          = lookup_sprite_tag_alt(buffer1, "", FALSE, "tile_type",
                                  tt->terrain_name);
        break;
@@ -1745,7 +1760,8 @@
     enum direction4 dir;
 
     for (dir = 0; dir < 4; dir++) {
-      draw->blend[dir] = crop_sprite(draw->layer[0].base,
+      assert(sprite_vector_size(&draw->layer[0].base) > 0);
+      draw->blend[dir] = crop_sprite(draw->layer[0].base.p[0],
                                     offsets[dir][0], offsets[dir][1],
                                     W / 2, H / 2,
                                     sprites.dither_tile, 0, 0);
@@ -2427,7 +2443,18 @@
 
   for (l = 0; l < draw->num_layers; l++) {
     if (draw->layer[l].match_style == MATCH_NONE) {
-      ADD_SPRITE_SIMPLE(draw->layer[l].base);
+      int count = sprite_vector_size(&draw->layer[l].base);
+
+      /* Pseudo-random reproducable algorithm to pick a sprite. */
+#define LARGE_PRIME 10007
+#define SMALL_PRIME 1009
+      assert(count < SMALL_PRIME);
+      assert((int)(LARGE_PRIME * MAX_MAP_INDEX) > 0);
+      count = ((map_pos_to_index(map_x, map_y)
+               * LARGE_PRIME) % SMALL_PRIME) % count;
+      ADD_SPRITE(draw->layer[l].base.p[count],
+                draw->layer[l].is_tall ? DRAW_FULL : DRAW_NORMAL,
+                TRUE, draw->layer[l].offset_x, draw->layer[l].offset_y);
     } else {
       int match_type = draw->layer[l].match_type;
 
Index: client/tilespec.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/tilespec.h,v
retrieving revision 1.85
diff -u -r1.85 tilespec.h
--- client/tilespec.h   3 Sep 2004 04:22:36 -0000       1.85
+++ client/tilespec.h   8 Sep 2004 21:21:11 -0000
@@ -106,6 +106,11 @@
 
 #define MAX_NUM_LAYERS 2
 
+/* Create the sprite_vector type. */
+#define SPECVEC_TAG sprite
+#define SPECVEC_TYPE struct Sprite *
+#include "specvec.h"
+
 struct terrain_drawing_data {
   char *name;
   char *mine_tag;
@@ -120,7 +125,7 @@
 
     enum cell_type cell_type;
 
-    struct Sprite *base;
+    struct sprite_vector base;
     struct Sprite *match[MAX_INDEX_CARDINAL];
     struct Sprite **cells;
   } layer[MAX_NUM_LAYERS];

[Prev in Thread] Current Thread [Next in Thread]
  • [Freeciv-Dev] (PR#9988) multiple sprites for one terrain, Jason Short <=