Complete.Org: Mailing Lists: Archives: freeciv-dev: May 1999:
[Freeciv-Dev] graphics and colors proposal
Home

[Freeciv-Dev] graphics and colors proposal

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
To: freeciv-dev@xxxxxxxxxxx
Subject: [Freeciv-Dev] graphics and colors proposal
From: David Pfitzner <dwp@xxxxxxxxxxxxxx>
Date: Sat, 22 May 1999 13:38:14 +1000 (EST)

On Wed, 19 May 1999 David Pfitzner wrote:

> I think the first problem above can actually be overcome 
> to a large extent of one uses 64 color palettes, but 
> individually optimised for each file (so small.xpm would 
> get 64 colours optimised just for that file, which I've 
> tried and think looks reasonable).

>  This assumes that one 
> ignores the second problem (eg, assume 16 bit colour or 
> better, or live with whatever happesn on 8 bit displays).

I had a look into how well the above scheme would work,
and found out a few things.

To clarify, the idea is that each xpm file is allowed
its own individual colormap.  This allows the xpm file
sizes to stay small (if the number of colors per file
is kept to about 64) but gives better results on high
color systems than forcing all xpm files to use a common
64-color palette.  

On low color systems, the first xpm files loaded get
to use their specified colors until the colormap is full, 
and then other files get dithered using the available 
colors.  This may not look quite as good on 256 color 
systems as deliberately using a common colormap, but may 
not be much worse, and should be acceptable.

Actually, freeciv already currently does the above in some
sense, for for the radar.xpm and intro.xpm files (the map 
and minimap images before the game starts), which have
individual 256-colour palettes, and thus appear dithered
when using 256 colour systems.

Actually2, it seems the GTK+ doesn't allocate colors 
based on load order, but instead dithers everything to
some common palette, which is also reasonable.

However I found out that the above scheme doesn't quite
work for the current Xaw client: it core dumps for me 
if all the colors are already used up before we call
setup_widgets().  The attached patch adjusts things so
that the load order is:

   load tiles.xpm and small.xpm
   setup_widgets()
   load rest of game xpm files
   load intro xpm files

Then it seems to work fine (presumably providing tiles.xpm
and small.xpm don't have too many colors between them which 
should be ok if they are limited to 64 colors each).

So, my proposal:

In the short term (specifically, up to the next release) 
we stick to xpm format, and those who want somewhat more 
colors can use the above scheme.  In particular I would 
like to put the new small.xpm in cvs (in data/default)
with an individually optimsed 64-color palette, and also 
a single space.xpm also with such a palette.)  Of course 
people are still free to make xpm sets with common low-color 
palettes, and xpm sets with lots of colors, but the above 
should be the standard for graphics files included in the dist.

In the long term (after 1.8.1) we could revisit the graphics
format issue, eg (optionally?) using PNG format.  Note that 
1.8.1 will be the first stable relase to include the GTK+
client which requires imlib, so we may be able to get some 
feedback about how much trouble it would be to require imlib.

Also, Martin has indicated he'll put a section with the available
tilesets on the download page.   That should make the alternative
tilesets much more visible, rather than just having them hidden 
deep inside the ftp archive.

So, any problems with this proposal?

Regards,
-- David
diff -u -r --exclude-from exclude freeciv-cvs/client/gui-xaw/graphics.c 
freeciv-mod/client/gui-xaw/graphics.c
--- freeciv-cvs/client/gui-xaw/graphics.c       Wed May 12 21:33:12 1999
+++ freeciv-mod/client/gui-xaw/graphics.c       Sat May 22 12:40:10 1999
@@ -118,25 +118,30 @@
   return ctor_sprite_mask(mypixmap, mask, width, height);
 }
 
+/* This stores the index so far in global tile_sprites
+   between the end of load_tile_gfx_first() and the start
+   of load_tile_gfx_rest():
+*/
+static int tiles_i;
 
 /***************************************************************************
-...
+  Load tiles.xpm and small.xpm; these are necessary before we can
+  call setup_widgets.  Note that these two files must _not_ exhaust
+  the colormap (on 256 color systems) or setup_widgets will likely
+  dump core.
+  Initialises globals:
+     tile_sprites, NORMAL_TILE_WIDTH, NORMAL_TILE_HEIGHT.
+  Fills in tile_sprites for tiles.xpm and small.xpm graphics.   
 ***************************************************************************/
