1 // Copyright (C) 2003, 2004, 2005, 2006, 2007 Ulf Lorenz
2 // Copyright (C) 2004, 2006 Andrea Paternesi
3 // Copyright (C) 2006, 2007, 2008, 2009 Ben Asselstine
5 // This program is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation; either version 3 of the License, or
8 // (at your option) any later version.
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU Library General Public License for more details.
15 // You should have received a copy of the GNU General Public License
16 // along with this program; if not, write to the Free Software
17 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20 #ifndef GRAPHICS_CACHE_H
21 #define GRAPHICS_CACHE_H
39 struct TowerCacheItem;
40 struct TempleCacheItem;
42 struct DiplomacyCacheItem;
43 struct StoneCacheItem;
45 struct BridgeCacheItem;
46 struct CursorCacheItem;
48 struct SelectorCacheItem;
49 struct ShieldCacheItem;
50 struct ProdShieldCacheItem;
51 struct MoveBonusCacheItem;
53 struct PlantedStandardCacheItem;
54 struct NewLevelCacheItem;
57 struct SignpostCacheItem;
59 struct ExplosionCacheItem;
62 /** Soliton class for caching army and map images
64 * With the introduction of player-specific colors, the problem of caching
65 * images has popped up. The player colors are implemented by taking an army
66 * picture and a mask, with the mask being a 16 color image, substituting
67 * the colors in the mask and blitting the mask over the army (or e.g. city)
68 * image. This takes several blits (>3, there are also things like medals
69 * to be considered) and is therefore costly.
71 * This class approaches this problem by caching formatted images. You get
72 * e.g. an army image by querying the cache, which either gives you the cached
73 * image or creates a new one. If the size is exceeded, the class will free
74 * the oldest (not used for the longest time) images until it gets below the
75 * treshold. It maintains some kind of balance between cached city pictures
76 * and cached army pictures, but the kind of balance may change, so I'll
77 * better not describe it here. :)
79 * Recently, it has been improved to cache flag pictures (showing how many
80 * armies a stack contains) as well.
82 * The maximum cache size can be changed on the fly by modifying the value in
83 * the Configuration class. However, if set too small (around 1 megabyte), this
84 * value will silently be ignored.
86 * @note For efficiency reasons, the class will not copy the surfaces it has,
87 * so DON'T MODIFY THEM unless you know what you do! (i.e. never)
108 //! Method for getting/creating the soliton instance.
109 static GraphicsCache* getInstance();
111 //! Explicitely deletes the soliton instance
112 static void deleteInstance();
114 //! Clears the whole cache.
117 //! Get the current cache size, the maximum is in Configuration::s_cacheSize
118 guint32 getCacheSize() const {return d_cachesize;}
120 /** Method for getting the army picture from the cache
122 * This method returns either the cached image of the given type or
123 * creates a new one and caches it. Use this method to access
124 * army images! And: Don't touch the returned surface!! For performance
125 * reasons you get the original surface which is also in the cache.
127 * The returned surface contains the correct player colors and some
128 * icons displaying the level of the unit.
130 * @param armyset the armyset to be used
131 * @param army the index of the army to be used
132 * @param player the player owning the army
133 * @param greyed the image is greyed out; deselected/inactive.
134 * @return the image of the unit
136 PixMask* getArmyPic(guint32 armyset, guint32 army, const Player* p,
137 const bool* medals, bool greyed = false);
138 PixMask* getArmyPic(Army *a, bool greyed = false);
140 PixMask* 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);
141 PixMask* 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);
143 /** Method for getting the shield picture from the cache
145 * This method returns either the cached image of the given type or
146 * creates a new one and caches it. Use this method to access
147 * army images! And: Don't touch the returned surface!! For performance
148 * reasons you get the original surface which is also in the cache.
150 * The returned surface contains the correct player colors and some
151 * icons displaying the level of the unit.
153 * @param shieldset the id of the shieldset to be used
154 * @param type the size of the shield: 0=sm, 1=med, 2=lg
155 * @param colour which player the shield is for
156 * @return the image of the shield
158 PixMask* getShieldPic(guint32 shieldset, guint32 type, guint32 colour);
159 PixMask* getShieldPic(guint32 type, Player *p);
161 /** Method for getting a ruin picture
163 * @param type the type of the ruin
164 * @return image of the ruin
166 PixMask* getRuinPic(int type);
167 PixMask* getRuinPic(int type, guint32 cityset);
169 /** Method for getting a diplomacy icon
171 * @param type o = small, or 1 = large.
172 * @param state the diplomatic state. e.g. peace, war, etc
173 * @return image of the icon
175 PixMask* getDiplomacyPic(int type, Player::DiplomaticState state);
177 /** Method for getting a temple picture
179 * @param type the type of the temple
180 * @return image of the temple
182 PixMask* getTemplePic(int type);
183 PixMask* getTemplePic(int type, guint32 cityset);
185 /** Method for getting a road picture
187 * @param type the type of the road
188 * @return image of the road
190 PixMask* getRoadPic(int type, guint32 tileset);
191 PixMask* getRoadPic(int type);
193 /** Method for getting a fog picture
195 * @param type the type of the fog
196 * @return image of the fog
198 PixMask* getFogPic(int type, guint32 tileset);
199 PixMask* getFogPic(int type);
201 /** Method for getting a bridge picture
203 * @param type the type of the bridge 0=e/w 1=n/s
204 * @return image of the bridge
206 PixMask* getBridgePic(int type, guint32 tileset);
207 PixMask* getBridgePic(int type);
209 /** Method for getting a cursor picture
211 * @param type the type of the cursor
212 * @return image of the cursor
214 PixMask* getCursorPic(int type);
216 /** Method for getting a ship picture. This is the picture
217 * that appears when the stack goes into the water.
219 * @param p the player to colour the ship as
220 * @return image of the ship
222 PixMask* getShipPic(const Player* p);
224 /** Method for getting a standard picture. This is the picture
225 * that appears when the hero plants a flag..
227 * @param p the player to colour the flag as
228 * @return image of the standard
230 PixMask* getPlantedStandardPic(const Player* p);
232 /** Method for getting a port picture. This is the picture
233 * that appears often as an anchor on coastal regions.
235 * @return image of the port
237 PixMask* getPortPic();
238 PixMask* getPortPic(guint32 cityset);
240 /** Method for getting a signpost picture. This is the picture
241 * that appears as a little tiny sign on grassy tiles.
243 * @return image of the signpost
245 PixMask* getSignpostPic();
246 PixMask* getSignpostPic(guint32 cityset);
248 /** Method for getting a bag-of-items picture. This is the picture
249 * that shows when a hero drops one or more items on the ground.
251 * @return image of the sack of items
253 PixMask* getBagPic();
254 PixMask* getBagPic(guint32 armyset);
256 /** Method for getting an explosion picture. This is the picture
257 * that shows when stacks are fighting.
259 * @return image of the explosion.
261 PixMask* getExplosionPic();
262 PixMask* getExplosionPic(guint32 tileset);
264 /** Method for getting a new-level picture. This is the picture
265 * that appears when a hero gains a new level, and subsequently gets
266 * to increase a stat.
268 * @param p the player to colour the image as.
269 * @return new-level image.
271 PixMask* getNewLevelPic(const Player* p, guint32 gender);
273 /** Method for getting a city picture
275 * For simplicity we have extended the basic_image/mask style to
276 * cities as well, since it greatly reduces the number of images.
277 * Use this method solely to get city images, and don't touch the
280 * @param type the level of the city; -1 returns the pic for
282 * @param player the player owning the city
283 * @param cityset the cityset that has the city image
284 * @return image of the described city
286 PixMask* getCityPic(int type, const Player* p, guint32 cityset);
287 /** Another method for getting a city picture
289 * Most often, we don't need such a sophisticated method. So just
290 * supply the city instance and be happy. :)
292 * @param city the city whose picture we want to get
293 * @return image of the city
295 PixMask* getCityPic(const City* city);
296 PixMask* getCityPic(const City* city, guint32 cityset);
298 /** Method for getting tower pictures.
300 * As with the other methods, use solely this method to get the tower
301 * images. And DON'T modify the images!
303 * @param p the player for which we want to get the tower
304 * @return image for the tower
306 PixMask* getTowerPic(const Player *p);
307 PixMask* getTowerPic(const Player* p, guint32 cityset);
309 /** Method for getting flag pictures.
311 * As with the other methods, use solely this method to get the flag
312 * images. And DON'T modify the images!
314 * @param stack the stack for which we want to get the flag
315 * @return image for the flag
317 PixMask* getFlagPic(const Stack* s);
318 PixMask* getFlagPic(const Stack* s, guint32 tileset);
319 PixMask* getFlagPic(guint32 stack_size, const Player *p);
320 PixMask* getFlagPic(guint32 stack_size, const Player *p, guint32 tileset);
322 /** Method for getting selector pictures.
324 * As with the other methods, use solely this method to get the
325 * selector images. And DON'T modify the images!
327 * @param type the frame of the selector
328 * @param p the player to draw it for
329 * @return image for the flag
331 PixMask* getSelectorPic(guint32 type, guint32 frame, const Player* p, guint32 tileset);
333 PixMask* getSelectorPic(guint32 type, guint32 frame, const Player *p);
335 /** Method for getting shield pictures.
337 * As with the other methods, use solely this method to get the
338 * shield images. And DON'T modify the images!
340 * @param type small, medium or large shield size
341 * @param p the player to draw it for
342 * @return image for the shield
344 PixMask* getShieldPic(guint32 type, const Player* p);
347 PixMask* getSmallRuinedCityPic();
348 //! Return a small hero picture, either white (active==true) or black.
349 PixMask* getSmallHeroPic(bool active);
350 PixMask* getMoveBonusPic(guint32 bonus, bool has_ship);
351 PixMask*getSmallTemplePic();
352 PixMask*getSmallRuinExploredPic();
353 PixMask* getSmallRuinUnexploredPic();
354 PixMask* getSmallStrongholdUnexploredPic();
356 /** Method for getting production shield pictures.
358 * As with the other methods, use solely this method to get the
359 * shield images. And DON'T modify the images!
361 * @param type home/away/destination/source/invalid.
363 * normally, but when "see all" is turned on, one sees source/dest.
364 * @param prod city production is going on, true or false
365 * @return image for the shield
366 * note that type=source, production=false is impossible
367 * note that type=invalid,production=true is used to show the symbol
368 * that means no more units can be vectored to this city.
370 PixMask* getProdShieldPic(guint32 type, bool prod);
372 PixMask* getMedalPic(bool large, int type);
375 /** Modify an image with player colors.
377 * Take an arbitray surface and mask image, apply the player colors such
378 * that the pixels in the mask image reflect this and blit the mask over
379 * the original image. This has been made public to allow arbitrary images
380 * (in detail the win game image) to have masks.
382 * @param image the original image
383 * @param mask the mask; is only opaque where player colors are wanted
384 * @return a surface with player colors applied.
387 PixMask* applyMask(PixMask* image, PixMask* mask, const Player* p);
389 static PixMask* applyMask(PixMask* image, PixMask* mask, Gdk::Color colour, bool isNeutral);
391 static PixMask* greyOut(PixMask* image);
393 static bool loadSelectorImages(std::string filename, guint32 tilesize, std::vector<PixMask* > &images, std::vector<PixMask* > &masks);
395 static bool loadFlagImages(std::string filename, guint32 size, std::vector<PixMask* > &images, std::vector<PixMask* > &masks);
399 * @param picname the name of the image (including the suffix).
400 * @param alpha set this to false if you encounter transparent
401 * images that should be opaque. :)
402 * Especially for background images...
403 * @return the surface which contains the image
405 static PixMask* getMiscPicture(std::string picname, bool alpha=true);
411 //! Creates a new temple picture with the given parameters.
412 TempleCacheItem* addTemplePic(int type, guint32 cityset);
414 //! Creates a new ruin picture with the given parameters.
415 RuinCacheItem* addRuinPic(int type, guint32 cityset);
417 //! Creates a new diplomacy icon with the given parameters.
418 DiplomacyCacheItem* addDiplomacyPic(int type, Player::DiplomaticState state);
420 //! Creates a new road picture with the given parameters.
421 RoadCacheItem* addRoadPic(int type, guint32 tileset);
423 //! Creates a new fog picture with the given parameters.
424 FogCacheItem* addFogPic(FogCacheItem *item);
426 //! Creates a new bridge picture with the given parameters.
427 BridgeCacheItem* addBridgePic(int type, guint32 tileset);
429 //! Creates a new cursor picture with the given parameters.
430 CursorCacheItem* addCursorPic(int type);
432 //! Creates a new army picture with the given parameters.
433 ArmyCacheItem* addArmyPic(ArmyCacheItem*item);
435 //! Creates a new drawn tile with the given parameters.
436 TileCacheItem* addTilePic(TileCacheItem*item);
438 //! Creates a new shield picture with the given parameters.
439 ShieldCacheItem* addShieldPic(guint32 shieldset, guint32 type, guint32 colour);
441 //! Creates a new city picture with the given parameters.
442 CityCacheItem* addCityPic(int type, const Player* p, guint32 cityset);
444 //! Creates a new tower picture with the given parameters.
445 TowerCacheItem* addTowerPic(const Player* p, guint32 cityset);
447 //! Creates a new ship picture with the given parameters.
448 ShipCacheItem* addShipPic(const Player* p);
450 //! Creates a new planted standard picture with the given parameters.
451 PlantedStandardCacheItem* addPlantedStandardPic(const Player* p);
453 //! Creates a new port picture with the given parameters.
454 PortCacheItem* addPortPic(guint32 cityset);
456 //! Creates a new port picture with the given parameters.
457 SignpostCacheItem* addSignpostPic(guint32 cityset);
459 //! Creates a new bag-of-items picture with the given parameters.
460 BagCacheItem* addBagPic(guint32 armyset);
462 //! Creates a new explosion picture with the given parameters.
463 ExplosionCacheItem* addExplosionPic(guint32 tileset);
465 //! Creates a new new-level picture in the player's colour.
466 NewLevelCacheItem* addNewLevelPic(const Player* p, guint32 gender);
468 //! Creates a new flag picture with the given parameters.
469 FlagCacheItem* addFlagPic(int size, const Player *p, guint32 tileset);
471 //! Creates a new selector picture with the given parameters.
472 SelectorCacheItem* addSelectorPic(guint32 type, guint32 frame,
473 const Player* p, guint32 tileset);
475 //! Creates a new production shield picture with the given parameters.
476 ProdShieldCacheItem* addProdShieldPic(guint32 type, bool prod);
478 //! Creates a new movement bonus picture with the given parameters.
479 MoveBonusCacheItem* addMoveBonusPic(guint32 type);
482 //! Checks if the cache has exceeded the maximum size and reduce it.
483 void checkPictures();
485 //! Erases the oldest (least recently requested) army cache item.
486 void eraseLastArmyItem();
488 //! Erases the oldest (least recently requested) army cache item.
489 void eraseLastTileItem();
491 //! Erases the oldest (least recently requested) temple cache item.
492 void eraseLastTempleItem();
494 //! Erases the oldest (least recently requested) ruin cache item.
495 void eraseLastRuinItem();
497 //! Erases the oldest (least recently requested) diplomacy cache item.
498 void eraseLastDiplomacyItem();
500 //! Erases the oldest (least recently requested) road cache item.
501 void eraseLastRoadItem();
503 //! Erases the oldest (least recently requested) fog cache item.
504 void eraseLastFogItem();
506 //! Erases the oldest (least recently requested) bridge cache item.
507 void eraseLastBridgeItem();
509 //! Erases the oldest (least recently requested) cursor cache item.
510 void eraseLastCursorItem();
512 //! Erases the oldest (least recently requested) city cache item.
513 void eraseLastCityItem();
515 //! Erases the oldest (least recently requested) tower cache item.
516 void eraseLastTowerItem();
518 //! Erases the oldest (least recently requested) ship cache item.
519 void eraseLastShipItem();
521 //! Erases the oldest planted standard cache item.
522 void eraseLastPlantedStandardItem();
524 //! Erases the oldest port cache item.
525 void eraseLastPortItem();
527 //! Erases the oldest bag-of-items cache item.
528 void eraseLastBagItem();
530 //! Erases the oldest explosion cache item.
531 void eraseLastExplosionItem();
533 //! Erases the oldest signpost cache item.
534 void eraseLastSignpostItem();
536 //! Erase the oldest picture of a hero gaining a level.
537 void eraseLastNewLevelItem();
539 //! Erases the oldest flag cache item
540 void eraseLastFlagItem();
542 //! Erases the oldest selector cache item
543 void eraseLastSelectorItem();
545 //! Erases the oldest shield cache item
546 void eraseLastShieldItem();
548 //! Erases the oldest production shield cache item
549 void eraseLastProdShieldItem();
551 //! Erases the oldest movement bonus cache item
552 void eraseLastMoveBonusItem();
554 //! Loads the images for the city pictures
557 //! Loads the images for the tower pictures
558 void loadTowerPics();
560 //! Loads the images for the temple pictures.
561 void loadTemplePics();
563 //! Loads the images for the ruin pictures.
566 //! Loads the images for the diplomacy pictures.
567 void loadDiplomacyPics();
569 //! Loads the images for the cursor pictures.
570 void loadCursorPics();
572 //! Loads the images for the medals.
573 void loadMedalPics();
575 //! Loads the images for the production shields
576 void loadProdShields();
578 //! Loads the images associated with heroes gaining a new level.
579 void loadNewLevelPics();
581 //! Loads the images for the movement bonuses
582 void loadMoveBonusPics();
584 void 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);
588 * This method loads an image, adjusts it to the current resolution etc.
589 * to improve blitting performance.
591 * @note Some of the images (.jpg??) become transparent if the alpha
592 * channel is copied (they don't have transparent bits anyway), so they
593 * should be loaded with alpha set to false
595 * @param filename full filename (with path) of the image to load
596 * @param alpha if set to true, copy the alpha channel as well
597 * (i.e. if the file has transparent pixels, they
598 * will be marked as transparent in the returned image)
599 * @return converted image or 0 if anything failed.
601 static PixMask* loadImage(std::string filename, bool alpha = true);
603 static GraphicsCache* s_instance;
606 std::list<ArmyCacheItem*> d_armylist;
607 typedef std::map<ArmyCacheItem, std::list<ArmyCacheItem*>::iterator > ArmyMap;
610 std::list<TileCacheItem*> d_tilelist;
611 typedef std::map<TileCacheItem, std::list<TileCacheItem*>::iterator > TileMap;
613 std::list<CityCacheItem*> d_citylist;
614 std::list<TowerCacheItem*> d_towerlist;
615 std::list<FlagCacheItem*> d_flaglist;
616 std::list<TempleCacheItem*> d_templelist;
617 std::list<RuinCacheItem*> d_ruinlist;
618 std::list<DiplomacyCacheItem*> d_diplomacylist;
619 std::list<RoadCacheItem*> d_roadlist;
620 std::list<FogCacheItem*> d_foglist;
621 typedef std::map<FogCacheItem, std::list<FogCacheItem*>::iterator > FogCacheMap;
623 FogCacheMap d_fogmap;
624 std::list<BridgeCacheItem*> d_bridgelist;
625 std::list<CursorCacheItem*> d_cursorlist;
626 std::list<SelectorCacheItem*> d_selectorlist;
627 std::list<ShieldCacheItem*> d_shieldlist;
628 std::list<ProdShieldCacheItem*> d_prodshieldlist;
629 std::list<MoveBonusCacheItem*> d_movebonuslist;
630 std::list<ShipCacheItem*> d_shiplist;
631 std::list<PlantedStandardCacheItem*> d_plantedstandardlist;
632 std::list<PortCacheItem*> d_portlist;
633 std::list<SignpostCacheItem*> d_signpostlist;
634 std::list<BagCacheItem*> d_baglist;
635 std::list<ExplosionCacheItem*> d_explosionlist;
636 std::list<NewLevelCacheItem*> d_newlevellist;
638 //some private surfaces
639 PixMask* d_diplomacypic[2][DIPLOMACY_TYPES];
641 PixMask* d_cursorpic[CURSOR_TYPES];
642 PixMask* d_prodshieldpic[PRODUCTION_SHIELD_TYPES];
643 PixMask* d_smallruinedcity;
644 PixMask* d_smallhero;
645 PixMask* d_smallinactivehero;
646 PixMask* d_movebonuspic[MOVE_BONUS_TYPES];
647 PixMask* d_medalpic[2][MEDAL_TYPES];
648 PixMask* d_small_ruin_unexplored;
649 PixMask* d_small_stronghold_unexplored;
650 PixMask* d_small_ruin_explored;
651 PixMask* d_small_temple;
652 PixMask *d_newlevel_male;
653 PixMask *d_newlevelmask_male;
654 PixMask *d_newlevel_female;
655 PixMask *d_newlevelmask_female;
658 bool operator <(ArmyCacheItem lhs, ArmyCacheItem rhs);
659 bool operator <(TileCacheItem lhs, TileCacheItem rhs);
660 bool operator <(FogCacheItem lhs, FogCacheItem rhs);