initial commit, lordsawar source, slightly modified
[lordsawar] / src / GraphicsCache.cpp
diff --git a/src/GraphicsCache.cpp b/src/GraphicsCache.cpp
new file mode 100644 (file)
index 0000000..b1c65c7
--- /dev/null
@@ -0,0 +1,2741 @@
+// Copyright (C) 2003, 2004, 2005, 2006, 2007 Ulf Lorenz
+// Copyright (C) 2004, 2005, 2006 Andrea Paternesi
+// Copyright (C) 2006, 2007, 2008, 2009 Ben Asselstine
+//
+//  This program is free software; you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License as published by
+//  the Free Software Foundation; either version 3 of the License, or
+//  (at your option) any later version.
+//
+//  This program is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//  GNU Library General Public License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program; if not, write to the Free Software
+//  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 
+//  02110-1301, USA.
+
+#include <assert.h>
+#include <string.h>
+
+#include "rectangle.h"
+
+#include "GraphicsCache.h"
+#include "armysetlist.h"
+#include "shieldsetlist.h"
+#include "tilesetlist.h"
+#include "citysetlist.h"
+#include "citylist.h"
+#include "army.h"
+#include "playerlist.h"
+#include "Configuration.h"
+#include "File.h"
+#include "GameMap.h"
+#include "city.h"
+#include "stack.h"
+#include "gui/image-helpers.h"
+#include "FogMap.h"
+#include "hero.h"
+
+//#define debug(x) {std::cerr<<__FILE__<<": "<<__LINE__<<": "<<x<<std::endl<<std::flush;}
+#define debug(x)
+
+//some structures first
+
+//this structure is the base class for storing cached objects. It stores the
+//(army-, but can be extended) set, the type of army and the player which the
+//surface is designed for (and the surface itself, of course).
+struct ArmyCacheItem
+{
+    guint32 armyset;
+    guint32 army_id;
+    guint32 player_id;
+    bool medals[3];
+    bool greyed;
+    PixMask* surface;
+};
+bool operator <(ArmyCacheItem lhs, ArmyCacheItem rhs)
+{
+  return memcmp(&lhs, &rhs, sizeof (ArmyCacheItem) - sizeof (PixMask*)) < 0;
+}
+
+//the structure to store ships in
+struct ShipCacheItem
+{
+    guint32 player_id;
+    guint32 armyset;
+    PixMask* surface;
+};
+
+//the structure to store planted standard in
+struct PlantedStandardCacheItem
+{
+    guint32 player_id;
+    guint32 armyset;
+    PixMask* surface;
+};
+
+//the structure to store new level pictures in
+struct NewLevelCacheItem
+{
+    guint32 player_id;
+    guint32 gender;
+    PixMask* surface;
+};
+
+//the structure to store temples in
+struct TempleCacheItem
+{
+    guint32 cityset;
+    int type;
+    PixMask* surface;
+};
+
+//the structure to store ruins in
+struct RuinCacheItem
+{
+    guint32 cityset;
+    int type;
+    PixMask* surface;
+};
+
+//the structure to store diplomacy icons in
+struct DiplomacyCacheItem
+{
+    int type;
+    Player::DiplomaticState state;
+    PixMask* surface;
+};
+
+//the structure to store roads in
+struct RoadCacheItem
+{
+    guint32 tileset;
+    int type;
+    PixMask* surface;
+};
+
+//the structure to store fog patterns in
+struct FogCacheItem
+{
+    guint32 tileset;
+    int type;
+    PixMask* surface;
+};
+bool operator <(FogCacheItem lhs, FogCacheItem rhs)
+{
+  return memcmp(&lhs, &rhs, sizeof (FogCacheItem) - sizeof (PixMask*)) < 0;
+}
+
+//the structure to store bridges in
+struct BridgeCacheItem
+{
+    guint32 tileset;
+    int type;
+    PixMask* surface;
+};
+
+//the structure to store cursors in
+struct CursorCacheItem
+{
+    int type;
+    PixMask* surface;
+};
+
+//the structure to store buildings in
+struct CityCacheItem
+{
+    guint32 cityset;
+    int type;
+    guint32 player_id;
+    PixMask* surface;
+};
+
+//the structure to store towers in
+struct TowerCacheItem
+{
+    guint32 cityset;
+    guint32 player_id;
+    PixMask* surface;
+};
+
+// the structure to store flags in
+struct FlagCacheItem
+{
+    guint32 tileset;
+    guint32 size;
+    guint32 player_id;
+    PixMask* surface;
+};
+
+// the structure to store selector images in
+struct SelectorCacheItem
+{
+    guint32 tileset;
+    guint32 type;
+    guint32 frame;
+    guint32 player_id;
+    PixMask* surface;
+};
+
+// the structure to store shield images in
+struct ShieldCacheItem
+{
+    guint32 shieldset;
+    guint32 type;
+    guint32 colour;
+    PixMask* surface;
+};
+
+// the structure to store production shield images in
+struct ProdShieldCacheItem
+{
+    guint32 type;
+    bool prod;
+    PixMask* surface;
+};
+
+// the structure to store movement bonus images in
+struct MoveBonusCacheItem
+{
+    guint32 type; // 0=empty, 1=trees, 2=foothills, 3=hills+trees, 4=fly, 5=boat
+    PixMask* surface;
+};
+
+// the structure to store drawn bigmap tiles in
+struct TileCacheItem
+{
+  int tile_style_id;
+  int fog_type_id;
+  bool has_bag;
+  bool has_standard;
+  int standard_player_id;
+  int stack_size; //flag size
+  int stack_player_id;
+  int army_type_id;
+  bool has_tower;
+  bool has_ship;
+  Maptile::Building building_type;
+  int building_subtype;
+  Vector<int> building_tile;
+  int building_player_id;
+  guint32 tilesize;
+  bool has_grid;
+  guint32 tileset;
+  guint32 cityset;
+  PixMask* surface;
+};
+
+struct PortCacheItem
+{
+  guint32 cityset;
+  PixMask *surface;
+};
+
+struct SignpostCacheItem
+{
+  guint32 cityset;
+  PixMask *surface;
+};
+
+struct BagCacheItem
+{
+  guint32 armyset;
+  PixMask *surface;
+};
+
+struct ExplosionCacheItem
+{
+  guint32 tileset;
+  PixMask *surface;
+};
+
+bool operator <(TileCacheItem lhs, TileCacheItem rhs)
+{
+  return memcmp(&lhs, &rhs, sizeof (TileCacheItem) - sizeof (PixMask*)) < 0;
+}
+//-----------------------------------------------------
+
+GraphicsCache* GraphicsCache::s_instance = 0;
+
+GraphicsCache* GraphicsCache::getInstance()
+{
+    if (!s_instance)
+        s_instance = new GraphicsCache();
+
+    return s_instance;
+}
+
+void GraphicsCache::deleteInstance()
+{
+    if (!s_instance)
+        return;
+
+    delete s_instance;
+    s_instance =0;
+}
+
+GraphicsCache::GraphicsCache()
+    :d_cachesize(0)
+{
+    loadDiplomacyPics();
+
+    loadCursorPics();
+    loadProdShields();
+    loadMoveBonusPics();
+    loadMedalPics();
+    loadNewLevelPics();
+
+    d_smallruinedcity = getMiscPicture("smallruinedcity.png");
+    d_smallhero = getMiscPicture("hero.png");
+    d_smallinactivehero = getMiscPicture("hero-inactive.png");
+    d_small_ruin_unexplored = getMiscPicture("smallunexploredruin.png");
+    d_small_stronghold_unexplored = 
+      getMiscPicture("smallunexploredstronghold.png");
+    d_small_ruin_explored = getMiscPicture("smallexploredruin.png");
+    d_small_temple = getMiscPicture("smalltemple.png");
+}
+
+GraphicsCache::~GraphicsCache()
+{
+    clear();
+
+    for (unsigned int i = 0; i < PRODUCTION_SHIELD_TYPES; i++)
+    {
+        delete d_prodshieldpic[i];
+    }
+
+    for (unsigned int i = 0; i < MOVE_BONUS_TYPES; i++)
+    {
+        delete d_movebonuspic[i];
+    }
+
+    delete d_smallruinedcity;
+    delete d_smallhero;
+    delete d_smallinactivehero;
+    delete d_small_temple;
+    delete d_small_ruin_unexplored;
+    delete d_small_stronghold_unexplored;
+    delete d_small_ruin_explored;
+    delete d_newlevel_male;
+    delete d_newlevel_female;
+    delete d_newlevelmask_male;
+    delete d_newlevelmask_female;
+}
+
+PixMask* GraphicsCache::getSmallRuinedCityPic()
+{
+  return d_smallruinedcity;
+}
+
+PixMask* GraphicsCache::getSmallHeroPic(bool active)
+{
+  if (active)
+    return d_smallhero;
+  else
+    return d_smallinactivehero;
+}
+
+PixMask* GraphicsCache::getSmallRuinExploredPic()
+{
+  return d_small_ruin_explored;
+}
+PixMask* GraphicsCache::getSmallRuinUnexploredPic()
+{
+  return d_small_ruin_unexplored;
+}
+PixMask* GraphicsCache::getSmallStrongholdUnexploredPic()
+{
+  return d_small_stronghold_unexplored;
+}
+PixMask* GraphicsCache::getSmallTemplePic()
+{
+  return d_small_temple;
+}
+
+PixMask* GraphicsCache::getMoveBonusPic(guint32 bonus, bool has_ship)
+{
+  guint32 type;
+  if (bonus == Tile::isFlying()) // show fly icon
+    type = 4; 
+  else if (bonus & Tile::FOREST && bonus & Tile::HILLS) // show trees and hills
+    type = 3;
+  else if (bonus & Tile::HILLS) // show foothills
+    type = 2;
+  else if (bonus & Tile::FOREST) // show trees
+    type = 1;
+  else if (has_ship) // (what a) show boat
+    type = 5;
+  else // show blank
+    type = 0;
+  debug("GraphicsCache::getMoveBonusPic " <<bonus <<"," <<type)
+
+  std::list<MoveBonusCacheItem*>::iterator it;
+  MoveBonusCacheItem* myitem;
+
+  for (it = d_movebonuslist.begin(); it != d_movebonuslist.end(); it++)
+  {
+      if ((*it)->type == type)
+      {
+          myitem = (*it);
+
+          //put the item in last place (last touched)
+          d_movebonuslist.erase(it);
+          d_movebonuslist.push_back(myitem);
+
+          return myitem->surface;
+      }
+    }
+
+    //no item found -> create a new one
+    myitem = addMoveBonusPic(type);
+
+    return myitem->surface;
+}
+
+PixMask* GraphicsCache::getShipPic(const Player* p)
+{
+    debug("getting ship pic " <<p->getName())
+    std::list<ShipCacheItem*>::iterator it;
+    ShipCacheItem* myitem;
+    for (it = d_shiplist.begin(); it != d_shiplist.end(); it++)
+    {
+        if ((*it)->player_id == p->getId() && (*it)->armyset == p->getArmyset())
+        {
+            myitem = (*it);
+            
+            // put the item on the last place (==last touched)
+            d_shiplist.erase(it);
+            d_shiplist.push_back(myitem);
+            
+            return myitem->surface;
+        }
+    }
+    // We are still here, so the graphic is not in the cache. addShipPic calls
+    // checkPictures on its own, so we can simply return the surface
+    myitem = addShipPic(p);
+
+    return myitem->surface;
+}
+
+PixMask* GraphicsCache::getNewLevelPic(const Player* p, guint32 gender)
+{
+    debug("getting new level pic " <<p->getName())
+    std::list<NewLevelCacheItem*>::iterator it;
+    NewLevelCacheItem* myitem;
+    for (it = d_newlevellist.begin(); it != d_newlevellist.end(); it++)
+    {
+        if ((*it)->player_id == p->getId() && (*it)->gender == gender)
+        {
+            myitem = (*it);
+            
+            // put the item on the last place (==last touched)
+            d_newlevellist.erase(it);
+            d_newlevellist.push_back(myitem);
+            
+            return myitem->surface;
+        }
+    }
+    // We are still here, so the graphic is not in the cache. 
+    // addNewLevelPic calls checkPictures on its own, so we can 
+    // simply return the surface
+    myitem = addNewLevelPic(p, gender);
+
+    return myitem->surface;
+}
+
+PixMask* GraphicsCache::getPortPic()
+{
+  return getPortPic(GameMap::getInstance()->getCityset()->getId());
+}
+
+PixMask* GraphicsCache::getPortPic(guint32 cityset)
+{
+    debug("getting port pic " << cityset)
+    std::list<PortCacheItem*>::iterator it;
+    PortCacheItem* myitem;
+    for (it = d_portlist.begin(); it != d_portlist.end(); it++)
+    {
+        if ((*it)->cityset == cityset)
+        {
+            myitem = (*it);
+            
+            // put the item on the last place (==last touched)
+            d_portlist.erase(it);
+            d_portlist.push_back(myitem);
+            
+            return myitem->surface;
+        }
+    }
+    // We are still here, so the graphic is not in the cache. 
+    // addPortPic calls checkPictures on its own, so we can 
+    // simply return the surface
+    myitem = addPortPic(cityset);
+
+    return myitem->surface;
+}
+
+PixMask* GraphicsCache::getSignpostPic()
+{
+  return getSignpostPic(GameMap::getInstance()->getCityset()->getId());
+}
+
+PixMask* GraphicsCache::getSignpostPic(guint32 cityset)
+{
+    debug("getting signpost pic " << cityset)
+    std::list<SignpostCacheItem*>::iterator it;
+    SignpostCacheItem* myitem;
+    for (it = d_signpostlist.begin(); it != d_signpostlist.end(); it++)
+    {
+        if ((*it)->cityset == cityset)
+        {
+            myitem = (*it);
+            
+            // put the item on the last place (==last touched)
+            d_signpostlist.erase(it);
+            d_signpostlist.push_back(myitem);
+            
+            return myitem->surface;
+        }
+    }
+    // We are still here, so the graphic is not in the cache. 
+    // addSignpostPic calls checkPictures on its own, so we can 
+    // simply return the surface
+    myitem = addSignpostPic(cityset);
+
+    return myitem->surface;
+}
+
+PixMask* GraphicsCache::getBagPic()
+{
+  guint32 armyset = Playerlist::getActiveplayer()->getArmyset();
+  return getBagPic(armyset);
+}
+
+PixMask* GraphicsCache::getBagPic(guint32 armyset)
+{
+    debug("getting bag pic " << armyset)
+    std::list<BagCacheItem*>::iterator it;
+    BagCacheItem* myitem;
+    for (it = d_baglist.begin(); it != d_baglist.end(); it++)
+    {
+        if ((*it)->armyset == armyset)
+        {
+            myitem = (*it);
+            
+            // put the item on the last place (==last touched)
+            d_baglist.erase(it);
+            d_baglist.push_back(myitem);
+            
+            return myitem->surface;
+        }
+    }
+    // We are still here, so the graphic is not in the cache. 
+    // addBagPic calls checkPictures on its own, so we can 
+    // simply return the surface
+    myitem = addBagPic(armyset);
+
+    return myitem->surface;
+}
+
+PixMask* GraphicsCache::getExplosionPic()
+{
+  return getExplosionPic(GameMap::getInstance()->getTileset()->getId());
+}
+
+PixMask* GraphicsCache::getExplosionPic(guint32 tileset)
+{
+    debug("getting explosion pic " << tileset)
+    std::list<ExplosionCacheItem*>::iterator it;
+    ExplosionCacheItem* myitem;
+    for (it = d_explosionlist.begin(); it != d_explosionlist.end(); it++)
+    {
+        if ((*it)->tileset == tileset)
+        {
+            myitem = (*it);
+            
+            // put the item on the last place (==last touched)
+            d_explosionlist.erase(it);
+            d_explosionlist.push_back(myitem);
+            
+            return myitem->surface;
+        }
+    }
+    // We are still here, so the graphic is not in the cache. 
+    // addExplosionPic calls checkPictures on its own, so we can 
+    // simply return the surface
+    myitem = addExplosionPic(tileset);
+
+    return myitem->surface;
+}
+
+PixMask* GraphicsCache::getPlantedStandardPic(const Player* p)
+{
+    debug("getting planted standard pic " <<p->getName())
+    std::list<PlantedStandardCacheItem*>::iterator it;
+    PlantedStandardCacheItem* myitem;
+    for (it = d_plantedstandardlist.begin(); it != d_plantedstandardlist.end(); it++)
+    {
+        if ((*it)->player_id == p->getId() && (*it)->armyset == p->getArmyset())
+        {
+            myitem = (*it);
+            
+            // put the item on the last place (==last touched)
+            d_plantedstandardlist.erase(it);
+            d_plantedstandardlist.push_back(myitem);
+            
+            return myitem->surface;
+        }
+    }
+    // We are still here, so the graphic is not in the cache. 
+    // addPlantedStandardPic calls checkPictures on its own, so we can 
+    // simply return the surface
+    myitem = addPlantedStandardPic(p);
+
+    return myitem->surface;
+}
+
+PixMask* GraphicsCache::getArmyPic(Army *a, bool greyed)
+{
+  return getArmyPic(a->getOwner()->getArmyset(), a->getTypeId(), 
+                   a->getOwner(), NULL, greyed);
+}
+
+PixMask* GraphicsCache::getArmyPic(guint32 armyset, guint32 army_id, 
+                                  const Player* p, const bool *medals,
+                                  bool greyed)
+{
+  debug("getting army pic " <<armyset <<" " <<army <<" " <<p->getName() << 
+    " "  << greyed)
+
+    std::list<ArmyCacheItem*>::iterator it;
+    ArmyCacheItem* myitem;
+
+    // important: medals can be 0 in special cases
+    bool my_medals[3] = {0,0,0};
+    if (medals)
+        for (int i = 0; i < 3; i++)
+            my_medals[i] = medals[i];
+
+    // special situation: ruin keepers don't belong to any player
+    // we don't actually show them, but what the heck
+    if (!p)
+        p = Playerlist::getInstance()->getNeutral();
+    
+    ArmyCacheItem item = ArmyCacheItem();
+    item.armyset = armyset;
+    item.army_id = army_id;
+    item.player_id = p->getId();
+    item.medals[0] = my_medals[0];
+    item.medals[1] = my_medals[1];
+    item.medals[2] = my_medals[2];
+    item.greyed = greyed;
+    ArmyMap::iterator mit = d_armymap.find(item);
+    if (mit != d_armymap.end())
+      {
+       std::list<ArmyCacheItem*>::iterator it = (*mit).second;
+       myitem = *it;
+       d_armylist.erase(it);
+       d_armylist.push_back(myitem);
+       it = d_armylist.end();
+       it--;
+       d_armymap[*myitem] = it;
+       return myitem->surface;
+      }
+
+    // We are still here, so the graphic is not in the cache. addArmyPic calls
+    // checkPictures on its own, so we can simply return the surface
+    debug("getarmypic============= " << my_medals) 
+    myitem = addArmyPic(&item);
+
+    return myitem->surface;
+}
+
+PixMask* GraphicsCache::getTilePic(int tile_style_id, int fog_type_id, bool has_bag, bool has_standard, int standard_player_id, int stack_size, int stack_player_id, int army_type_id, bool has_tower, bool has_ship, Maptile::Building building_type, int building_subtype, Vector<int> building_tile, int building_player_id, guint32 tilesize, bool has_grid)
+{
+  guint32 tileset = GameMap::getInstance()->getTileset()->getId();
+  guint32 cityset = GameMap::getInstance()->getCityset()->getId();
+  return getTilePic(tile_style_id, fog_type_id, has_bag, has_standard, standard_player_id, stack_size, stack_player_id, army_type_id, has_tower, has_ship, building_type, building_subtype, building_tile, building_player_id, tilesize, has_grid, tileset, cityset);
+}
+
+PixMask* GraphicsCache::getTilePic(int tile_style_id, int fog_type_id, bool has_bag, bool has_standard, int standard_player_id, int stack_size, int stack_player_id, int army_type_id, bool has_tower, bool has_ship, Maptile::Building building_type, int building_subtype, Vector<int> building_tile, int building_player_id, guint32 tilesize, bool has_grid, guint32 tileset, guint32 cityset)
+{
+    debug("getting tile pic " << tile_style_id << " " <<
+         fog_type_id << " " << has_bag << " " << has_standard << " " <<
+         standard_player_id << " " << stack_size << " " << stack_player_id <<
+         " " << army_type_id << " " << has_tower << " " << has_ship << " " << 
+         building_type << " " << building_subtype << " " << building_tile.x 
+         << "," << building_tile.y << " " << building_player_id << " " << 
+         tilesize << " " << has_grid << " " <<tileset);
+
+    std::list<TileCacheItem*>::iterator it;
+    TileCacheItem* myitem;
+
+    TileCacheItem item = TileCacheItem();
+    item.tilesize = tilesize;
+    item.tile_style_id = tile_style_id;
+    item.has_bag = has_bag;
+    item.has_standard = has_standard;
+    item.standard_player_id = standard_player_id;
+    item.stack_size = stack_size;
+    item.stack_player_id = stack_player_id;
+    item.army_type_id = army_type_id;
+    item.has_tower = has_tower;
+    item.has_ship = has_ship;
+    item.building_type= building_type;
+    item.building_subtype= building_subtype;
+    item.building_tile = building_tile;
+    item.building_player_id = building_player_id;
+    item.has_grid = has_grid;
+    item.fog_type_id = fog_type_id;
+    item.tileset = tileset;
+    item.cityset = cityset;
+    TileMap::iterator mit = d_tilemap.find(item);
+    if (mit != d_tilemap.end())
+      {
+       std::list<TileCacheItem*>::iterator it = (*mit).second;
+       myitem = *it;
+       d_tilelist.erase(it);
+       d_tilelist.push_back(myitem);
+       it = d_tilelist.end();
+       it--;
+       d_tilemap[*myitem] = it;
+       return myitem->surface;
+      }
+
+    // We are still here, so the graphic is not in the cache. addTilePic calls
+    // checkPictures on its own, so we can simply return the surface
+    myitem = addTilePic(&item);
+
+    return myitem->surface;
+}
+
+PixMask* GraphicsCache::getShieldPic(guint32 shieldset, guint32 type, 
+                                    guint32 colour)
+{
+    debug("getting shield pic " <<shieldset <<" " <<type <<" " <<colour)
+
+    std::list<ShieldCacheItem*>::iterator it;
+    ShieldCacheItem* myitem;
+
+    for (it =d_shieldlist.begin(); it != d_shieldlist.end(); it++)
+    {
+        if ((*it)->shieldset == shieldset && (*it)->type == type
+            && (*it)->colour == colour)
+        {
+            myitem = (*it);
+            
+            // put the item on the last place (==last touched)
+            d_shieldlist.erase(it);
+            d_shieldlist.push_back(myitem);
+            
+            return myitem->surface;
+        }
+    }
+
+    // We are still here, so the graphic is not in the cache. addShieldPic calls
+    // checkPictures on its own, so we can simply return the surface
+    myitem = addShieldPic(shieldset, type, colour);
+
+    return myitem->surface;
+}
+        
+PixMask* GraphicsCache::getShieldPic(guint32 type, Player *p)
+{
+  guint32 shieldset = GameMap::getInstance()->getShieldset()->getId();
+  return getShieldPic(shieldset, type, p->getId());
+}
+
+PixMask* GraphicsCache::getTemplePic(int type)
+{
+  guint32 cityset = GameMap::getInstance()->getCityset()->getId();
+  return getTemplePic(type, cityset);
+}
+PixMask* GraphicsCache::getTemplePic(int type, guint32 cityset)
+{
+    debug("GraphicsCache::getTemplePic " <<type)
+
+    std::list<TempleCacheItem*>::iterator it;
+    TempleCacheItem* myitem;
+
+    for (it = d_templelist.begin(); it != d_templelist.end(); it++)
+    {
+        if ((*it)->type == type && (*it)->cityset == cityset)
+        {
+            myitem = (*it);
+
+            //put the item in last place (last touched)
+            d_templelist.erase(it);
+            d_templelist.push_back(myitem);
+
+            return myitem->surface;
+        }
+    }
+
+    //no item found -> create a new one
+    myitem = addTemplePic(type, cityset);
+
+    return myitem->surface;
+}
+
+PixMask* GraphicsCache::getRuinPic(int type)
+{
+  guint32 cityset = GameMap::getInstance()->getCityset()->getId();
+  return getRuinPic(type, cityset);
+}
+PixMask* GraphicsCache::getRuinPic(int type, guint32 cityset)
+{
+    debug("GraphicsCache::getRuinPic " <<type)
+
+    std::list<RuinCacheItem*>::iterator it;
+    RuinCacheItem* myitem;
+
+    for (it = d_ruinlist.begin(); it != d_ruinlist.end(); it++)
+    {
+        if ((*it)->type == type && (*it)->cityset == cityset)
+        {
+            myitem = (*it);
+
+            //put the item in last place (last touched)
+            d_ruinlist.erase(it);
+            d_ruinlist.push_back(myitem);
+
+            return myitem->surface;
+        }
+    }
+
+    //no item found -> create a new one
+    myitem = addRuinPic(type, cityset);
+
+    return myitem->surface;
+}
+
+PixMask* GraphicsCache::getDiplomacyPic(int type, Player::DiplomaticState state)
+{
+    debug("GraphicsCache::getDiplomaticPic " <<type << ", " << state)
+
+    std::list<DiplomacyCacheItem*>::iterator it;
+    DiplomacyCacheItem* myitem;
+
+    for (it = d_diplomacylist.begin(); it != d_diplomacylist.end(); it++)
+    {
+        if ((*it)->type == type && (*it)->state == state)
+        {
+            myitem = (*it);
+
+            //put the item in last place (last touched)
+            d_diplomacylist.erase(it);
+            d_diplomacylist.push_back(myitem);
+
+            return myitem->surface;
+        }
+    }
+
+    //no item found -> create a new one
+    myitem = addDiplomacyPic(type, state);
+
+    return myitem->surface;
+}
+
+PixMask* GraphicsCache::getRoadPic(int type)
+{
+  return getRoadPic(type, GameMap::getInstance()->getTileset()->getId());
+}
+PixMask* GraphicsCache::getRoadPic(int type, guint32 tileset)
+{
+    debug("GraphicsCache::getRoadPic " <<type)
+
+    std::list<RoadCacheItem*>::iterator it;
+    RoadCacheItem* myitem;
+
+    for (it = d_roadlist.begin(); it != d_roadlist.end(); it++)
+    {
+        if ((*it)->type == type && (*it)->tileset == tileset)
+        {
+            myitem = (*it);
+
+            //put the item in last place (last touched)
+            d_roadlist.erase(it);
+            d_roadlist.push_back(myitem);
+
+            return myitem->surface;
+        }
+    }
+
+    //no item found -> create a new one
+    myitem = addRoadPic(type, tileset);
+
+    return myitem->surface;
+}
+
+PixMask* GraphicsCache::getFogPic(int type)
+{
+  return getFogPic(type, GameMap::getInstance()->getTileset()->getId());
+}
+
+PixMask* GraphicsCache::getFogPic(int type, guint32 tileset)
+{
+    debug("GraphicsCache::getFogPic " <<type)
+
+    std::list<FogCacheItem*>::iterator it;
+    FogCacheItem* myitem;
+
+    FogCacheItem item = FogCacheItem();
+    item.type = type;
+    item.tileset = tileset;
+    FogCacheMap::iterator mit = d_fogmap.find(item);
+    if (mit != d_fogmap.end())
+      {
+       std::list<FogCacheItem*>::iterator it = (*mit).second;
+       myitem = *it;
+       d_foglist.erase(it);
+       d_foglist.push_back(myitem);
+       it = d_foglist.end();
+       it--;
+       d_fogmap[*myitem] = it;
+       return myitem->surface;
+      }
+
+    //no item found -> create a new one
+    myitem = addFogPic(&item);
+
+    return myitem->surface;
+}
+
+PixMask* GraphicsCache::getBridgePic(int type)
+{
+  return getBridgePic(type, GameMap::getInstance()->getTileset()->getId());
+}
+PixMask* GraphicsCache::getBridgePic(int type, guint32 tileset)
+{
+    debug("GraphicsCache::getBridgePic " <<type)
+
+    std::list<BridgeCacheItem*>::iterator it;
+    BridgeCacheItem* myitem;
+
+    for (it = d_bridgelist.begin(); it != d_bridgelist.end(); it++)
+    {
+        if ((*it)->type == type && (*it)->tileset == tileset)
+        {
+            myitem = (*it);
+
+            //put the item in last place (last touched)
+            d_bridgelist.erase(it);
+            d_bridgelist.push_back(myitem);
+
+            return myitem->surface;
+        }
+    }
+
+    //no item found -> create a new one
+    myitem = addBridgePic(type, tileset);
+
+    return myitem->surface;
+}
+
+PixMask* GraphicsCache::getCursorPic(int type)
+{
+    debug("GraphicsCache::getCursorPic " <<type)
+
+    std::list<CursorCacheItem*>::iterator it;
+    CursorCacheItem* myitem;
+
+    for (it = d_cursorlist.begin(); it != d_cursorlist.end(); it++)
+    {
+        if ((*it)->type == type)
+        {
+            myitem = (*it);
+
+            //put the item in last place (last touched)
+            d_cursorlist.erase(it);
+            d_cursorlist.push_back(myitem);
+
+            return myitem->surface;
+        }
+    }
+
+    //no item found -> create a new one
+    myitem = addCursorPic(type);
+
+    return myitem->surface;
+}
+
+PixMask* GraphicsCache::getCityPic(const City* city, guint32 cityset)
+{
+  if (!city)
+    return NULL;
+  int type;
+  if (city->isBurnt() == true)
+    type = -1;
+  else
+    type = 0;
+  return getCityPic(type, city->getOwner(), cityset);
+}
+
+PixMask* GraphicsCache::getCityPic(const City* city)
+{
+  guint32 cityset = GameMap::getInstance()->getCityset()->getId();
+  return getCityPic(city, cityset);
+}
+
+PixMask* GraphicsCache::getCityPic(int type, const Player* p, guint32 cityset)
+{
+    debug("GraphicsCache::getCityPic " <<type)
+
+    std::list<CityCacheItem*>::iterator it;
+    CityCacheItem* myitem;
+
+    for (it = d_citylist.begin(); it != d_citylist.end(); it++)
+    {
+        if ((*it)->type == type && (*it)->cityset == cityset &&
+           (*it)->player_id == p->getId())
+        {
+            myitem = (*it);
+
+            //put the item in last place (last touched)
+            d_citylist.erase(it);
+            d_citylist.push_back(myitem);
+
+            return myitem->surface;
+        }
+    }
+
+    //no item found -> create a new one
+    myitem = addCityPic(type, p, cityset);
+
+    return myitem->surface;
+}
+
+PixMask* GraphicsCache::getTowerPic(const Player* p)
+{
+  guint32 cityset = GameMap::getInstance()->getCityset()->getId();
+  return getTowerPic(p, cityset);
+}
+
+PixMask* GraphicsCache::getTowerPic(const Player* p, guint32 cityset)
+{
+    debug("GraphicsCache::getTowerPic player " <<p->getName())
+
+    std::list<TowerCacheItem*>::iterator it;
+    TowerCacheItem* myitem;
+
+    for (it = d_towerlist.begin(); it != d_towerlist.end(); it++)
+    {
+        if ((*it)->cityset == cityset && (*it)->player_id == p->getId())
+        {
+            myitem = (*it);
+
+            //put the item in last place (last touched)
+            d_towerlist.erase(it);
+            d_towerlist.push_back(myitem);
+
+            return myitem->surface;
+        }
+    }
+
+    //no item found -> create a new one
+    myitem = addTowerPic(p, cityset);
+
+    return myitem->surface;
+}
+
+PixMask* GraphicsCache::getFlagPic(guint32 stack_size, const Player *p, guint32 tileset)
+{
+  if (stack_size > MAX_STACK_SIZE || p == NULL || tileset == 0)
+    return NULL;
+    debug("GraphicsCache::getFlagPic " <<stack_size <<", player" <<p->getId())
+
+    std::list<FlagCacheItem*>::iterator it;
+    FlagCacheItem* myitem;
+
+    for (it = d_flaglist.begin(); it != d_flaglist.end(); it++)
+    {
+        myitem = *it;
+        if (myitem->size == stack_size && myitem->player_id == p->getId() &&
+           myitem->tileset == tileset)
+        {
+            // put the item in last place (last touched)
+            d_flaglist.erase(it);
+            d_flaglist.push_back(myitem);
+
+            return myitem->surface;
+        }
+    }
+
+    // no item found => create a new one
+    myitem = addFlagPic(stack_size, p, tileset);
+
+    return myitem->surface;
+}
+PixMask* GraphicsCache::getFlagPic(guint32 stack_size, const Player *p)
+{
+  return getFlagPic(stack_size, p, 
+                   GameMap::getInstance()->getTileset()->getId());
+}
+
+PixMask* GraphicsCache::getFlagPic(const Stack* s)
+{
+  return getFlagPic(s, GameMap::getInstance()->getTileset()->getId());
+}
+PixMask* GraphicsCache::getFlagPic(const Stack* s, guint32 tileset)
+{
+    if (!s)
+    {
+        std::cerr << "GraphicsCache::getFlagPic: no stack supplied! Exiting...\n";
+        exit(-1);
+    }
+    
+  return getFlagPic(s->size(), s->getOwner(), tileset);
+}
+
+PixMask* GraphicsCache::getSelectorPic(guint32 type, guint32 frame, 
+                                          const Player *p)
+{
+  return getSelectorPic(type, frame, p, 
+                       GameMap::getInstance()->getTileset()->getId());
+}
+PixMask* GraphicsCache::getSelectorPic(guint32 type, guint32 frame, 
+                                          const Player *p, guint32 tileset)
+{
+    debug("GraphicsCache::getSelectorPic " <<type <<", " << frame << ", player" <<s->getOwner()->getName())
+
+    if (!p)
+    {
+        std::cerr << "GraphicsCache::getSelectorPic: no player supplied! Exiting...\n";
+        exit(-1);
+    }
+    
+    std::list<SelectorCacheItem*>::iterator it;
+    SelectorCacheItem* myitem;
+
+    for (it = d_selectorlist.begin(); it != d_selectorlist.end(); it++)
+    {
+        myitem = *it;
+        if ((myitem->type == type) && (myitem->player_id == p->getId()) 
+           && myitem->frame == frame && myitem->tileset == tileset)
+        {
+            // put the item in last place (last touched)
+            d_selectorlist.erase(it);
+            d_selectorlist.push_back(myitem);
+
+            return myitem->surface;
+        }
+    }
+
+    // no item found => create a new one
+    myitem = addSelectorPic(type, frame, p, tileset);
+
+    return myitem->surface;
+}
+
+
+PixMask* GraphicsCache::getProdShieldPic(guint32 type, bool prod)
+{
+    debug("GraphicsCache::getProdShieldPic " <<type <<", " << ", prod " <<prod)
+
+    std::list<ProdShieldCacheItem*>::iterator it;
+    ProdShieldCacheItem* myitem;
+
+    for (it = d_prodshieldlist.begin(); it != d_prodshieldlist.end(); it++)
+    {
+        myitem = *it;
+        if ((myitem->type == type) && (myitem->prod == prod))
+        {
+            // put the item in last place (last touched)
+            d_prodshieldlist.erase(it);
+            d_prodshieldlist.push_back(myitem);
+
+            return myitem->surface;
+        }
+    }
+
+    // no item found => create a new one
+    myitem = addProdShieldPic(type, prod);
+
+    return myitem->surface;
+}
+
+
+PixMask* GraphicsCache::applyMask(PixMask* image, PixMask* mask, Gdk::Color colour, bool isNeutral)
+{
+  int width = image->get_width();
+  int height = image->get_height();
+  PixMask* result = PixMask::create(image->to_pixbuf());
+  if (mask->get_width() != width || (mask->get_height()) != height)
+    {
+      std::cerr <<"Warning: mask and original image do not match\n";
+      return NULL;
+    }
+  if (isNeutral)
+    return result;
+  
+  Glib::RefPtr<Gdk::Pixbuf> maskbuf = mask->to_pixbuf();
+
+  guint8 *data = maskbuf->get_pixels();
+  guint8 *copy = (guint8*)  malloc (height * width * 4 * sizeof(guint8));
+  memcpy(copy, data, height * width * 4 * sizeof(guint8));
+  for (int i = 0; i < width; i++)
+    for (int j = 0; j < height; j++)
+      {
+       const int base = (j * 4) + (i * height * 4);
+
+       if (copy[base+3] != 0)
+         {
+           copy[base+0] = colour.get_red_p() *copy[base+0];
+           copy[base+1] = colour.get_green_p() * copy[base+1];
+           copy[base+2] = colour.get_blue_p() * copy[base+2];
+         }
+      }
+  Glib::RefPtr<Gdk::Pixbuf> colouredmask = 
+    Gdk::Pixbuf::create_from_data(copy, Gdk::COLORSPACE_RGB, true, 8, 
+                                 width, height, width * 4);
+  result->draw_pixbuf(colouredmask, 0, 0, 0, 0, width, height);
+  free(copy);
+
+  return result;
+}
+
+PixMask* GraphicsCache::greyOut(PixMask* image)
+{
+  int width = image->get_width();
+  int height = image->get_height();
+  PixMask* result = PixMask::create(image->to_pixbuf());
+  
+  guint8 *data = result->to_pixbuf()->get_pixels();
+  guint8 *copy = (guint8*)  malloc (height * width * 4 * sizeof(guint8));
+  memcpy(copy, data, height * width * 4 * sizeof(guint8));
+  for (int i = 0; i < width; i++)
+    for (int j = 0; j < height; j++)
+      {
+       const int base = (j * 4) + (i * height * 4);
+
+       if (data[base+3] != 0)
+         {
+           guint32 max = 0;
+           if (copy[base+0] > max)
+             max = copy[base+0];
+           else if (copy[base+1] > max)
+             max = copy[base+1];
+           else if (copy[base+2] > max)
+             max = copy[base+2];
+           int x =  i % 2;
+           int y = j % 2;
+           if ((x == 0 && y == 0) || (x == 1 && y == 1))
+             max = 88;
+           copy[base+0] = max;
+           copy[base+1] = max;
+           copy[base+2] = max;
+         }
+      }
+  Glib::RefPtr<Gdk::Pixbuf> greyed_out =  
+    Gdk::Pixbuf::create_from_data(copy, Gdk::COLORSPACE_RGB, true, 8, 
+                                 width, height, width * 4);
+
+  result->draw_pixbuf(greyed_out, 0, 0, 0, 0, width, height);
+  free(copy);
+
+  return result;
+}
+
+PixMask* GraphicsCache::applyMask(PixMask* image, PixMask* mask, const Player* p)
+{
+  return applyMask(image, mask, p->getColor(),
+                  Playerlist::getInstance()->getNeutral()->getId() == p->getId());
+}
+
+void GraphicsCache::checkPictures()
+{
+  // for security, we always take a minimum cache size of 2MB. This
+  // includes (at 4 byte color depth and assuming 64x64 pixel size)
+  // - 10 cities (each 64kb => 640kb)
+  // - 20 flags (each 16kb => 320kb)
+  // - 40 units (each 16kb => 640kb)
+  // + a bit more. The problem is that if we have less images than needed
+  // for a single rendering, the surfaces will become invalid before actually
+  // used. This should not be a problem with the normal map (the surfaces are
+  // copied and discarded), but when selecting armies from armyset, where
+  // you can have these images assigned to buttons.
+  guint32 maxcache = Configuration::s_cacheSize;
+  if (maxcache < (1<<21))
+    maxcache = (1<<21);
+
+  if (d_cachesize < maxcache)
+    return;
+
+
+  // Now the cache size has been exceeded. We try to guarantee the values
+  // given above and reduce the number of images. Let us start with the
+  // cities
+
+  while (d_citylist.size() > 10)
+    eraseLastCityItem();
+
+  while (d_towerlist.size() > 10)
+    eraseLastTowerItem();
+
+  while (d_shiplist.size() > 10)
+    eraseLastShipItem();
+
+  while (d_plantedstandardlist.size() > 10)
+    eraseLastPlantedStandardItem();
+
+  while (d_newlevellist.size() > 10)
+    eraseLastNewLevelItem();
+
+  while (d_templelist.size() > 10)
+    eraseLastTempleItem();
+
+  while (d_ruinlist.size() > 10)
+    eraseLastRuinItem();
+
+  while (d_diplomacylist.size() > 10)
+    eraseLastDiplomacyItem();
+
+  while (d_roadlist.size() > 18)
+    eraseLastRoadItem();
+
+  while (d_foglist.size() > 16)
+    eraseLastFogItem();
+
+  while (d_bridgelist.size() > 10)
+    eraseLastBridgeItem();
+
+  while (d_cursorlist.size() > 10)
+    eraseLastCursorItem();
+
+  // was this enough?
+  if (d_cachesize < maxcache)
+    return;
+
+  // next, kill flag pics
+  while (d_flaglist.size() > 20)
+    eraseLastFlagItem();
+
+  if (d_cachesize < maxcache)
+    return;
+
+  // next, kill selector pics
+  while (d_selectorlist.size() > 20)
+    eraseLastSelectorItem();
+
+  if (d_cachesize < maxcache)
+    return;
+
+  // next, kill shield pics
+  while (d_shieldlist.size() > 20)
+    eraseLastShieldItem();
+
+  if (d_cachesize < maxcache)
+    return;
+
+  // next, kill production shield pics
+  while (d_prodshieldlist.size() > 20)
+    eraseLastProdShieldItem();
+
+  if (d_cachesize < maxcache)
+    return;
+
+  // next, kill port pics
+  while (d_portlist.size() > 1)
+    eraseLastPortItem();
+
+  if (d_cachesize < maxcache)
+    return;
+
+  // next, kill signpost pics
+  while (d_signpostlist.size() > 1)
+    eraseLastSignpostItem();
+
+  if (d_cachesize < maxcache)
+    return;
+
+  // next, kill bag pics
+  while (d_baglist.size() > 1)
+    eraseLastBagItem();
+
+  if (d_cachesize < maxcache)
+    return;
+
+  // next, kill explosion pics
+  while (d_explosionlist.size() > 1)
+    eraseLastExplosionItem();
+
+  if (d_cachesize < maxcache)
+    return;
+
+  // next, kill movement bonus pics
+  while (d_movebonuslist.size() > 20)
+    eraseLastMoveBonusItem();
+
+  if (d_cachesize < maxcache)
+    return;
+
+  // still not enough? Erase tile images
+  while (d_tilelist.size() > 200)
+    eraseLastTileItem();
+
+  // still not enough? Erase army images
+  while (d_armylist.size() > 40)
+    eraseLastArmyItem();
+
+}
+
+void GraphicsCache::drawTilePic(PixMask *surface, int fog_type_id, bool has_bag, bool has_standard, int standard_player_id, int stack_size, int stack_player_id, int army_type_id, bool has_tower, bool has_ship, Maptile::Building building_type, int building_subtype, Vector<int> building_tile, int building_player_id, guint32 ts, bool has_grid, guint32 tileset, guint32 cityset)
+{
+  const Player *player;
+  Glib::RefPtr<Gdk::Pixmap> pixmap = surface->get_pixmap();
+
+  switch (building_type)
+    {
+    case Maptile::CITY:
+       {
+         player = Playerlist::getInstance()->getPlayer(building_player_id);
+         getCityPic(building_subtype, player, cityset)->blit(building_tile, ts, pixmap);
+       }
+      break;
+    case Maptile::RUIN:
+      getRuinPic(building_subtype, cityset)->blit(building_tile, ts, pixmap); break;
+    case Maptile::TEMPLE:
+      getTemplePic(building_subtype, cityset)->blit(building_tile, ts, pixmap); break;
+    case Maptile::SIGNPOST:
+      getSignpostPic(cityset)->blit(building_tile, ts, pixmap); break;
+    case Maptile::ROAD:
+      getRoadPic(building_subtype)->blit(building_tile, ts, pixmap); break;
+    case Maptile::PORT:
+      getPortPic(cityset)->blit(building_tile, ts, pixmap); break;
+    case Maptile::BRIDGE:
+      getBridgePic(building_subtype)->blit(building_tile, ts, pixmap); break;
+      break;
+    case Maptile::NONE: default:
+      break;
+    }
+
+  if (has_standard)
+    {
+      player = Playerlist::getInstance()->getPlayer(standard_player_id) ;
+      getPlantedStandardPic(player)->blit(pixmap);
+    }
+
+  if (has_bag)
+    {
+      PixMask *pic = getBagPic();
+      Vector<int>bagsize = Vector<int>(pic->get_width(), pic->get_height());
+      pic->blit(pixmap, Vector<int>(ts,ts)-bagsize);
+    }
+
+  if (stack_player_id > -1)
+    {
+      player = Playerlist::getInstance()->getPlayer(stack_player_id);
+      if (has_tower)
+       getTowerPic(player)->blit(pixmap);
+      else
+       {
+         if (stack_size > -1)
+           getFlagPic(stack_size, player)->blit(pixmap);
+         if (has_ship)
+           getShipPic(player)->blit(pixmap);
+         else
+           getArmyPic(player->getArmyset(), army_type_id, player, NULL)->blit(pixmap);
+       }
+    }
+  if (has_grid)
+    {
+      Glib::RefPtr<Gdk::GC> context = surface->get_gc();
+      Gdk::Color line_color = Gdk::Color();
+      line_color.set_rgb_p(0,0,0);
+      context->set_rgb_fg_color(line_color);
+      pixmap->draw_rectangle(context, false, 0, 0, ts, ts);
+    }
+
+  if (fog_type_id)
+    {
+      Tileset *t= 
+       Tilesetlist::getInstance()->getTileset(tileset);
+      t->getFogImage(fog_type_id - 1)->blit(pixmap);
+    }
+}
+
+TileCacheItem* GraphicsCache::addTilePic(TileCacheItem *item)
+{
+    
+  debug("ADD tile pic " << " " << item->tile_style_id << " " <<
+       item->fog_type_id << " " << item->has_bag << " " << 
+       item->has_standard << " " << item->standard_player_id << " " << 
+       item->stack_size << " " << item->stack_player_id <<
+       " " << item->army_type_id << " " << item->has_tower << " " << 
+       item->has_ship << " " << item->building_type << " " << 
+       item->building_subtype << " " << item->building_tile.x << 
+       "," << item->building_tile.y << " " << item->building_player_id << 
+       " " << item->tilesize << " " << item->has_grid << " " << item->tileset
+       " " << item->cityset);
+
+  TileCacheItem* myitem = new TileCacheItem();
+  *myitem = *item;
+
+  //short circuit the drawing sequence if the tile is completely obscured
+  Tileset *t = Tilesetlist::getInstance()->getTileset(item->tileset);
+  if (myitem->fog_type_id == FogMap::ALL)
+    myitem->surface = t->getFogImage(myitem->fog_type_id - 1)->copy();
+  else
+    {
+      myitem->surface = 
+       t->getTileStyle(myitem->tile_style_id)->getImage()->copy();
+    
+      drawTilePic(myitem->surface, myitem->fog_type_id, myitem->has_bag, 
+                 myitem->has_standard, myitem->standard_player_id, 
+                 myitem->stack_size, myitem->stack_player_id, 
+                 myitem->army_type_id, myitem->has_tower, myitem->has_ship, 
+                 myitem->building_type, myitem->building_subtype, 
+                 myitem->building_tile, myitem->building_player_id, 
+                 myitem->tilesize, myitem->has_grid, myitem->tileset,
+                 myitem->cityset);
+    }
+
+  //now the final preparation steps:
+  //a) add the size
+  int size = myitem->surface->get_width() * myitem->surface->get_height();
+  d_cachesize += myitem->surface->get_depth()/8 * size;
+
+  //b) add the entry to the list
+  d_tilelist.push_back(myitem);
+  std::list<TileCacheItem*>::iterator it = d_tilelist.end();
+  it--;
+  d_tilemap[*myitem] = it;
+
+  //c) check if the cache size is too large
+  checkPictures();
+
+  //we are finished, so return the pic
+  return myitem;
+}
+
+ArmyCacheItem* GraphicsCache::addArmyPic(ArmyCacheItem *item)
+{
+  debug("ADD army pic: " <<item->armyset <<"," <<item->army_id)
+
+  ArmyCacheItem* myitem = new ArmyCacheItem();
+  *myitem = *item;
+
+  const ArmyProto * basearmy = 
+    Armysetlist::getInstance()->getArmy(myitem->armyset, myitem->army_id);
+
+  // copy the pixmap including player colors
+  Player *p = Playerlist::getInstance()->getPlayer(myitem->player_id);
+  Shield::Colour c = Shield::Colour(p->getId());
+  PixMask *coloured = applyMask(basearmy->getImage(c), basearmy->getMask(c), p);
+  if (myitem->greyed)
+    {
+      PixMask *greyed_out = greyOut(coloured);
+      myitem->surface = greyed_out;
+      delete coloured;
+    }
+  else
+      myitem->surface = coloured;
+
+  if (myitem->medals != NULL)
+    {
+      debug("medalsbonus============= " << medalsbonus); 
+      for(int i=0;i<3;i++)
+       { 
+         if (myitem->medals[i])
+           d_medalpic[0][i]->blit(myitem->surface->get_pixmap());
+       }
+    }
+
+  //now the final preparation steps:
+  //a) add the size
+  int size = myitem->surface->get_width() * myitem->surface->get_height();
+  d_cachesize += myitem->surface->get_depth()/8 * size;
+
+  //b) add the entry to the list
+  d_armylist.push_back(myitem);
+  std::list<ArmyCacheItem*>::iterator it = d_armylist.end();
+  it--;
+  d_armymap[*myitem] = it;
+
+  //c) check if the cache size is too large
+  checkPictures();
+
+  //we are finished, so return the pic
+  return myitem;
+}
+
+ShieldCacheItem* GraphicsCache::addShieldPic(guint32 shieldset, guint32 type, 
+                                            guint32 colour)
+{
+  debug("ADD shield pic: " <<shieldset <<"," <<type <<"," <<colour)
+
+  ShieldCacheItem* myitem = new ShieldCacheItem();
+  myitem->shieldset = shieldset;
+  myitem->type = type;
+  myitem->colour = colour;
+
+  ShieldStyle *sh;
+  sh = Shieldsetlist::getInstance()->getShield(shieldset, type, colour);
+
+  // copy the pixmap including player colors
+  //lookup the shieldstyle
+  myitem->surface = applyMask(sh->getImage(), sh->getMask(), 
+                             Playerlist::getInstance()->getPlayer(colour));
+
+  //now the final preparation steps:
+  //a) add the size
+  int size = myitem->surface->get_width() * myitem->surface->get_height();
+  d_cachesize += myitem->surface->get_depth()/8 * size;
+
+  //b) add the entry to the list
+  d_shieldlist.push_back(myitem);
+
+  //c) check if the cache size is too large
+  checkPictures();
+
+  //we are finished, so return the pic
+  return myitem;
+}
+
+
+ShipCacheItem* GraphicsCache::addShipPic(const Player* p)
+{
+  debug("ADD ship pic: " <<p->getName())
+
+  ShipCacheItem* myitem = new ShipCacheItem();
+  myitem->player_id = p->getId();
+  myitem->armyset = p->getArmyset();
+
+  Armysetlist *al = Armysetlist::getInstance();
+  PixMask*ship = al->getShipPic(p->getArmyset());
+  PixMask*shipmask = al->getShipMask(p->getArmyset());
+  // copy the pixmap including player colors
+  myitem->surface = applyMask(ship, shipmask, p);
+
+  //now the final preparation steps:
+  //a) add the size
+  int size = myitem->surface->get_width() * myitem->surface->get_height();
+  d_cachesize += myitem->surface->get_depth()/8 * size;
+
+  //b) add the entry to the list
+  d_shiplist.push_back(myitem);
+
+  //c) check if the cache size is too large
+  checkPictures();
+
+  //we are finished, so return the pic
+  return myitem;
+}
+
+NewLevelCacheItem* GraphicsCache::addNewLevelPic(const Player* p, guint32 gender)
+{
+  debug("ADD new level pic: " <<p->getName())
+
+  NewLevelCacheItem* myitem = new NewLevelCacheItem();
+  myitem->player_id = p->getId();
+  myitem->gender = gender;
+
+  // copy the pixmap including player colors
+  if (gender == Hero::FEMALE)
+    myitem->surface = applyMask(d_newlevel_female, d_newlevelmask_female, p);
+  else
+    myitem->surface = applyMask(d_newlevel_male, d_newlevelmask_male, p);
+
+  //now the final preparation steps:
+  //a) add the size
+  int size = myitem->surface->get_width() * myitem->surface->get_height();
+  d_cachesize += myitem->surface->get_depth()/8 * size;
+
+  //b) add the entry to the list
+  d_newlevellist.push_back(myitem);
+
+  //c) check if the cache size is too large
+  checkPictures();
+
+  //we are finished, so return the pic
+  return myitem;
+}
+
+PortCacheItem* GraphicsCache::addPortPic(guint32 cityset)
+{
+  debug("ADD port pic: " << cityset);
+
+  PortCacheItem* myitem = new PortCacheItem();
+  myitem->cityset = cityset;
+
+  Citysetlist *csl = Citysetlist::getInstance();
+  Cityset *cs = csl->getCityset(cityset);
+
+  // copy the pixmap
+  myitem->surface = cs->getPortImage()->copy();
+
+  //now the final preparation steps:
+  //a) add the size
+  int size = myitem->surface->get_width() * myitem->surface->get_height();
+  d_cachesize += myitem->surface->get_depth()/8 * size;
+
+  //b) add the entry to the list
+  d_portlist.push_back(myitem);
+
+  //c) check if the cache size is too large
+  checkPictures();
+
+  //we are finished, so return the pic
+  return myitem;
+}
+
+ExplosionCacheItem* GraphicsCache::addExplosionPic(guint32 tileset)
+{
+  debug("ADD explosion pic: " << tileset);
+
+  ExplosionCacheItem* myitem = new ExplosionCacheItem();
+  myitem->tileset = tileset;
+
+  // copy the pixmap
+  myitem->surface = 
+    Tilesetlist::getInstance()->getTileset(tileset)->getExplosionImage()->copy();
+
+  //now the final preparation steps:
+  //a) add the size
+  int size = myitem->surface->get_width() * myitem->surface->get_height();
+  d_cachesize += myitem->surface->get_depth()/8 * size;
+
+  //b) add the entry to the list
+  d_explosionlist.push_back(myitem);
+
+  //c) check if the cache size is too large
+  checkPictures();
+
+  //we are finished, so return the pic
+  return myitem;
+}
+
+BagCacheItem* GraphicsCache::addBagPic(guint32 armyset)
+{
+  debug("ADD bad pic: " << armyset);
+
+  BagCacheItem* myitem = new BagCacheItem();
+  myitem->armyset = armyset;
+
+  // copy the pixmap
+  myitem->surface = Armysetlist::getInstance()->getBagPic(armyset)->copy();
+
+  //now the final preparation steps:
+  //a) add the size
+  int size = myitem->surface->get_width() * myitem->surface->get_height();
+  d_cachesize += myitem->surface->get_depth()/8 * size;
+
+  //b) add the entry to the list
+  d_baglist.push_back(myitem);
+
+  //c) check if the cache size is too large
+  checkPictures();
+
+  //we are finished, so return the pic
+  return myitem;
+}
+
+SignpostCacheItem* GraphicsCache::addSignpostPic(guint32 cityset)
+{
+  debug("ADD signpost pic: " << cityset);
+
+  SignpostCacheItem* myitem = new SignpostCacheItem();
+  myitem->cityset = cityset;
+
+  Citysetlist *csl = Citysetlist::getInstance();
+  Cityset *cs = csl->getCityset(cityset);
+
+  // copy the pixmap
+  myitem->surface = cs->getSignpostImage()->copy();
+
+  //now the final preparation steps:
+  //a) add the size
+  int size = myitem->surface->get_width() * myitem->surface->get_height();
+  d_cachesize += myitem->surface->get_depth()/8 * size;
+
+  //b) add the entry to the list
+  d_signpostlist.push_back(myitem);
+
+  //c) check if the cache size is too large
+  checkPictures();
+
+  //we are finished, so return the pic
+  return myitem;
+}
+
+PlantedStandardCacheItem* GraphicsCache::addPlantedStandardPic(const Player* p)
+{
+  debug("ADD planted standard pic: " <<p->getName())
+
+    PlantedStandardCacheItem* myitem = new PlantedStandardCacheItem();
+  myitem->player_id = p->getId();
+  myitem->armyset = p->getArmyset();
+
+  Armysetlist *al = Armysetlist::getInstance();
+  PixMask*standard = al->getStandardPic(p->getArmyset());
+  PixMask*standard_mask = al->getStandardMask(p->getArmyset());
+
+  // copy the pixmap including player colors
+  myitem->surface = applyMask(standard, standard_mask, p);
+
+  //now the final preparation steps:
+  //a) add the size
+  int size = myitem->surface->get_width() * myitem->surface->get_height();
+  d_cachesize += myitem->surface->get_depth()/8 * size;
+
+  //b) add the entry to the list
+  d_plantedstandardlist.push_back(myitem);
+
+  //c) check if the cache size is too large
+  checkPictures();
+
+  //we are finished, so return the pic
+  return myitem;
+}
+
+
+TempleCacheItem* GraphicsCache::addTemplePic(int type, guint32 cityset)
+{
+  Cityset *cs = Citysetlist::getInstance()->getCityset(cityset);
+  PixMask* mysurf = cs->getTempleImage(type)->copy();
+
+  //now create the cache item and add the size
+  TempleCacheItem* myitem = new TempleCacheItem();
+  myitem->type = type;
+  myitem->cityset = cityset;
+  myitem->surface = mysurf;
+
+  d_templelist.push_back(myitem);
+
+  //add the size
+  int size = mysurf->get_width() * mysurf->get_height();
+  d_cachesize += size * mysurf->get_depth()/8;
+
+  //and check the size of the cache
+  checkPictures();
+
+  return myitem;
+}
+
+RuinCacheItem* GraphicsCache::addRuinPic(int type, guint32 cityset)
+{
+  Cityset *cs = Citysetlist::getInstance()->getCityset(cityset);
+  PixMask* mysurf = cs->getRuinImage(type)->copy();
+
+  //now create the cache item and add the size
+  RuinCacheItem* myitem = new RuinCacheItem();
+  myitem->type = type;
+  myitem->cityset = cityset;
+  myitem->surface = mysurf;
+  myitem->cityset = cityset;
+
+  d_ruinlist.push_back(myitem);
+
+  //add the size
+  int size = mysurf->get_width() * mysurf->get_height();
+  d_cachesize += size * mysurf->get_depth()/8;
+
+  //and check the size of the cache
+  checkPictures();
+
+  return myitem;
+}
+
+DiplomacyCacheItem* GraphicsCache::addDiplomacyPic(int type, Player::DiplomaticState state)
+{
+  PixMask* mysurf = 
+    d_diplomacypic[type][state - Player::AT_PEACE];
+
+  //now create the cache item and add the size
+  DiplomacyCacheItem* myitem = new DiplomacyCacheItem();
+  myitem->type = type;
+  myitem->state = state;
+  myitem->surface = mysurf;
+
+  d_diplomacylist.push_back(myitem);
+
+  //add the size
+  int size = mysurf->get_width() * mysurf->get_height();
+  d_cachesize += size * mysurf->get_depth()/8;
+
+  //and check the size of the cache
+  checkPictures();
+
+  return myitem;
+}
+
+RoadCacheItem* GraphicsCache::addRoadPic(int type, guint32 tileset)
+{
+  Tileset *ts = Tilesetlist::getInstance()->getTileset(tileset);
+  PixMask* mysurf = ts->getRoadImage(type)->copy();
+
+  //now create the cache item and add the size
+  RoadCacheItem* myitem = new RoadCacheItem();
+  myitem->type = type;
+  myitem->tileset = tileset;
+  myitem->surface = mysurf;
+
+  d_roadlist.push_back(myitem);
+
+  //add the size
+  int size = mysurf->get_width() * mysurf->get_height();
+  d_cachesize += size * mysurf->get_depth()/8;
+
+  //and check the size of the cache
+  checkPictures();
+
+  return myitem;
+}
+
+FogCacheItem* GraphicsCache::addFogPic(FogCacheItem *item)
+{
+  Tileset *ts = Tilesetlist::getInstance()->getTileset(item->tileset);
+  PixMask* mysurf = ts->getFogImage(item->type - 1)->copy();
+
+  //now create the cache item and add the size
+  FogCacheItem* myitem = new FogCacheItem();
+  *myitem = *item;
+  myitem->surface = mysurf;
+
+  d_foglist.push_back(myitem);
+  std::list<FogCacheItem*>::iterator it = d_foglist.end();
+  it--;
+  d_fogmap[*myitem] = it;
+
+  //add the size
+  int size = mysurf->get_width() * mysurf->get_height();
+  d_cachesize += size * mysurf->get_depth()/8;
+
+  //and check the size of the cache
+  checkPictures();
+
+  return myitem;
+}
+
+BridgeCacheItem* GraphicsCache::addBridgePic(int type, guint32 tileset)
+{
+  Tileset *ts = Tilesetlist::getInstance()->getTileset(tileset);
+  PixMask* mysurf = ts->getBridgeImage(type)->copy();
+
+  //now create the cache item and add the size
+  BridgeCacheItem* myitem = new BridgeCacheItem();
+  myitem->type = type;
+  myitem->tileset = tileset;
+  myitem->surface = mysurf;
+
+  d_bridgelist.push_back(myitem);
+
+  //add the size
+  int size = mysurf->get_width() * mysurf->get_height();
+  d_cachesize += size * mysurf->get_depth()/8;
+
+  //and check the size of the cache
+  checkPictures();
+
+  return myitem;
+}
+
+CursorCacheItem* GraphicsCache::addCursorPic(int type)
+{
+  PixMask* mysurf = d_cursorpic[type];
+
+  //now create the cache item and add the size
+  CursorCacheItem* myitem = new CursorCacheItem();
+  myitem->type = type;
+  myitem->surface = mysurf;
+
+  d_cursorlist.push_back(myitem);
+
+  //add the size
+  int size = mysurf->get_width() * mysurf->get_height();
+  d_cachesize += size * mysurf->get_depth()/8;
+
+  //and check the size of the cache
+  checkPictures();
+
+  return myitem;
+}
+
+CityCacheItem* GraphicsCache::addCityPic(int type, const Player* p, guint32 cityset)
+{
+  //now create the cache item and add the size
+  CityCacheItem* myitem = new CityCacheItem();
+  myitem->cityset = cityset;
+  myitem->player_id = p->getId();
+  myitem->type = type;
+  Cityset *cs = Citysetlist::getInstance()->getCityset(cityset);
+  if (type == -1)
+    myitem->surface = cs->getRazedCityImage(p->getId())->copy();
+  else
+    myitem->surface = cs->getCityImage(p->getId())->copy();
+
+  d_citylist.push_back(myitem);
+
+  //add the size
+  int size = myitem->surface->get_width() * myitem->surface->get_height();
+  d_cachesize += size * myitem->surface->get_depth()/8;
+
+  //and check the size of the cache
+  checkPictures();
+
+  return myitem;
+}
+
+TowerCacheItem* GraphicsCache::addTowerPic(const Player* p, guint32 cityset)
+{
+  //now create the cache item and add the size
+  TowerCacheItem* myitem = new TowerCacheItem();
+  myitem->player_id = p->getId();
+  myitem->cityset = cityset;
+  Cityset *cs = Citysetlist::getInstance()->getCityset(cityset);
+  myitem->surface = cs->getTowerImage(p->getId());
+
+  d_towerlist.push_back(myitem);
+
+  //add the size
+  int size = myitem->surface->get_width() * myitem->surface->get_height();
+  d_cachesize += size * myitem->surface->get_depth()/8;
+
+  //and check the size of the cache
+  checkPictures();
+
+  return myitem;
+}
+
+FlagCacheItem* GraphicsCache::addFlagPic(int size, const Player *p, guint32 tileset)
+{
+  Tileset *ts = Tilesetlist::getInstance()->getTileset(tileset);
+  debug("GraphicsCache::addFlagPic, player="<<p->getId()<<", size="<<size)
+
+  // size of the stack starts at 1, but we need the index, which starts at 0
+
+  PixMask* mysurf = applyMask (ts->getFlagImage(size-1), 
+                              ts->getFlagMask(size-1), p);
+
+  //now create the cache item and add the size
+  FlagCacheItem* myitem = new FlagCacheItem();
+  myitem->player_id = p->getId();
+  myitem->size = size;
+  myitem->tileset = tileset;
+  myitem->surface = mysurf;
+
+  d_flaglist.push_back(myitem);
+
+  //add the size
+  int picsize = mysurf->get_width() * mysurf->get_height();
+  d_cachesize += picsize * mysurf->get_depth()/8;
+
+  //and check the size of the cache
+  checkPictures();
+
+  return myitem;
+}
+
+SelectorCacheItem* GraphicsCache::addSelectorPic(guint32 type, guint32 frame, const Player* p, guint32 tileset)
+{
+  Tileset *ts = Tilesetlist::getInstance()->getTileset(tileset);
+  debug("GraphicsCache::addSelectorPic, player="<<p->getName()<<", type="<<type<< ", " << frame)
+
+    // frame is the frame of animation we're looking for.  starts at 0.
+    // type is 0 for big, 1 for small
+
+  PixMask* mysurf;
+  if (type == 0)
+    mysurf = applyMask(ts->getSelectorImage(frame), ts->getSelectorMask(frame), p);
+  else
+    mysurf = applyMask(ts->getSmallSelectorImage(frame), 
+                      ts->getSmallSelectorMask(frame), p);
+
+  //now create the cache item and add the size
+  SelectorCacheItem* myitem = new SelectorCacheItem();
+  myitem->player_id = p->getId();
+  myitem->type = type;
+  myitem->tileset = tileset;
+  myitem->frame = frame;
+  myitem->surface = mysurf;
+
+  d_selectorlist.push_back(myitem);
+
+  //add the size
+  int picsize = mysurf->get_width() * mysurf->get_height();
+  d_cachesize += picsize * mysurf->get_depth()/8;
+
+  //and check the size of the cache
+  checkPictures();
+
+  return myitem;
+}
+
+ProdShieldCacheItem* GraphicsCache::addProdShieldPic(guint32 type, bool prod)
+{
+  debug("GraphicsCache::addProdShieldPic, prod="<<prod<<", type="<<type)
+
+    // type is 0 for home, 1 for away, 2 for destination, 3 for source,
+    // 4 for invalid
+
+    PixMask* mysurf = NULL;
+  switch (type)
+    {
+    case 0: //home city
+      if (prod) //production
+       mysurf = d_prodshieldpic[1]->copy();
+      else //no production
+       mysurf = d_prodshieldpic[0]->copy();
+      break;
+    case 1: //away city
+      if (prod) //production
+       mysurf = d_prodshieldpic[3]->copy();
+      else //no production
+       mysurf = d_prodshieldpic[2]->copy();
+      break;
+    case 2: //destination city
+      if (prod) //production
+       mysurf = d_prodshieldpic[5]->copy();
+      else //no production
+       mysurf = d_prodshieldpic[4]->copy();
+      break;
+    case 3: //source city
+      mysurf = d_prodshieldpic[6]->copy();
+      break;
+    case 4: //invalid
+      mysurf = d_prodshieldpic[7]->copy();
+      break;
+    }
+
+  //now create the cache item and add the size
+  ProdShieldCacheItem* myitem = new ProdShieldCacheItem();
+  myitem->prod = prod;
+  myitem->type = type;
+  myitem->surface = mysurf;
+
+  d_prodshieldlist.push_back(myitem);
+
+  //add the size
+  int picsize = mysurf->get_width() * mysurf->get_height();
+  d_cachesize += picsize * mysurf->get_depth()/8;
+
+  //and check the size of the cache
+  checkPictures();
+
+  return myitem;
+}
+
+MoveBonusCacheItem* GraphicsCache::addMoveBonusPic(guint32 type)
+{
+  debug("GraphicsCache::addMoveBonusPic, type="<<type)
+
+    //type is 0=empty, 1=trees, 2=foothills, 3=hills+trees, 4=fly, 5=boat
+
+    PixMask* mysurf;
+  mysurf = d_movebonuspic[type]->copy();
+
+  //now create the cache item and add the size
+  MoveBonusCacheItem* myitem = new MoveBonusCacheItem();
+  myitem->type = type;
+  myitem->surface = mysurf;
+
+  d_movebonuslist.push_back(myitem);
+
+  //add the size
+  int picsize = mysurf->get_width() * mysurf->get_height();
+  d_cachesize += picsize * mysurf->get_depth()/8;
+
+  //and check the size of the cache
+  checkPictures();
+
+  return myitem;
+}
+
+
+void GraphicsCache::clear()
+{
+  while (!d_armylist.empty())
+    eraseLastArmyItem();
+
+  while (!d_tilelist.empty())
+    eraseLastTileItem();
+
+  while (!d_templelist.empty())
+    eraseLastTempleItem();
+
+  while (!d_ruinlist.empty())
+    eraseLastRuinItem();
+
+  while (!d_diplomacylist.empty())
+    eraseLastDiplomacyItem();
+
+  while (!d_roadlist.empty())
+    eraseLastRoadItem();
+
+  while (!d_foglist.empty())
+    eraseLastFogItem();
+
+  while (!d_bridgelist.empty())
+    eraseLastBridgeItem();
+
+  while (!d_cursorlist.empty())
+    eraseLastCursorItem();
+
+  while (!d_citylist.empty())
+    eraseLastCityItem();
+
+  while (!d_towerlist.empty())
+    eraseLastTowerItem();
+
+  while (!d_shiplist.empty())
+    eraseLastShipItem();
+
+  while (!d_plantedstandardlist.empty())
+    eraseLastPlantedStandardItem();
+
+  while (!d_portlist.empty())
+    eraseLastPortItem();
+
+  while (!d_signpostlist.empty())
+    eraseLastSignpostItem();
+
+  while (!d_baglist.empty())
+    eraseLastBagItem();
+
+  while (!d_explosionlist.empty())
+    eraseLastExplosionItem();
+
+  while (!d_flaglist.empty())
+    eraseLastFlagItem();
+
+  while (!d_selectorlist.empty())
+    eraseLastSelectorItem();
+
+  while (!d_shieldlist.empty())
+    eraseLastShieldItem();
+
+  while (!d_prodshieldlist.empty())
+    eraseLastProdShieldItem();
+
+  while (!d_movebonuslist.empty())
+    eraseLastMoveBonusItem();
+}
+
+void GraphicsCache::eraseLastArmyItem()
+{
+  if (d_armylist.empty())
+    return;
+
+  //As the name suggests, this function erases the last item in the list.
+  //Whenever an item is requested, it moves to the first position, so the
+  //last item is the oldest and therefore propably most useless in the list.
+  ArmyCacheItem* myitem = *(d_armylist.begin());
+  ArmyMap::iterator it = d_armymap.find(*myitem);
+  if (it != d_armymap.end())
+    d_armymap.erase(it);
+  d_armylist.erase(d_armylist.begin());
+
+  //don't forget to subtract the size from the size entry
+  int size = myitem->surface->get_width() * myitem->surface->get_height();
+  d_cachesize -= myitem->surface->get_depth()/8 * size;
+
+  delete myitem->surface;
+  delete myitem;
+}
+
+void GraphicsCache::eraseLastTileItem()
+{
+  if (d_tilelist.empty())
+    return;
+
+  //As the name suggests, this function erases the last item in the list.
+  //Whenever an item is requested, it moves to the first position, so the
+  //last item is the oldest and therefore propably most useless in the list.
+  TileCacheItem* myitem = *(d_tilelist.begin());
+  TileMap::iterator it = d_tilemap.find(*myitem);
+  if (it != d_tilemap.end()) //fixme, find out why this check is necessary.
+    d_tilemap.erase(it);
+  d_tilelist.erase(d_tilelist.begin());
+
+  //don't forget to subtract the size from the size entry
+  int size = myitem->surface->get_width() * myitem->surface->get_height();
+  d_cachesize -= myitem->surface->get_depth()/8 * size;
+
+  delete myitem->surface;
+  delete myitem;
+}
+
+void GraphicsCache::eraseLastTempleItem()
+{
+  if (d_templelist.empty())
+    return;
+
+  TempleCacheItem* myitem = *(d_templelist.begin());
+  d_templelist.erase(d_templelist.begin());
+
+  int size = myitem->surface->get_width() * myitem->surface->get_height();
+  d_cachesize -= myitem->surface->get_depth()/8 * size;
+
+  delete myitem->surface;
+  delete myitem;
+}
+
+void GraphicsCache::eraseLastRuinItem()
+{
+  if (d_ruinlist.empty())
+    return;
+
+  RuinCacheItem* myitem = *(d_ruinlist.begin());
+  d_ruinlist.erase(d_ruinlist.begin());
+
+  int size = myitem->surface->get_width() * myitem->surface->get_height();
+  d_cachesize -= myitem->surface->get_depth()/8 * size;
+
+  delete myitem->surface;
+  delete myitem;
+}
+
+void GraphicsCache::eraseLastDiplomacyItem()
+{
+  if (d_diplomacylist.empty())
+    return;
+
+  DiplomacyCacheItem* myitem = *(d_diplomacylist.begin());
+  d_diplomacylist.erase(d_diplomacylist.begin());
+
+  int size = myitem->surface->get_width() * myitem->surface->get_height();
+  d_cachesize -= myitem->surface->get_depth()/8 * size;
+
+  delete myitem->surface;
+  delete myitem;
+}
+
+void GraphicsCache::eraseLastRoadItem()
+{
+  if (d_roadlist.empty())
+    return;
+
+  RoadCacheItem* myitem = *(d_roadlist.begin());
+  d_roadlist.erase(d_roadlist.begin());
+
+  int size = myitem->surface->get_width() * myitem->surface->get_height();
+  d_cachesize -= myitem->surface->get_depth()/8 * size;
+
+  delete myitem->surface;
+  delete myitem;
+}
+
+void GraphicsCache::eraseLastFogItem()
+{
+  if (d_foglist.empty())
+    return;
+
+  FogCacheItem* myitem = *(d_foglist.begin());
+  FogCacheMap::iterator it = d_fogmap.find(*myitem);
+  if (it != d_fogmap.end())
+    d_fogmap.erase(it);
+  d_foglist.erase(d_foglist.begin());
+
+  int size = myitem->surface->get_width() * myitem->surface->get_height();
+  d_cachesize -= myitem->surface->get_depth()/8 * size;
+
+  delete myitem->surface;
+  delete myitem;
+}
+
+void GraphicsCache::eraseLastBridgeItem()
+{
+  if (d_bridgelist.empty())
+    return;
+
+  BridgeCacheItem* myitem = *(d_bridgelist.begin());
+  d_bridgelist.erase(d_bridgelist.begin());
+
+  int size = myitem->surface->get_width() * myitem->surface->get_height();
+  d_cachesize -= myitem->surface->get_depth()/8 * size;
+
+  delete myitem->surface;
+  delete myitem;
+}
+
+void GraphicsCache::eraseLastCursorItem()
+{
+  if (d_cursorlist.empty())
+    return;
+
+  CursorCacheItem* myitem = *(d_cursorlist.begin());
+  d_cursorlist.erase(d_cursorlist.begin());
+
+  int size = myitem->surface->get_width() * myitem->surface->get_height();
+  d_cachesize -= myitem->surface->get_depth()/8 * size;
+
+  delete myitem->surface;
+  delete myitem;
+}
+
+void GraphicsCache::eraseLastCityItem()
+{
+  if (d_citylist.empty())
+    return;
+
+  CityCacheItem* myitem = *(d_citylist.begin());
+  d_citylist.erase(d_citylist.begin());
+
+  int size = myitem->surface->get_width() * myitem->surface->get_height();
+  d_cachesize -= myitem->surface->get_depth()/8 * size;
+
+  delete myitem->surface;
+  delete myitem;
+}
+
+void GraphicsCache::eraseLastTowerItem()
+{
+  if (d_towerlist.empty())
+    return;
+
+  TowerCacheItem* myitem = *(d_towerlist.begin());
+  d_towerlist.erase(d_towerlist.begin());
+
+  int size = myitem->surface->get_width() * myitem->surface->get_height();
+  d_cachesize -= myitem->surface->get_depth()/8 * size;
+
+  delete myitem->surface;
+  delete myitem;
+}
+
+void GraphicsCache::eraseLastShipItem()
+{
+  if (d_shiplist.empty())
+    return;
+
+  ShipCacheItem* myitem = *(d_shiplist.begin());
+  d_shiplist.erase(d_shiplist.begin());
+
+  int size = myitem->surface->get_width() * myitem->surface->get_height();
+  d_cachesize -= myitem->surface->get_depth()/8 * size;
+
+  delete myitem->surface;
+  delete myitem;
+}
+
+void GraphicsCache::eraseLastNewLevelItem()
+{
+  if (d_newlevellist.empty())
+    return;
+
+  NewLevelCacheItem* myitem = *(d_newlevellist.begin());
+  d_newlevellist.erase(d_newlevellist.begin());
+
+  int size = myitem->surface->get_width() * myitem->surface->get_height();
+  d_cachesize -= myitem->surface->get_depth()/8 * size;
+
+  delete myitem->surface;
+  delete myitem;
+}
+
+void GraphicsCache::eraseLastExplosionItem()
+{
+  if (d_explosionlist.empty())
+    return;
+
+  ExplosionCacheItem* myitem = *(d_explosionlist.begin());
+  d_explosionlist.erase(d_explosionlist.begin());
+
+  int size = myitem->surface->get_width() * myitem->surface->get_height();
+  d_cachesize -= myitem->surface->get_depth()/8 * size;
+
+  delete myitem->surface;
+  delete myitem;
+}
+
+void GraphicsCache::eraseLastBagItem()
+{
+  if (d_baglist.empty())
+    return;
+
+  BagCacheItem* myitem = *(d_baglist.begin());
+  d_baglist.erase(d_baglist.begin());
+
+  int size = myitem->surface->get_width() * myitem->surface->get_height();
+  d_cachesize -= myitem->surface->get_depth()/8 * size;
+
+  delete myitem->surface;
+  delete myitem;
+}
+
+void GraphicsCache::eraseLastSignpostItem()
+{
+  if (d_signpostlist.empty())
+    return;
+
+  SignpostCacheItem* myitem = *(d_signpostlist.begin());
+  d_signpostlist.erase(d_signpostlist.begin());
+
+  int size = myitem->surface->get_width() * myitem->surface->get_height();
+  d_cachesize -= myitem->surface->get_depth()/8 * size;
+
+  delete myitem->surface;
+  delete myitem;
+}
+
+void GraphicsCache::eraseLastPortItem()
+{
+  if (d_portlist.empty())
+    return;
+
+  PortCacheItem* myitem = *(d_portlist.begin());
+  d_portlist.erase(d_portlist.begin());
+
+  int size = myitem->surface->get_width() * myitem->surface->get_height();
+  d_cachesize -= myitem->surface->get_depth()/8 * size;
+
+  delete myitem->surface;
+  delete myitem;
+}
+
+void GraphicsCache::eraseLastPlantedStandardItem()
+{
+  if (d_plantedstandardlist.empty())
+    return;
+
+  PlantedStandardCacheItem* myitem = *(d_plantedstandardlist.begin());
+  d_plantedstandardlist.erase(d_plantedstandardlist.begin());
+
+  int size = myitem->surface->get_width() * myitem->surface->get_height();
+  d_cachesize -= myitem->surface->get_depth()/8 * size;
+
+  delete myitem->surface;
+  delete myitem;
+}
+
+void GraphicsCache::eraseLastFlagItem()
+{
+  if (d_flaglist.empty())
+    return;
+
+  FlagCacheItem* myitem = *(d_flaglist.begin());
+  d_flaglist.erase(d_flaglist.begin());
+
+  int size = myitem->surface->get_width() * myitem->surface->get_height();
+  d_cachesize -= myitem->surface->get_depth()/8 * size;
+
+  delete myitem->surface;
+  delete myitem;
+}
+
+void GraphicsCache::eraseLastSelectorItem()
+{
+  if (d_selectorlist.empty())
+    return;
+
+  SelectorCacheItem* myitem = *(d_selectorlist.begin());
+  d_selectorlist.erase(d_selectorlist.begin());
+
+  int size = myitem->surface->get_width() * myitem->surface->get_height();
+  d_cachesize -= myitem->surface->get_depth()/8 * size;
+
+  delete myitem->surface;
+  delete myitem;
+}
+
+void GraphicsCache::eraseLastShieldItem()
+{
+  if (d_shieldlist.empty())
+    return;
+
+  ShieldCacheItem* myitem = *(d_shieldlist.begin());
+  d_shieldlist.erase(d_shieldlist.begin());
+
+  int size = myitem->surface->get_width() * myitem->surface->get_height();
+  d_cachesize -= myitem->surface->get_depth()/8 * size;
+
+  delete myitem->surface;
+  delete myitem;
+}
+
+void GraphicsCache::eraseLastProdShieldItem()
+{
+  if (d_prodshieldlist.empty())
+    return;
+
+  ProdShieldCacheItem* myitem = *(d_prodshieldlist.begin());
+  d_prodshieldlist.erase(d_prodshieldlist.begin());
+
+  int size = myitem->surface->get_width() * myitem->surface->get_height();
+  d_cachesize -= myitem->surface->get_depth()/8 * size;
+
+  delete myitem->surface;
+  delete myitem;
+}
+
+void GraphicsCache::eraseLastMoveBonusItem()
+{
+  if (d_movebonuslist.empty())
+    return;
+
+  MoveBonusCacheItem* myitem = *(d_movebonuslist.begin());
+  d_movebonuslist.erase(d_movebonuslist.begin());
+
+  int size = myitem->surface->get_width() * myitem->surface->get_height();
+  d_cachesize -= myitem->surface->get_depth()/8 * size;
+
+  delete myitem->surface;
+  delete myitem;
+}
+
+void GraphicsCache::loadDiplomacyPics()
+{
+  int ts = 30;
+  std::vector<PixMask* > diplomacypics;
+  diplomacypics = disassemble_row(File::getMiscFile("various/diplomacy-small.png"), 
+                            DIPLOMACY_TYPES);
+  for (unsigned int i = 0; i < DIPLOMACY_TYPES ; i++)
+    {
+      if (diplomacypics[i]->get_width() != ts)
+       PixMask::scale(diplomacypics[i], ts, ts);
+      d_diplomacypic[0][i] = diplomacypics[i];
+
+    }
+
+  ts = 50;
+  diplomacypics = disassemble_row(File::getMiscFile("various/diplomacy-large.png"), 
+                            DIPLOMACY_TYPES);
+  for (unsigned int i = 0; i < DIPLOMACY_TYPES ; i++)
+    {
+      if (diplomacypics[i]->get_width() != ts)
+       PixMask::scale(diplomacypics[i], ts, ts);
+      d_diplomacypic[1][i] = diplomacypics[i];
+
+    }
+}
+
+void GraphicsCache::loadCursorPics()
+{
+  int ts = 16;
+
+  // load the cursor pictures
+  std::vector<PixMask* > cursorpics;
+  cursorpics = disassemble_row(File::getMiscFile("various/cursors.png"),
+                              CURSOR_TYPES);
+  for (unsigned int i = 0; i < CURSOR_TYPES ; i++)
+    {
+      if (cursorpics[i]->get_width() != ts)
+       PixMask::scale(cursorpics[i], ts, ts);
+      d_cursorpic[i] = cursorpics[i];
+    }
+}
+
+bool GraphicsCache::loadSelectorImages(std::string filename, guint32 size, std::vector<PixMask* > &images, std::vector<PixMask* > &masks)
+{
+  int num_frames;
+  num_frames = Gdk::Pixbuf::create_from_file (filename)->get_width() / size;
+  images = disassemble_row(filename, num_frames, true);
+  for (int i = 0; i < num_frames; i++)
+    {
+      if (images[i]->get_width() != (int)size)
+       PixMask::scale(images[i], size, size);
+    }
+
+  masks = disassemble_row(filename, num_frames, false);
+  for (int i = 0; i < num_frames; i++)
+    {
+      if (masks[i]->get_width() != (int)size)
+       PixMask::scale(masks[i], size, size);
+    }
+
+  return true;
+}
+
+void GraphicsCache::loadProdShields()
+{
+  //load the production shieldset
+  int xsize = PRODUCTION_SHIELD_WIDTH;
+  int ysize = PRODUCTION_SHIELD_HEIGHT;
+  std::vector<PixMask* > prodshieldpics;
+  prodshieldpics = disassemble_row
+    (File::getMiscFile("various/prodshieldset.png"), PRODUCTION_SHIELD_TYPES);
+  for (unsigned int i = 0; i < PRODUCTION_SHIELD_TYPES; i++)
+    {
+      if (prodshieldpics[i]->get_width() != xsize)
+       PixMask::scale(prodshieldpics[i], xsize, ysize);
+      d_prodshieldpic[i] = prodshieldpics[i];
+    }
+}
+
+void GraphicsCache::loadMedalPics()
+{
+  //load the medal icons
+  int ts = 40;
+  std::vector<PixMask* > medalpics;
+  medalpics = disassemble_row(File::getMiscFile("various/medals_mask.png"),
+                                 MEDAL_TYPES);
+  for (unsigned int i = 0; i < MEDAL_TYPES; i++)
+    {
+      if (medalpics[i]->get_width() != ts)
+       PixMask::scale(medalpics[i], ts, ts);
+      d_medalpic[0][i] = medalpics[i];
+    }
+  medalpics = disassemble_row(File::getMiscFile("various/bigmedals.png"),
+                             MEDAL_TYPES);
+  for (unsigned int i = 0; i < MEDAL_TYPES; i++)
+    d_medalpic[1][i] = medalpics[i];
+}
+
+void GraphicsCache::loadNewLevelPics()
+{
+  std::vector<PixMask* > half;
+  half = disassemble_row(File::getMiscFile("various/hero-newlevel-male.png"), 
+                        2);
+  d_newlevel_male = half[0];
+  d_newlevelmask_male = half[1];
+  half = disassemble_row(File::getMiscFile("various/hero-newlevel-female.png"), 
+                        2);
+  d_newlevel_female = half[0];
+  d_newlevelmask_female = half[1];
+}
+
+void GraphicsCache::loadMoveBonusPics()
+{
+  //load the movement bonus icons
+  int xsize = MOVE_BONUS_WIDTH;
+  int ysize = MOVE_BONUS_HEIGHT;
+  std::vector<PixMask* > movebonuspics;
+  movebonuspics = disassemble_row(File::getMiscFile("various/movebonus.png"),
+                                 MOVE_BONUS_TYPES);
+  for (unsigned int i = 0; i < MOVE_BONUS_TYPES; i++)
+    {
+      if (movebonuspics[i]->get_width() != xsize)
+       PixMask::scale(movebonuspics[i], xsize, ysize);
+      d_movebonuspic[i] = movebonuspics[i];
+    }
+}
+
+bool GraphicsCache::loadFlagImages(std::string filename, guint32 size, std::vector<PixMask* > &images, std::vector<PixMask* > &masks)
+{
+  images = disassemble_row(filename, FLAG_TYPES, true);
+  for (unsigned int i = 0; i < FLAG_TYPES; i++)
+    {
+      if (images[i]->get_width() != (int)size)
+       PixMask::scale(images[i], size, size);
+
+    }
+  masks = disassemble_row(filename, FLAG_TYPES, false);
+  for (unsigned int i = 0; i < FLAG_TYPES; i++)
+    {
+      if (masks[i]->get_width() !=(int) size)
+       PixMask::scale(masks[i], size, size);
+    }
+  return true;
+}
+
+PixMask* GraphicsCache::getMedalPic(bool large, int type)
+{
+  if (large)
+    return d_medalpic[1][type];
+  else
+    return d_medalpic[0][type];
+}
+
+PixMask* GraphicsCache::loadImage(std::string filename, bool alpha)
+{
+  return PixMask::create(filename);
+}
+
+PixMask* GraphicsCache::getMiscPicture(std::string picname, bool alpha)
+{
+  return loadImage(File::getMiscFile("/various/" + picname), alpha);
+}
+