-void load_tile_gfx(void)
+void load_tile_gfx_first(void)
 {
   int i, x, y, ntiles, a;
-  struct Sprite *big_sprite, *small_sprite, *unit_sprite, *treaty_sprite;
-  struct Sprite *roads_sprite, *space_sprite, *flags_sprite;
-  int row;
+  struct Sprite *big_sprite, *small_sprite;
 
   big_sprite   = load_xpmfile(tilefilename("tiles.xpm"));
-  unit_sprite  = load_xpmfile(tilefilename("units.xpm"));
   small_sprite = load_xpmfile(tilefilename("small.xpm"));
-  treaty_sprite= load_xpmfile(tilefilename("treaty.xpm"));
-  roads_sprite = load_xpmfile(tilefilename("roads.xpm"));
-  space_sprite = load_xpmfile(tilefilename("space.xpm"));
-  flags_sprite = load_xpmfile(tilefilename("flags.xpm"));
 
+  /* tiles + units + small + treaty + roads + space + flags: */
   ntiles= (20*19) + (20*3) + (31*1) + 3 + (16*4) + 6 + (14*2);
 
   tile_sprites=fc_malloc(ntiles*sizeof(struct Sprite *));
@@ -173,6 +178,28 @@
     tile_sprites[i++]=ctor_sprite(mypixmap, 
                                  SMALL_TILE_WIDTH, SMALL_TILE_HEIGHT);
   }
+  free_sprite(big_sprite);
+  free_sprite(small_sprite);
+  tiles_i = i;
+}
+
+/***************************************************************************
+  Load the rest of the xpm files: those which are not required
+  for setup_widgets().
+***************************************************************************/
+void load_tile_gfx_rest(void)
+{
+  int i = tiles_i;
+  int x, y;
+  struct Sprite *unit_sprite, *treaty_sprite;
+  struct Sprite *roads_sprite, *space_sprite, *flags_sprite;
+  int row;
+
+  unit_sprite  = load_xpmfile(tilefilename("units.xpm"));
+  treaty_sprite= load_xpmfile(tilefilename("treaty.xpm"));
+  roads_sprite = load_xpmfile(tilefilename("roads.xpm"));
+  space_sprite = load_xpmfile(tilefilename("space.xpm"));
+  flags_sprite = load_xpmfile(tilefilename("flags.xpm"));
 
   {
     Pixmap mypixmap;
@@ -256,8 +283,6 @@
   }
   
   free_sprite(unit_sprite);
-  free_sprite(big_sprite);
-  free_sprite(small_sprite);
   free_sprite(treaty_sprite);
   free_sprite(roads_sprite);
   free_sprite(space_sprite);
diff -u -r --exclude-from exclude freeciv-cvs/client/gui-xaw/graphics.h 
freeciv-mod/client/gui-xaw/graphics.h
--- freeciv-cvs/client/gui-xaw/graphics.h       Wed May 12 21:33:12 1999
+++ freeciv-mod/client/gui-xaw/graphics.h       Sat May 22 12:25:21 1999
@@ -67,7 +67,8 @@
 void dtor_sprite(struct Sprite *mysprite);
 
 struct Sprite *get_tile_sprite(int tileno);
-void load_tile_gfx(void);
+void load_tile_gfx_first(void);
+void load_tile_gfx_rest(void);
 void load_intro_gfx(void);
 void load_cursors(void);
 
diff -u -r --exclude-from exclude freeciv-cvs/client/gui-xaw/gui_main.c 
freeciv-mod/client/gui-xaw/gui_main.c
--- freeciv-cvs/client/gui-xaw/gui_main.c       Wed May 12 21:33:12 1999
+++ freeciv-mod/client/gui-xaw/gui_main.c       Sat May 22 12:43:35 1999
@@ -399,14 +399,20 @@
     gray25=XCreateBitmapFromData(display,root_window,d2,4,4);
   }
 
-  load_tile_gfx();
+  /* get NORMAL_TILE_WIDTH etc, small.xpm, required for setup_widgets: */
+  load_tile_gfx_first();
 
   /* 135 below is rough value (could be more intelligent) --dwp */
   num_units_below = 135/(int)NORMAL_TILE_WIDTH;
   num_units_below = MIN(num_units_below,MAX_NUM_UNITS_BELOW);
   num_units_below = MAX(num_units_below,1);
   
+  /* do setup_widgets before loading the rest of graphics to ensure that
+     setup_widgets() has enough colors available:  (on 256-colour systems)
+  */
   setup_widgets();
+
+  load_tile_gfx_rest();
   load_intro_gfx();
   load_cursors();
 

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