1 // Copyright (C) 2003, 2004, 2005, 2006, 2007 Ulf Lorenz
2 // Copyright (C) 2004, 2005, 2006 Andrea Paternesi
3 // Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2014, 2015, 2016,
4 // 2020 Ben Asselstine
5 //
6 // This program is free software; you can redistribute it and/or modify
7 // it under the terms of the GNU General Public License as published by
8 // the Free Software Foundation; either version 3 of the License, or
9 // (at your option) any later version.
10 //
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU Library General Public License for more details.
15 //
16 // You should have received a copy of the GNU General Public License
17 // along with this program; if not, write to the Free Software
18 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 // 02110-1301, USA.
20 #include <sigc++/functors/mem_fun.h>
21 #include <iostream>
22 #include "ImageCache.h"
23 #include "gui/image-helpers.h"
24 #include "playerlist.h"
25 #include "stack.h"
26 #include "player.h"
27 #include "tilesetlist.h"
28 #include "GameMap.h"
29 #include "armysetlist.h"
30 #include "shield.h"
31 #include "citysetlist.h"
32 #include "shieldsetlist.h"
33 #include "Configuration.h"
34 #include "city.h"
35 #include "Tile.h"
36 #include "ruin.h"
37 #include "temple.h"
38 #include "road.h"
39 #include "bridge.h"
40 #include "FogMap.h"
41 #include "shieldset.h"
42 #include "ScenarioMedia.h"
43
44 ImageCache* ImageCache::s_instance = 0;
45
getInstance()46 ImageCache* ImageCache::getInstance()
47 {
48 if (!s_instance)
49 s_instance = new ImageCache();
50
51 return s_instance;
52 }
53
deleteInstance()54 void ImageCache::deleteInstance()
55 {
56 if (!s_instance)
57 return;
58
59 delete s_instance;
60 s_instance = NULL;
61 }
62
ImageCache()63 ImageCache::ImageCache()
64 : d_cachesize(0),
65 selectorcache((sigc::ptr_fun(&SelectorPixMaskCacheItem::generate))),
66 armycache((sigc::ptr_fun(&ArmyPixMaskCacheItem::generate))),
67 flagcache((sigc::ptr_fun(&FlagPixMaskCacheItem::generate))),
68 circledarmycache((sigc::ptr_fun(&CircledArmyPixMaskCacheItem::generate))),
69 tilecache((sigc::ptr_fun(&TilePixMaskCacheItem::generate))),
70 citycache((sigc::ptr_fun(&CityPixMaskCacheItem::generate))),
71 towercache((sigc::ptr_fun(&TowerPixMaskCacheItem::generate))),
72 templecache((sigc::ptr_fun(&TemplePixMaskCacheItem::generate))),
73 ruincache((sigc::ptr_fun(&RuinPixMaskCacheItem::generate))),
74 diplomacycache((sigc::ptr_fun(&DiplomacyPixMaskCacheItem::generate))),
75 roadcache((sigc::ptr_fun(&RoadPixMaskCacheItem::generate))),
76 fogcache((sigc::ptr_fun(&FogPixMaskCacheItem::generate))),
77 bridgecache((sigc::ptr_fun(&BridgePixMaskCacheItem::generate))),
78 cursorcache((sigc::ptr_fun(&CursorPixMaskCacheItem::generate))),
79 shieldcache((sigc::ptr_fun(&ShieldPixMaskCacheItem::generate))),
80 prodshieldcache((sigc::ptr_fun(&ProdShieldPixMaskCacheItem::generate))),
81 movebonuscache((sigc::ptr_fun(&MoveBonusPixMaskCacheItem::generate))),
82 shipcache((sigc::ptr_fun(&ShipPixMaskCacheItem::generate))),
83 plantedstandardcache((sigc::ptr_fun(&PlantedStandardPixMaskCacheItem::generate))),
84 portcache((sigc::ptr_fun(&PortPixMaskCacheItem::generate))),
85 signpostcache((sigc::ptr_fun(&SignpostPixMaskCacheItem::generate))),
86 bagcache((sigc::ptr_fun(&BagPixMaskCacheItem::generate))),
87 explosioncache((sigc::ptr_fun(&ExplosionPixMaskCacheItem::generate))),
88 newlevelcache((sigc::ptr_fun(&NewLevelPixMaskCacheItem::generate))),
89 defaulttilestylecache((sigc::ptr_fun(&DefaultTileStylePixMaskCacheItem::generate))),
90 tartancache((sigc::ptr_fun(&TartanPixMaskCacheItem::generate))),
91 emptytartancache((sigc::ptr_fun(&EmptyTartanPixMaskCacheItem::generate))),
92 statuscache((sigc::ptr_fun(&StatusPixMaskCacheItem::generate))),
93 gamebuttoncache((sigc::ptr_fun(&GameButtonPixMaskCacheItem::generate))),
94 dialogcache((sigc::ptr_fun(&DialogPixMaskCacheItem::generate))),
95 medalcache((sigc::ptr_fun(&MedalPixMaskCacheItem::generate)))
96 {
97 loadDiplomacyImages();
98 loadCursorImages();
99 loadProdShieldImages();
100 loadMoveBonusImages();
101 loadMedalImages(ScenarioMedia::getDefaultSmallMedalsImageFilename(),
102 ScenarioMedia::getDefaultBigMedalsImageFilename());
103 d_smallruinedcity = loadMiscImage("smallruinedcity.png");
104 d_smallhero = loadMiscImage("hero.png");
105 d_smallbag = loadMiscImage("bag.png");
106 d_smallinactivehero = loadMiscImage("hero-inactive.png");
107 d_small_ruin_unexplored = loadMiscImage("smallunexploredruin.png");
108 d_small_stronghold_unexplored =
109 loadMiscImage("smallunexploredstronghold.png");
110 d_small_ruin_explored = loadMiscImage("smallexploredruin.png");
111 d_small_temple = loadMiscImage("smalltemple.png");
112 loadNewLevelImages();
113 loadDefaultTileStyleImages();
114 loadWaypointImages(); //only for game. not for editors.
115 loadGameButtonImages(); //only for game. not for editors.
116 d_nextturn = NULL;
117 d_citydefeated = NULL;
118 d_winning = NULL;
119 d_malehero = NULL;
120 d_femalehero = NULL;
121 d_ruinsuccess = NULL;
122 d_ruindefeat = NULL;
123 d_parleyoffered = NULL;
124 d_parleyrefused = NULL;
125 d_commentator = NULL;
126 }
127
loadDiplomacyImages()128 bool ImageCache::loadDiplomacyImages()
129 {
130 bool broken = false;
131 int ts = 30;
132 std::vector<PixMask*> diplomacy;
133 diplomacy = disassemble_row(File::getVariousFile("diplomacy-small.png"),
134 DIPLOMACY_TYPES, broken);
135 if (broken)
136 return false;
137 for (unsigned int i = 0; i < DIPLOMACY_TYPES ; i++)
138 {
139 if (diplomacy[i]->get_width() != ts)
140 PixMask::scale(diplomacy[i], ts, ts);
141 d_diplomacy[0][i] = diplomacy[i];
142 }
143
144 ts = 50;
145 diplomacy = disassemble_row(File::getVariousFile("diplomacy-large.png"),
146 DIPLOMACY_TYPES, broken);
147 if (broken)
148 return false;
149 for (unsigned int i = 0; i < DIPLOMACY_TYPES ; i++)
150 {
151 if (diplomacy[i]->get_width() != ts)
152 PixMask::scale(diplomacy[i], ts, ts);
153 d_diplomacy[1][i] = diplomacy[i];
154 }
155 return true;
156 }
157
loadCursorImages()158 bool ImageCache::loadCursorImages()
159 {
160 bool broken = false;
161 int ts = 16;
162
163 // load the cursor pictures
164 std::vector<PixMask*> cursor;
165 cursor = disassemble_row(File::getVariousFile("cursors.png"),
166 CURSOR_TYPES, broken);
167 if (broken)
168 return false;
169 for (unsigned int i = 0; i < CURSOR_TYPES ; i++)
170 {
171 if (cursor[i]->get_width() != ts)
172 PixMask::scale(cursor[i], ts, ts);
173 d_cursor[i] = cursor[i];
174 }
175 return true;
176 }
177
loadProdShieldImages()178 bool ImageCache::loadProdShieldImages()
179 {
180 bool broken = false;
181 //load the production shieldset
182 std::vector<PixMask*> prodshield;
183 prodshield = disassemble_row
184 (File::getVariousFile("prodshieldset.png"), PRODUCTION_SHIELD_TYPES,
185 broken);
186 if (broken)
187 return false;
188 for (unsigned int i = 0; i < PRODUCTION_SHIELD_TYPES; i++)
189 d_prodshield[i] = prodshield[i];
190 prodshield.clear();
191 return true;
192 }
193
loadMoveBonusImages()194 bool ImageCache::loadMoveBonusImages()
195 {
196 bool broken = false;
197 //load the movement bonus icons
198 std::vector<PixMask*> movebonus;
199 movebonus = disassemble_row(File::getVariousFile("movebonus.png"),
200 MOVE_BONUS_TYPES, broken);
201 if (broken)
202 return false;
203 for (unsigned int i = 0; i < MOVE_BONUS_TYPES; i++)
204 d_movebonus[i] = movebonus[i];
205 return true;
206 }
207
loadNewLevelImages()208 bool ImageCache::loadNewLevelImages()
209 {
210 bool broken = false;
211 std::vector<PixMask*> half;
212 half = disassemble_row
213 (ScenarioMedia::getDefaultHeroNewLevelMaleImageFilename(), 2, broken);
214 if (broken)
215 return false;
216 d_newlevel_male = half[0];
217 d_newlevelmask_male = half[1];
218 half = disassemble_row
219 (ScenarioMedia::getDefaultHeroNewLevelFemaleImageFilename(), 2, broken);
220 if (broken)
221 return false;
222 d_newlevel_female = half[0];
223 d_newlevelmask_female = half[1];
224 return true;
225 }
226
loadDefaultTileStyleImages()227 bool ImageCache::loadDefaultTileStyleImages()
228 {
229 bool broken = false;
230 std::vector<PixMask*> images =
231 disassemble_row(File::getVariousFile("tilestyles.png"),
232 DEFAULT_TILESTYLE_TYPES, broken);
233 if (broken)
234 return false;
235 for (unsigned int i = 0; i < DEFAULT_TILESTYLE_TYPES; i++)
236 d_default_tilestyles[i] = images[i];
237 return true;
238 }
239
loadMedalImages(Glib::ustring sm,Glib::ustring lg)240 bool ImageCache::loadMedalImages(Glib::ustring sm, Glib::ustring lg)
241 {
242 bool broken = false;
243 //load the medal icons
244 int ts = 40;
245 std::vector<PixMask*> medal;
246 medal = disassemble_row(sm, MEDAL_TYPES, broken);
247 if (broken)
248 return false;
249 for (unsigned int i = 0; i < MEDAL_TYPES; i++)
250 {
251 if (medal[i]->get_width() != ts)
252 PixMask::scale(medal[i], ts, ts);
253 d_medal[0][i] = medal[i];
254 }
255 medal = disassemble_row(lg, MEDAL_TYPES, broken);
256 if (broken)
257 return false;
258 for (unsigned int i = 0; i < MEDAL_TYPES; i++)
259 d_medal[1][i] = medal[i];
260 return true;
261 }
262
loadWaypointImages()263 bool ImageCache::loadWaypointImages()
264 {
265 bool broken = false;
266 std::vector<PixMask*> images = disassemble_row
267 (File::getVariousFile("waypoints.png"), NUM_WAYPOINTS, broken);
268 if (broken)
269 return false;
270 for (unsigned int i = 0; i < NUM_WAYPOINTS; i++)
271 d_waypoint[i] = images[i];
272 return true;
273 }
274
loadGameButtonImages()275 bool ImageCache::loadGameButtonImages()
276 {
277 bool broken = false;
278 std::vector<PixMask*> images = disassemble_row
279 (File::getVariousFile("buttons.png"), NUM_GAME_BUTTON_IMAGES, broken);
280 if (broken)
281 return false;
282 int w = 0, h = 0;
283 Gtk::IconSize::lookup(Gtk::IconSize(Gtk::ICON_SIZE_BUTTON), w, h);
284 for (unsigned int i = 0; i < NUM_GAME_BUTTON_IMAGES; i++)
285 PixMask::scale(images[i], w, h);
286 for (unsigned int i = 0; i < NUM_GAME_BUTTON_IMAGES; i++)
287 d_gamebuttons[i] = images[i];
288
289 images.clear();
290 return true;
291 }
292
loadMiscImage(Glib::ustring pngfile)293 PixMask* ImageCache::loadMiscImage(Glib::ustring pngfile)
294 {
295 bool broken = false;
296 return PixMask::create(File::getVariousFile(pngfile), broken);
297 }
298
~ImageCache()299 ImageCache::~ImageCache()
300 {
301
302 for (unsigned int i = 0; i < DIPLOMACY_TYPES;i++)
303 {
304 delete d_diplomacy[0][i];
305 delete d_diplomacy[1][i];
306 }
307
308 for (unsigned int i = 0; i < CURSOR_TYPES;i++)
309 delete d_cursor[i];
310
311 for (unsigned int i = 0; i < PRODUCTION_SHIELD_TYPES; i++)
312 delete d_prodshield[i];
313
314 for (unsigned int i = 0; i < MOVE_BONUS_TYPES; i++)
315 delete d_movebonus[i];
316
317 delete d_newlevel_male;
318 delete d_newlevelmask_male;
319 delete d_newlevel_female;
320 delete d_newlevelmask_female;
321
322 for (unsigned int i = 0; i < DEFAULT_TILESTYLE_TYPES; i++)
323 delete d_default_tilestyles[i];
324
325 for (unsigned int i = 0; i < MEDAL_TYPES; i++)
326 {
327 delete d_medal[0][i];
328 delete d_medal[1][i];
329 }
330
331 delete d_smallruinedcity;
332 delete d_smallhero;
333 delete d_smallbag;
334 delete d_smallinactivehero;
335 delete d_small_temple;
336 delete d_small_ruin_unexplored;
337 delete d_small_stronghold_unexplored;
338 delete d_small_ruin_explored;
339
340 for (unsigned int i = 0; i < NUM_WAYPOINTS; i++)
341 delete d_waypoint[i];
342
343 for (unsigned int i = 0; i < NUM_GAME_BUTTON_IMAGES; i++)
344 delete d_gamebuttons[i];
345
346 if (d_nextturn)
347 delete d_nextturn;
348 if (d_citydefeated)
349 delete d_citydefeated;
350 if (d_winning)
351 delete d_winning;
352 if (d_malehero)
353 delete d_malehero;
354 if (d_femalehero)
355 delete d_femalehero;
356 if (d_ruinsuccess)
357 delete d_ruinsuccess;
358 if (d_ruindefeat)
359 delete d_ruindefeat;
360 if (d_parleyoffered)
361 delete d_parleyoffered;
362 if (d_parleyrefused)
363 delete d_parleyrefused;
364 if (d_commentator)
365 delete d_commentator;
366 reset();
367 }
368
reset()369 void ImageCache::reset()
370 {
371 selectorcache.reset();
372 flagcache.reset();
373 armycache.reset();
374 circledarmycache.reset();
375 tilecache.reset();
376 citycache.reset();
377 towercache.reset();
378 templecache.reset();
379 ruincache.reset();
380 diplomacycache.reset();
381 roadcache.reset();
382 fogcache.reset();
383 bridgecache.reset();
384 cursorcache.reset();
385 shieldcache.reset();
386 prodshieldcache.reset();
387 movebonuscache.reset();
388 shipcache.reset();
389 plantedstandardcache.reset();
390 portcache.reset();
391 signpostcache.reset();
392 bagcache.reset();
393 explosioncache.reset();
394 newlevelcache.reset();
395 defaulttilestylecache.reset();
396 tartancache.reset();
397 emptytartancache.reset();
398 statuscache.reset();
399 gamebuttoncache.reset();
400 dialogcache.reset();
401 medalcache.reset();
402
403 d_cachesize = 0;
404 return;
405 }
406
checkPictures()407 void ImageCache::checkPictures()
408 {
409 guint32 maxcache = Configuration::s_cacheSize;
410 if (maxcache < MINIMUM_CACHE_SIZE)
411 maxcache = MINIMUM_CACHE_SIZE;
412
413 if (d_cachesize < maxcache)
414 return;
415
416 // Now the cache size has been exceeded. We try to guarantee the values
417 // given above and reduce the number of images. Let us start with the
418 // cities
419
420 unsigned int num_players = Playerlist::getInstance()->countPlayersAlive();
421 if (armycache.size() >= 15 * num_players)
422 {
423 d_cachesize -= armycache.discardHalf();
424 if (d_cachesize < maxcache)
425 return;
426 }
427
428 if (circledarmycache.size() >= 15 * num_players)
429 {
430 d_cachesize -= circledarmycache.discardHalf();
431 if (d_cachesize < maxcache)
432 return;
433 }
434
435 if (flagcache.size() >= num_players * MAX_STACK_SIZE)
436 {
437 d_cachesize -= flagcache.discardHalf();
438 if (d_cachesize < maxcache)
439 return;
440 }
441
442 if (citycache.size() >= num_players)
443 {
444 d_cachesize -= citycache.discardHalf();
445 if (d_cachesize < maxcache)
446 return;
447 }
448
449 if (roadcache.size() >= ROAD_TYPES / 2)
450 {
451 d_cachesize -= roadcache.discardHalf();
452 if (d_cachesize < maxcache)
453 return;
454 }
455
456 if (fogcache.size() >= FOG_TYPES / 2)
457 {
458 d_cachesize -= fogcache.discardHalf();
459 if (d_cachesize < maxcache)
460 return;
461 }
462
463 if (bridgecache.size() >= BRIDGE_TYPES)
464 {
465 d_cachesize -= bridgecache.discardHalf();
466 if (d_cachesize < maxcache)
467 return;
468 }
469
470 if (shipcache.size() >= MAX_PLAYERS)
471 {
472 d_cachesize -= shipcache.discardHalf();
473 if (d_cachesize < maxcache)
474 return;
475 }
476
477 if (plantedstandardcache.size() >= num_players)
478 {
479 d_cachesize -= plantedstandardcache.discardHalf();
480 if (d_cachesize < maxcache)
481 return;
482 }
483
484 if (portcache.size() > 1)
485 {
486 d_cachesize -= portcache.discardHalf();
487 if (d_cachesize < maxcache)
488 return;
489 }
490
491 if (towercache.size() >= num_players)
492 {
493 d_cachesize -= towercache.discardHalf();
494 if (d_cachesize < maxcache)
495 return;
496 }
497
498 if (templecache.size() >= TEMPLE_TYPES)
499 {
500 d_cachesize -= templecache.discardHalf();
501 if (d_cachesize < maxcache)
502 return;
503 }
504
505 if (ruincache.size() >= RUIN_TYPES)
506 {
507 d_cachesize -= ruincache.discardHalf();
508 if (d_cachesize < maxcache)
509 return;
510 }
511
512 if (signpostcache.size() > 1)
513 {
514 d_cachesize -= signpostcache.discardHalf();
515 if (d_cachesize < maxcache)
516 return;
517 }
518
519 if (bagcache.size() > 1)
520 {
521 d_cachesize -= bagcache.discardHalf();
522 if (d_cachesize < maxcache)
523 return;
524 }
525
526 if (selectorcache.size() >= num_players * MAX_STACK_SIZE)
527 {
528 d_cachesize -= selectorcache.discardHalf();
529 if (d_cachesize < maxcache)
530 return;
531 }
532
533 if (tilecache.size() >= 15*15)
534 {
535 d_cachesize -= tilecache.discardHalf();
536 if (d_cachesize < maxcache)
537 return;
538 }
539
540 if (diplomacycache.size() >= DIPLOMACY_TYPES)
541 {
542 d_cachesize -= diplomacycache.discardHalf();
543 if (d_cachesize < maxcache)
544 return;
545 }
546
547 if (cursorcache.size() >= CURSOR_TYPES)
548 {
549 d_cachesize -= cursorcache.discardHalf();
550 if (d_cachesize < maxcache)
551 return;
552 }
553
554 if (shieldcache.size() >= num_players * 3)
555 {
556 d_cachesize -= shieldcache.discardHalf();
557 if (d_cachesize < maxcache)
558 return;
559 }
560
561 if (prodshieldcache.size() >= PRODUCTION_SHIELD_TYPES)
562 {
563 d_cachesize -= prodshieldcache.discardHalf();
564 if (d_cachesize < maxcache)
565 return;
566 }
567
568 if (movebonuscache.size() >= MOVE_BONUS_TYPES)
569 {
570 d_cachesize -= movebonuscache.discardHalf();
571 if (d_cachesize < maxcache)
572 return;
573 }
574
575 if (explosioncache.size() > 1)
576 {
577 d_cachesize -= explosioncache.discardHalf();
578 if (d_cachesize < maxcache)
579 return;
580 }
581
582 if (newlevelcache.size() > 2)
583 {
584 d_cachesize -= newlevelcache.discardHalf();
585 if (d_cachesize < maxcache)
586 return;
587 }
588
589 if (defaulttilestylecache.size() >= DEFAULT_TILESTYLE_TYPES)
590 {
591 d_cachesize -= defaulttilestylecache.discardHalf();
592 if (d_cachesize < maxcache)
593 return;
594 }
595
596 if (tartancache.size() >= MAX_PLAYERS + 1)
597 {
598 d_cachesize -= tartancache.discardHalf();
599 if (d_cachesize < maxcache)
600 return;
601 }
602
603 if (emptytartancache.size() >= MAX_PLAYERS + 1)
604 {
605 d_cachesize -= emptytartancache.discardHalf();
606 if (d_cachesize < maxcache)
607 return;
608 }
609
610 if (statuscache.size() >= 6)
611 {
612 d_cachesize -= statuscache.discardHalf();
613 if (d_cachesize < maxcache)
614 return;
615 }
616
617 if (gamebuttoncache.size() >= 12)
618 {
619 d_cachesize -= gamebuttoncache.discardHalf();
620 if (d_cachesize < maxcache)
621 return;
622 }
623
624 if (dialogcache.size() >= 10)
625 {
626 d_cachesize -= dialogcache.discardHalf();
627 if (d_cachesize < maxcache)
628 return;
629 }
630
631 if (medalcache.size() >= 6)
632 {
633 d_cachesize -= medalcache.discardHalf();
634 if (d_cachesize < maxcache)
635 return;
636 }
637 }
638
getSelectorPic(guint32 type,guint32 frame,const Player * p)639 PixMask* ImageCache::getSelectorPic(guint32 type, guint32 frame,
640 const Player *p)
641 {
642 return getSelectorPic(type, frame, p,
643 GameMap::getInstance()->getTilesetId());
644 }
645
getSelectorPic(guint32 type,guint32 frame,const Player * p,guint32 tileset)646 PixMask* ImageCache::getSelectorPic(guint32 type, guint32 frame,
647 const Player *p, guint32 tileset)
648 {
649 guint32 added = 0;
650 SelectorPixMaskCacheItem i;
651 i.tileset = tileset;
652 i.type = type;
653 i.frame = frame;
654 i.player_id = p->getId();
655 PixMask *s = selectorcache.get(i, added);
656 d_cachesize += added;
657 if (added)
658 checkPictures();
659 return s;
660 }
661
getArmyPic(Army * a,bool greyed)662 PixMask* ImageCache::getArmyPic(Army *a, bool greyed)
663 {
664 return getArmyPic(a->getOwner()->getArmyset(), a->getTypeId(),
665 a->getOwner(), NULL, true, 0, greyed);
666 }
667
getDialogArmyPic(Army * a,guint32 font_size,bool greyed)668 PixMask* ImageCache::getDialogArmyPic(Army *a, guint32 font_size, bool greyed)
669 {
670 return getArmyPic(a->getOwner()->getArmyset(), a->getTypeId(),
671 a->getOwner(), NULL, false, font_size, greyed);
672 }
673
getArmyPic(guint32 armyset,guint32 army_id,const Player * p,const bool * medals,bool map,guint32 font_size,bool greyed)674 PixMask* ImageCache::getArmyPic(guint32 armyset, guint32 army_id,
675 const Player* p, const bool *medals,
676 bool map, guint32 font_size, bool greyed)
677 {
678 guint added = 0;
679 ArmyPixMaskCacheItem i;
680 i.armyset = armyset;
681 i.army_id = army_id;
682 i.player_id = p->getId();
683 for (guint32 j = 0; j < MEDAL_TYPES; j++)
684 if (medals)
685 i.medals[j] = medals[j];
686 else
687 i.medals[j] = false;
688 i.map = map;
689 i.font_size = font_size;
690 i.greyed = greyed;
691 PixMask *s = armycache.get(i, added);
692 if (!s)
693 {
694 guint32 size = Armysetlist::getInstance()->get(i.armyset)->getTileSize();
695 s = getDefaultTileStylePic(DEFAULT_TILESTYLE_TYPES-1, size);
696 }
697 d_cachesize += added;
698 if (added)
699 checkPictures();
700 return s;
701 }
702
getFlagPic(guint32 stack_size,const Player * p,guint32 tileset)703 PixMask* ImageCache::getFlagPic(guint32 stack_size, const Player *p, guint32 tileset)
704 {
705 guint32 added = 0;
706 FlagPixMaskCacheItem i;
707 i.tileset = tileset;
708 i.size = stack_size;
709 i.player_id = p->getId();
710 PixMask *s = flagcache.get(i, added);
711 d_cachesize += added;
712 if (added)
713 checkPictures();
714 return s;
715 }
716
getFlagPic(guint32 stack_size,const Player * p)717 PixMask* ImageCache::getFlagPic(guint32 stack_size, const Player *p)
718 {
719 return getFlagPic(stack_size, p,
720 GameMap::getInstance()->getTilesetId());
721 }
722
getFlagPic(const Stack * s)723 PixMask* ImageCache::getFlagPic(const Stack* s)
724 {
725 return getFlagPic(s, GameMap::getInstance()->getTilesetId());
726 }
727
getFlagPic(const Stack * s,guint32 tileset)728 PixMask* ImageCache::getFlagPic(const Stack* s, guint32 tileset)
729 {
730 return getFlagPic(s->size(), s->getOwner(), tileset);
731 }
732
getCircledArmyPic(Army * a,bool greyed,guint32 circle_colour_id,bool show_army,guint32 font_size)733 PixMask* ImageCache::getCircledArmyPic(Army *a, bool greyed,
734 guint32 circle_colour_id,
735 bool show_army, guint32 font_size)
736 {
737 return getCircledArmyPic(a->getOwner()->getArmyset(), a->getTypeId(),
738 a->getOwner(), NULL, greyed, circle_colour_id, show_army,
739 font_size);
740 }
741
getCircledArmyPic(guint32 armyset,guint32 army_id,const Player * p,const bool * medals,bool greyed,guint32 circle_colour_id,bool show_army,guint32 font_size)742 PixMask* ImageCache::getCircledArmyPic(guint32 armyset, guint32 army_id,
743 const Player* p,
744 const bool *medals, bool greyed,
745 guint32 circle_colour_id,
746 bool show_army, guint32 font_size)
747 {
748 guint added = 0;
749 CircledArmyPixMaskCacheItem i;
750 i.armyset = armyset;
751 i.army_id = army_id;
752 i.player_id = p->getId();
753 for (guint32 j = 0; j < MEDAL_TYPES; j++)
754 if (medals)
755 i.medals[j] = medals[j];
756 else
757 i.medals[j] = false;
758 i.greyed = greyed;
759 i.circle_colour_id = circle_colour_id;
760 i.show_army = show_army;
761 i.font_size = font_size;
762 PixMask *s = circledarmycache.get(i, added);
763 d_cachesize += added;
764 if (added)
765 checkPictures();
766 return s;
767 }
768
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,int stone_type)769 PixMask* ImageCache::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, int stone_type)
770 {
771 guint32 tileset = GameMap::getInstance()->getTilesetId();
772 guint32 cityset = GameMap::getInstance()->getCitysetId();
773 guint32 shieldset = GameMap::getInstance()->getShieldsetId();
774 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, shieldset, stone_type);
775 }
776
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,guint32 shieldset,int stone_type)777 PixMask* ImageCache::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, guint32 shieldset, int stone_type)
778 {
779 guint added = 0;
780 TilePixMaskCacheItem i;
781 i.tile_style_id = tile_style_id;
782 i.fog_type_id = fog_type_id;
783 i.has_bag = has_bag;
784 i.has_standard = has_standard;
785 i.standard_player_id = standard_player_id;
786 i.stack_size = stack_size; //flag size
787 i.stack_player_id = stack_player_id;
788 i.army_type_id = army_type_id;
789 i.has_tower = has_tower;
790 i.has_ship = has_ship;
791 i.building_type = building_type;
792 i.building_subtype = building_subtype;
793 i.building_tile = building_tile;
794 i.building_player_id = building_player_id;
795 i.tilesize = tilesize;
796 i.has_grid = has_grid;
797 i.tileset = tileset;
798 i.cityset = cityset;
799 i.shieldset = shieldset;
800 i.stone_type = stone_type;
801 PixMask *s = tilecache.get(i, added);
802 d_cachesize += added;
803 if (added)
804 checkPictures();
805 return s;
806 }
807
getCityPic(const City * city,guint32 cityset)808 PixMask* ImageCache::getCityPic(const City* city, guint32 cityset)
809 {
810 if (!city)
811 return NULL;
812 int type;
813 if (city->isBurnt() == true)
814 type = -1;
815 else
816 type = 0;
817 return getCityPic(type, city->getOwner(), cityset);
818 }
819
getCityPic(const City * city)820 PixMask* ImageCache::getCityPic(const City* city)
821 {
822 guint32 cityset = GameMap::getInstance()->getCitysetId();
823 return getCityPic(city, cityset);
824 }
825
getCityPic(int type,const Player * p,guint32 cityset)826 PixMask* ImageCache::getCityPic(int type, const Player* p, guint32 cityset)
827 {
828 guint added = 0;
829 CityPixMaskCacheItem i;
830 i.cityset = cityset;
831 i.type = type;
832 i.player_id = p->getId();
833 PixMask *s = citycache.get(i, added);
834 d_cachesize += added;
835 if (added)
836 checkPictures();
837 return s;
838 }
839
getTowerPic(const Player * p)840 PixMask* ImageCache::getTowerPic(const Player* p)
841 {
842 guint32 cityset = GameMap::getInstance()->getCitysetId();
843 return getTowerPic(p, cityset);
844 }
845
getTowerPic(const Player * p,guint32 cityset)846 PixMask* ImageCache::getTowerPic(const Player* p, guint32 cityset)
847 {
848 guint added = 0;
849 TowerPixMaskCacheItem i;
850 i.cityset = cityset;
851 i.player_id = p->getId();
852 PixMask *s = towercache.get(i, added);
853 d_cachesize += added;
854 if (added)
855 checkPictures();
856 return s;
857 }
858
getTemplePic(Temple * t)859 PixMask* ImageCache::getTemplePic(Temple *t)
860 {
861 guint32 cityset = GameMap::getInstance()->getCitysetId();
862 return getTemplePic(t->getType(), cityset);
863 }
864
getTemplePic(int type)865 PixMask* ImageCache::getTemplePic(int type)
866 {
867 guint32 cityset = GameMap::getInstance()->getCitysetId();
868 return getTemplePic(type, cityset);
869 }
870
getTemplePic(int type,guint32 cityset)871 PixMask* ImageCache::getTemplePic(int type, guint32 cityset)
872 {
873 guint added = 0;
874 TemplePixMaskCacheItem i;
875 i.cityset = cityset;
876 i.type = type;
877 PixMask *s = templecache.get(i, added);
878 d_cachesize += added;
879 if (added)
880 checkPictures();
881 return s;
882 }
883
getRuinPic(Ruin * ruin)884 PixMask* ImageCache::getRuinPic(Ruin *ruin)
885 {
886 guint32 cityset = GameMap::getInstance()->getCitysetId();
887 return getRuinPic(ruin->getType(), cityset);
888 }
getRuinPic(int type)889 PixMask* ImageCache::getRuinPic(int type)
890 {
891 guint32 cityset = GameMap::getInstance()->getCitysetId();
892 return getRuinPic(type, cityset);
893 }
894
getRuinPic(int type,guint32 cityset)895 PixMask* ImageCache::getRuinPic(int type, guint32 cityset)
896 {
897 guint added = 0;
898 RuinPixMaskCacheItem i;
899 i.cityset = cityset;
900 i.type = type;
901 PixMask *s = ruincache.get(i, added);
902 d_cachesize += added;
903 if (added)
904 checkPictures();
905 return s;
906 }
907
getDiplomacyPic(int type,Player::DiplomaticState state,guint32 font_size)908 PixMask* ImageCache::getDiplomacyPic(int type, Player::DiplomaticState state,
909 guint32 font_size)
910 {
911 guint added = 0;
912 DiplomacyPixMaskCacheItem i;
913 i.type = type;
914 i.state = state;
915 i.font_size = font_size;
916 PixMask *s = diplomacycache.get(i, added);
917 d_cachesize += added;
918 if (added)
919 checkPictures();
920 return s;
921 }
922
getRoadPic(Road * r)923 PixMask* ImageCache::getRoadPic(Road *r)
924 {
925 return ImageCache::getRoadPic(r->getType());
926 }
927
getRoadPic(int type)928 PixMask* ImageCache::getRoadPic(int type)
929 {
930 return getRoadPic(type, GameMap::getInstance()->getTilesetId());
931 }
932
getRoadPic(int type,guint32 tileset)933 PixMask* ImageCache::getRoadPic(int type, guint32 tileset)
934 {
935 guint added = 0;
936 RoadPixMaskCacheItem i;
937 i.type = type;
938 i.tileset = tileset;
939 PixMask *s = roadcache.get(i, added);
940 d_cachesize += added;
941 if (added)
942 checkPictures();
943 return s;
944 }
945
getFogPic(int type)946 PixMask* ImageCache::getFogPic(int type)
947 {
948 return getFogPic(type, GameMap::getInstance()->getTilesetId());
949 }
950
getFogPic(int type,guint32 tileset)951 PixMask* ImageCache::getFogPic(int type, guint32 tileset)
952 {
953 guint added = 0;
954 FogPixMaskCacheItem i;
955 i.type = type;
956 i.tileset = tileset;
957 PixMask *s = fogcache.get(i, added);
958 d_cachesize += added;
959 if (added)
960 checkPictures();
961 return s;
962 }
963
getBridgePic(Bridge * b)964 PixMask* ImageCache::getBridgePic(Bridge *b)
965 {
966 return getBridgePic(b->getType());
967 }
968
getBridgePic(int type)969 PixMask* ImageCache::getBridgePic(int type)
970 {
971 return getBridgePic(type, GameMap::getInstance()->getTilesetId());
972 }
973
getBridgePic(int type,guint32 tileset)974 PixMask* ImageCache::getBridgePic(int type, guint32 tileset)
975 {
976 guint added = 0;
977 BridgePixMaskCacheItem i;
978 i.type = type;
979 i.tileset = tileset;
980 PixMask *s = bridgecache.get(i, added);
981 d_cachesize += added;
982 if (added)
983 checkPictures();
984 return s;
985 }
986
getCursorPic(int type,guint32 font_size)987 PixMask* ImageCache::getCursorPic(int type, guint32 font_size)
988 {
989 guint added = 0;
990 CursorPixMaskCacheItem i;
991 i.type = type;
992 i.font_size = font_size;
993 PixMask *s = cursorcache.get(i, added);
994 d_cachesize += added;
995 if (added)
996 checkPictures();
997 return s;
998 }
999
getShieldPic(guint32 type,Player * p,bool map,guint32 font_size)1000 PixMask* ImageCache::getShieldPic(guint32 type, Player *p, bool map,
1001 guint32 font_size)
1002 {
1003 guint32 shieldset = GameMap::getInstance()->getShieldsetId();
1004 return getShieldPic(shieldset, type, p->getId(), map, font_size);
1005 }
1006
getShieldPic(guint32 shieldset,guint32 type,guint32 colour,bool map,guint32 font_size)1007 PixMask* ImageCache::getShieldPic(guint32 shieldset, guint32 type,
1008 guint32 colour, bool map,
1009 guint32 font_size)
1010 {
1011 guint added = 0;
1012 ShieldPixMaskCacheItem i;
1013 i.type = type;
1014 i.shieldset = shieldset;
1015 i.colour = colour;
1016 i.map = map;
1017 i.font_size = font_size;
1018 PixMask *s = shieldcache.get(i, added);
1019 d_cachesize += added;
1020 if (added)
1021 checkPictures();
1022 return s;
1023 }
1024
getStatusPic(guint32 type,guint32 font_size)1025 PixMask* ImageCache::getStatusPic(guint32 type, guint32 font_size)
1026 {
1027 guint added = 0;
1028 StatusPixMaskCacheItem i;
1029 i.type = type;
1030 i.font_size = font_size;
1031 PixMask *s = statuscache.get(i, added);
1032 d_cachesize += added;
1033 if (added)
1034 checkPictures();
1035 return s;
1036 }
1037
getGameButtonPic(guint32 type,guint32 font_size)1038 PixMask* ImageCache::getGameButtonPic(guint32 type, guint32 font_size)
1039 {
1040 guint added = 0;
1041 GameButtonPixMaskCacheItem i;
1042 i.type = type;
1043 i.font_size = font_size;
1044 PixMask *s = gamebuttoncache.get(i, added);
1045 d_cachesize += added;
1046 if (added)
1047 checkPictures();
1048 return s;
1049 }
1050
getProdShieldPic(guint32 type,bool prod)1051 PixMask* ImageCache::getProdShieldPic(guint32 type, bool prod)
1052 {
1053 guint added = 0;
1054 ProdShieldPixMaskCacheItem i;
1055 i.type = type;
1056 i.prod = prod;
1057 PixMask *s = prodshieldcache.get(i, added);
1058 d_cachesize += added;
1059 if (added)
1060 checkPictures();
1061 return s;
1062 }
1063
getMoveBonusPic(guint32 bonus,bool has_ship,guint32 font_size)1064 PixMask* ImageCache::getMoveBonusPic(guint32 bonus, bool has_ship,
1065 guint32 font_size)
1066 {
1067 guint added = 0;
1068 MoveBonusPixMaskCacheItem i;
1069 if (bonus == Tile::isFlying()) // show fly icon
1070 i.type = 4;
1071 else if (bonus & Tile::FOREST && bonus & Tile::HILLS) // show trees and hills
1072 i.type = 3;
1073 else if (bonus & Tile::HILLS) // show foothills
1074 i.type = 2;
1075 else if (bonus & Tile::FOREST) // show trees
1076 i.type = 1;
1077 else // show blank
1078 i.type = 0;
1079 if (has_ship && bonus != Tile::isFlying()) // (what a) show boat
1080 i.type = 5;
1081 i.font_size = font_size;
1082 PixMask *s = movebonuscache.get(i, added);
1083 d_cachesize += added;
1084 if (added)
1085 checkPictures();
1086 return s;
1087 }
1088
getShipPic(const Player * p)1089 PixMask* ImageCache::getShipPic(const Player* p)
1090 {
1091 guint added = 0;
1092 ShipPixMaskCacheItem i;
1093 i.player_id = p->getId();
1094 i.armyset = p->getArmyset();
1095 PixMask *s = shipcache.get(i, added);
1096 if (!s)
1097 {
1098 guint32 size = Armysetlist::getInstance()->get(i.armyset)->getTileSize();
1099 s = getDefaultTileStylePic(DEFAULT_TILESTYLE_TYPES-1, size);
1100 }
1101 d_cachesize += added;
1102 if (added)
1103 checkPictures();
1104 return s;
1105 }
1106
getPlantedStandardPic(const Player * p)1107 PixMask* ImageCache::getPlantedStandardPic(const Player* p)
1108 {
1109 guint added = 0;
1110 PlantedStandardPixMaskCacheItem i;
1111 i.player_id = p->getId();
1112 i.armyset = p->getArmyset();
1113 PixMask *s = plantedstandardcache.get(i, added);
1114 if (!s)
1115 {
1116 guint32 size = Armysetlist::getInstance()->get(i.armyset)->getTileSize();
1117 s = getDefaultTileStylePic(DEFAULT_TILESTYLE_TYPES-1, size);
1118 }
1119 d_cachesize += added;
1120 if (added)
1121 checkPictures();
1122 return s;
1123 }
1124
getPortPic()1125 PixMask* ImageCache::getPortPic()
1126 {
1127 return getPortPic(GameMap::getInstance()->getCitysetId());
1128 }
1129
getPortPic(guint32 cityset)1130 PixMask* ImageCache::getPortPic(guint32 cityset)
1131 {
1132 guint added = 0;
1133 PortPixMaskCacheItem i;
1134 i.cityset = cityset;
1135 PixMask *s = portcache.get(i, added);
1136 d_cachesize += added;
1137 if (added)
1138 checkPictures();
1139 return s;
1140 }
1141
getSignpostPic()1142 PixMask* ImageCache::getSignpostPic()
1143 {
1144 return getSignpostPic(GameMap::getInstance()->getCitysetId());
1145 }
1146
getSignpostPic(guint32 cityset)1147 PixMask* ImageCache::getSignpostPic(guint32 cityset)
1148 {
1149 guint added = 0;
1150 SignpostPixMaskCacheItem i;
1151 i.cityset = cityset;
1152 PixMask *s = signpostcache.get(i, added);
1153 d_cachesize += added;
1154 if (added)
1155 checkPictures();
1156 return s;
1157 }
1158
getBagPic()1159 PixMask* ImageCache::getBagPic()
1160 {
1161 guint32 armyset = Playerlist::getActiveplayer()->getArmyset();
1162 return getBagPic(armyset);
1163 }
1164
getBagPic(guint32 armyset)1165 PixMask* ImageCache::getBagPic(guint32 armyset)
1166 {
1167 guint added = 0;
1168 BagPixMaskCacheItem i;
1169 i.armyset = armyset;
1170 PixMask *s = bagcache.get(i, added);
1171 if (!s)
1172 {
1173 guint32 size = Armysetlist::getInstance()->get(i.armyset)->getTileSize();
1174 s = getDefaultTileStylePic(DEFAULT_TILESTYLE_TYPES-1, size);
1175 }
1176 d_cachesize += added;
1177 if (added)
1178 checkPictures();
1179 return s;
1180 }
1181
getExplosionPic()1182 PixMask* ImageCache::getExplosionPic()
1183 {
1184 return getExplosionPic(GameMap::getInstance()->getTilesetId());
1185 }
1186
getExplosionPic(guint32 tileset)1187 PixMask* ImageCache::getExplosionPic(guint32 tileset)
1188 {
1189 guint added = 0;
1190 ExplosionPixMaskCacheItem i;
1191 i.tileset = tileset;
1192 PixMask *s = explosioncache.get(i, added);
1193 d_cachesize += added;
1194 if (added)
1195 checkPictures();
1196 return s;
1197 }
1198
getNewLevelPic(const Player * p,guint32 gender,guint32 font_size)1199 PixMask* ImageCache::getNewLevelPic(const Player* p, guint32 gender,
1200 guint32 font_size)
1201 {
1202 guint added = 0;
1203 NewLevelPixMaskCacheItem i;
1204 i.player_id = p->getId();
1205 i.gender = gender;
1206 i.font_size = font_size;
1207 PixMask *s = newlevelcache.get(i, added);
1208 d_cachesize += added;
1209 if (added)
1210 checkPictures();
1211 return s;
1212 }
1213
getDefaultTileStylePic(guint32 type,guint32 size)1214 PixMask* ImageCache::getDefaultTileStylePic(guint32 type, guint32 size)
1215 {
1216 guint added = 0;
1217 DefaultTileStylePixMaskCacheItem i;
1218 i.tilestyle_type = type;
1219 i.tilesize = size;
1220 PixMask *s = defaulttilestylecache.get(i, added);
1221 d_cachesize += added;
1222 if (added)
1223 checkPictures();
1224 return s;
1225 }
1226
getTartanPic(const Player * p,guint32 width,Shieldset * shieldset,guint32 font_size)1227 PixMask* ImageCache::getTartanPic(const Player *p, guint32 width, Shieldset *shieldset, guint32 font_size)
1228 {
1229 guint added = 0;
1230 TartanPixMaskCacheItem i;
1231 i.player_id = p->getId();
1232 i.width = width;
1233 i.shieldset = shieldset->getId();
1234 i.font_size = font_size;
1235 PixMask *s = tartancache.get(i, added);
1236 d_cachesize += added;
1237 if (added)
1238 checkPictures();
1239 return s;
1240 }
1241
getEmptyTartanPic(const Player * p,guint32 width,Shieldset * shieldset,guint32 font_size)1242 PixMask* ImageCache::getEmptyTartanPic(const Player *p, guint32 width, Shieldset *shieldset, guint32 font_size)
1243 {
1244 guint added = 0;
1245 EmptyTartanPixMaskCacheItem i;
1246 i.player_id = p->getId();
1247 i.width = width;
1248 i.shieldset = shieldset->getId();
1249 i.font_size = font_size;
1250 PixMask *s = emptytartancache.get(i, added);
1251 d_cachesize += added;
1252 if (added)
1253 checkPictures();
1254 return s;
1255 }
1256
getDialogPic(guint32 type,guint32 font_size)1257 PixMask* ImageCache::getDialogPic(guint32 type, guint32 font_size)
1258 {
1259 guint added = 0;
1260 DialogPixMaskCacheItem i;
1261 i.type = type;
1262 i.font_size = font_size;
1263 PixMask *s = dialogcache.get(i, added);
1264 d_cachesize += added;
1265 if (added)
1266 checkPictures();
1267 return s;
1268 }
1269
getDiplomacyImage(int type,Player::DiplomaticState state)1270 PixMask* ImageCache::getDiplomacyImage(int type, Player::DiplomaticState state)
1271 {
1272 return d_diplomacy[type][state];
1273 }
1274
getMoveBonusImage(guint32 type)1275 PixMask* ImageCache::getMoveBonusImage(guint32 type)
1276 {
1277 return d_movebonus[type];
1278 }
1279
getDefaultTileStyleImage(guint32 type)1280 PixMask* ImageCache::getDefaultTileStyleImage(guint32 type)
1281 {
1282 return d_default_tilestyles[type];
1283 }
1284
getCursorImage(int type)1285 PixMask* ImageCache::getCursorImage(int type)
1286 {
1287 return d_cursor[type];
1288 }
1289
getProdShieldImage(guint32 type)1290 PixMask *ImageCache::getProdShieldImage(guint32 type)
1291 {
1292 return d_prodshield[type];
1293 }
1294
getMedalImage(bool large,int type)1295 PixMask* ImageCache::getMedalImage(bool large, int type)
1296 {
1297 if (large)
1298 {
1299 if (ScenarioMedia::getInstance()->getBigMedalsImageName() != "")
1300 return ScenarioMedia::getInstance()->getBigMedalImage(type);
1301 else
1302 return d_medal[1][type];
1303 }
1304 else
1305 {
1306 if (ScenarioMedia::getInstance()->getSmallMedalsImageName() != "")
1307 return ScenarioMedia::getInstance()->getSmallMedalImage(type);
1308 else
1309 return d_medal[0][type];
1310 }
1311 }
1312
getNewLevelImage(bool female,bool mask)1313 PixMask *ImageCache::getNewLevelImage(bool female, bool mask)
1314 {
1315 if (female && mask)
1316 {
1317 if (ScenarioMedia::getInstance()->getHeroNewLevelFemaleMask())
1318 return ScenarioMedia::getInstance()->getHeroNewLevelFemaleMask();
1319 else
1320 return d_newlevelmask_female;
1321 }
1322 else if (female && !mask)
1323 {
1324 if (ScenarioMedia::getInstance()->getHeroNewLevelFemaleImage())
1325 return ScenarioMedia::getInstance()->getHeroNewLevelFemaleImage();
1326 else
1327 return d_newlevel_female;
1328 }
1329
1330 if (!female && mask)
1331 {
1332 if (ScenarioMedia::getInstance()->getHeroNewLevelMaleMask())
1333 return ScenarioMedia::getInstance()->getHeroNewLevelMaleMask();
1334 else
1335 return d_newlevelmask_male;
1336 }
1337 else if (!female && !mask)
1338 {
1339 if (ScenarioMedia::getInstance()->getHeroNewLevelMaleImage())
1340 return ScenarioMedia::getInstance()->getHeroNewLevelMaleImage();
1341 else
1342 return d_newlevel_male;
1343 }
1344 return NULL;
1345 }
1346
getMedalPic(bool large,guint32 type,guint32 font_size)1347 PixMask* ImageCache::getMedalPic(bool large, guint32 type,
1348 guint32 font_size)
1349 {
1350 guint added = 0;
1351 MedalPixMaskCacheItem i;
1352 i.large = large;
1353 i.type = type;
1354 i.font_size = font_size;
1355 PixMask *s = medalcache.get(i, added);
1356 d_cachesize += added;
1357 if (added)
1358 checkPictures();
1359 return s;
1360 }
1361
getGameButtonImage(guint32 type)1362 PixMask* ImageCache::getGameButtonImage(guint32 type)
1363 {
1364 return d_gamebuttons[type];
1365 }
1366
getWaypointImage(guint32 type)1367 PixMask* ImageCache::getWaypointImage(guint32 type)
1368 {
1369 return d_waypoint[type];
1370 }
1371
getSmallRuinedCityImage()1372 PixMask* ImageCache::getSmallRuinedCityImage()
1373 {
1374 return d_smallruinedcity;
1375 }
1376
getSmallBagImage()1377 PixMask* ImageCache::getSmallBagImage()
1378 {
1379 return d_smallbag;
1380 }
1381
getSmallHeroImage(bool active)1382 PixMask* ImageCache::getSmallHeroImage(bool active)
1383 {
1384 if (active)
1385 return d_smallhero;
1386 else
1387 return d_smallinactivehero;
1388 }
1389
getSmallRuinExploredImage()1390 PixMask* ImageCache::getSmallRuinExploredImage()
1391 {
1392 return d_small_ruin_explored;
1393 }
1394
getSmallRuinUnexploredImage()1395 PixMask* ImageCache::getSmallRuinUnexploredImage()
1396 {
1397 return d_small_ruin_unexplored;
1398 }
1399
getSmallStrongholdUnexploredImage()1400 PixMask* ImageCache::getSmallStrongholdUnexploredImage()
1401 {
1402 return d_small_stronghold_unexplored;
1403 }
1404
getSmallTempleImage()1405 PixMask* ImageCache::getSmallTempleImage()
1406 {
1407 return d_small_temple;
1408 }
1409
applyMask(PixMask * image,PixMask * mask,const Player * p)1410 PixMask* ImageCache::applyMask(PixMask* image, PixMask* mask, const Player* p)
1411 {
1412 return applyMask(image, mask, p->getColor());
1413 }
1414
applyMask(PixMask * image,PixMask * mask,Gdk::RGBA colour)1415 PixMask* ImageCache::applyMask(PixMask* image, PixMask* mask, Gdk::RGBA colour)
1416 {
1417 int width = image->get_width();
1418 int height = image->get_height();
1419 PixMask* result = PixMask::create(image->get_pixmap(), mask->get_pixmap());
1420 if (!result)
1421 return NULL;
1422 if (mask->get_width() != width || (mask->get_height()) != height)
1423 {
1424 std::cerr <<"Warning: mask and original image do not match\n";
1425 return NULL;
1426 }
1427 Glib::RefPtr<Gdk::Pixbuf> maskbuf = mask->to_pixbuf();
1428
1429 guint8 *data = maskbuf->get_pixels();
1430 guint8 *copy = (guint8*) malloc (height * width * 4 * sizeof(guint8));
1431 memcpy(copy, data, height * width * 4 * sizeof(guint8));
1432 for (int i = 0; i < width; i++)
1433 for (int j = 0; j < height; j++)
1434 {
1435 const int base = (j * 4) + (i * height * 4);
1436
1437 if (copy[base+3] != 0)
1438 {
1439 copy[base+0] = colour.get_red() *copy[base+0];
1440 copy[base+1] = colour.get_green() * copy[base+1];
1441 copy[base+2] = colour.get_blue() * copy[base+2];
1442 }
1443 }
1444 Glib::RefPtr<Gdk::Pixbuf> colouredmask =
1445 Gdk::Pixbuf::create_from_data(copy, Gdk::COLORSPACE_RGB, true, 8,
1446 width, height, width * 4);
1447 result->draw_pixbuf(colouredmask, 0, 0, 0, 0, width, height);
1448 free(copy);
1449
1450 return result;
1451 }
1452
greyOut(PixMask * image)1453 PixMask* ImageCache::greyOut(PixMask* image)
1454 {
1455 bool broken = false;
1456 int width = image->get_width();
1457 int height = image->get_height();
1458 PixMask* result = PixMask::create(image->to_pixbuf());
1459 if (broken)
1460 return NULL;
1461
1462 guint8 *data = result->to_pixbuf()->get_pixels();
1463 guint8 *copy = (guint8*) malloc (height * width * 4 * sizeof(guint8));
1464 memcpy(copy, data, height * width * 4 * sizeof(guint8));
1465 for (int i = 0; i < width; i++)
1466 for (int j = 0; j < height; j++)
1467 {
1468 const int base = (j * 4) + (i * height * 4);
1469
1470 if (data[base+3] != 0)
1471 {
1472 guint32 max = 0;
1473 if (copy[base+0] > max)
1474 max = copy[base+0];
1475 else if (copy[base+1] > max)
1476 max = copy[base+1];
1477 else if (copy[base+2] > max)
1478 max = copy[base+2];
1479 int x = i % 2;
1480 int y = j % 2;
1481 if ((x == 0 && y == 0) || (x == 1 && y == 1))
1482 max = 88;
1483 copy[base+0] = max;
1484 copy[base+1] = max;
1485 copy[base+2] = max;
1486 }
1487 }
1488 Glib::RefPtr<Gdk::Pixbuf> greyed_out =
1489 Gdk::Pixbuf::create_from_data(copy, Gdk::COLORSPACE_RGB, true, 8,
1490 width, height, width * 4);
1491
1492 result->draw_pixbuf(greyed_out, 0, 0, 0, 0, width, height);
1493 free(copy);
1494
1495 return result;
1496 }
draw_circle(Cairo::RefPtr<Cairo::Context> cr,double width_percent,int width,int height,Gdk::RGBA colour,bool coloured,bool mask)1497 void ImageCache::draw_circle(Cairo::RefPtr<Cairo::Context> cr, double width_percent, int width, int height, Gdk::RGBA colour, bool coloured, bool mask)
1498 {
1499 if (width_percent > 100)
1500 width_percent = 0;
1501 else if (width_percent < 0)
1502 width_percent = 0;
1503 width_percent /= 100.0;
1504 //i want 2 o'clock as a starting point, and 8pm as an ending point.
1505
1506 double dred = BEVELED_CIRCLE_DARK.get_red();
1507 double dgreen = BEVELED_CIRCLE_DARK.get_green();
1508 double dblue = BEVELED_CIRCLE_DARK.get_blue();
1509 double lred = BEVELED_CIRCLE_LIGHT.get_red();
1510 double lgreen = BEVELED_CIRCLE_LIGHT.get_green();
1511 double lblue = BEVELED_CIRCLE_LIGHT.get_blue();
1512
1513 double radius = (double)width * width_percent / 2.0;
1514 double line_width = radius * 0.2;
1515
1516 if (mask)
1517 cr->set_line_width(line_width + 2.0);
1518 else
1519 cr->set_line_width(line_width + 4.0);
1520 cr->set_source_rgb(((lred - dred) / 2.0) + lred,
1521 ((lgreen -dgreen) / 2.0) + lgreen,
1522 ((lblue - dblue) / 2.0) + lblue);
1523 cr->arc((double)width/2.0, (double)height/2.0, radius - (line_width / 2.0), 0, 2 *M_PI);
1524 cr->stroke();
1525 if (mask)
1526 return;
1527
1528 cr->set_line_width(1.0);
1529 cr->set_source_rgb(dred, dgreen, dblue);
1530 cr->arc((double)width/2.0, (double)height/2.0, radius, (2 * M_PI) * (2.0/12.0), (2 *M_PI) * (8.0/12.0));
1531 cr->stroke();
1532 cr->set_source_rgb(lred, lgreen, lblue);
1533 cr->arc((double)width/2.0, (double)height/2.0, radius, (2 * M_PI) * (8.0/12.0), (2 *M_PI) * (2.0/12.0));
1534 cr->stroke();
1535
1536 radius -= line_width;
1537 cr->set_source_rgb(lred, lgreen, lblue);
1538 cr->arc((double)width/2.0, (double)height/2.0, radius, (2 * M_PI) * (2.0/12.0), (2 *M_PI) * (8.0/12.0));
1539 cr->stroke();
1540
1541 cr->set_source_rgb(dred, dgreen, dblue);
1542 cr->arc((double)width/2.0, (double)height/2.0, radius, (2 * M_PI) * (8.0/12.0), (2 *M_PI) * (2.0/12.0));
1543 cr->stroke();
1544
1545 if (coloured)
1546 {
1547 cr->set_line_width(line_width);
1548 double red = colour.get_red();
1549 double green = colour.get_green();
1550 double blue = colour.get_blue();
1551 cr->set_source_rgb(red, green, blue);
1552 cr->arc((double)width/2.0, (double)height/2.0, radius + (line_width / 2.0), 0, 2 *M_PI);
1553 cr->stroke();
1554 }
1555 }
1556
circled(PixMask * image,Gdk::RGBA colour,bool coloured,double width_percent)1557 PixMask* ImageCache::circled(PixMask* image, Gdk::RGBA colour, bool coloured, double width_percent)
1558 {
1559 PixMask *copy = image->copy();
1560 int width = image->get_width();
1561 int height = image->get_height();
1562 //here we draw a coloured circle on top of the army's image
1563 Cairo::RefPtr<Cairo::Context> cr = Cairo::Context::create(copy->get_pixmap());
1564
1565 draw_circle(cr, width_percent, width, height, colour, coloured, false);
1566
1567 //here we draw a white circle on a copy of the image's mask.
1568 Cairo::RefPtr<Cairo::Surface> mask = copy->get_mask();
1569
1570 cr = Cairo::Context::create(mask);
1571 draw_circle(cr, width_percent, width, height, Gdk::RGBA("white"), coloured, true);
1572 PixMask *result = PixMask::create(copy->get_pixmap(), mask);
1573 //draw the army on top again, to make it look like the circle is behind.
1574 result->draw_pixbuf(image->to_pixbuf(), 0, 0, 0, 0, width, height);
1575 delete copy;
1576 return result;
1577 }
1578
getNextTurnPic()1579 PixMask* ImageCache::getNextTurnPic ()
1580 {
1581 PixMask *i = ScenarioMedia::getInstance()->getNextTurnImage();
1582 if (i)
1583 return i;
1584 if (!d_nextturn)
1585 {
1586 bool broken = false;
1587 i = PixMask::create(ScenarioMedia::getDefaultNextTurnImageFilename(),
1588 broken);
1589 if (!broken)
1590 d_nextturn = i;
1591 }
1592 return d_nextturn;
1593 }
1594
getCityDefeatedPic()1595 PixMask* ImageCache::getCityDefeatedPic ()
1596 {
1597 PixMask *i = ScenarioMedia::getInstance()->getCityDefeatedImage();
1598 if (i)
1599 return i;
1600 if (!d_citydefeated)
1601 {
1602 bool broken = false;
1603 i = PixMask::create(ScenarioMedia::getDefaultCityDefeatedImageFilename(),
1604 broken);
1605 if (!broken)
1606 d_citydefeated = i;
1607 }
1608 return d_citydefeated;
1609 }
1610
getWinningPic()1611 PixMask * ImageCache::getWinningPic ()
1612 {
1613 PixMask *i = ScenarioMedia::getInstance()->getWinningImage();
1614 if (i)
1615 return i;
1616 if (!d_winning)
1617 {
1618 bool broken = false;
1619 i = PixMask::create(ScenarioMedia::getDefaultWinningImageFilename(),
1620 broken);
1621 if (!broken)
1622 d_winning = i;
1623 }
1624 return d_winning;
1625 }
1626
getHeroPic(Hero::Gender gender)1627 PixMask * ImageCache::getHeroPic (Hero::Gender gender)
1628 {
1629 switch (gender)
1630 {
1631 case Hero::NONE:
1632 case Hero::MALE:
1633 {
1634 PixMask *i = ScenarioMedia::getInstance()->getMaleHeroImage();
1635 if (i)
1636 return i;
1637 if (!d_malehero)
1638 {
1639 bool broken = false;
1640 i = PixMask::create
1641 (ScenarioMedia::getDefaultMaleHeroImageFilename(), broken);
1642 if (!broken)
1643 d_malehero = i;
1644 }
1645 return d_malehero;
1646 }
1647 break;
1648 case Hero::FEMALE:
1649 {
1650 PixMask *i = ScenarioMedia::getInstance()->getFemaleHeroImage();
1651 if (i)
1652 return i;
1653 if (!d_femalehero)
1654 {
1655 bool broken = false;
1656 i = PixMask::create
1657 (ScenarioMedia::getDefaultFemaleHeroImageFilename(), broken);
1658 if (!broken)
1659 d_femalehero = i;
1660 }
1661 return d_femalehero;
1662 }
1663 break;
1664 }
1665 return NULL;
1666 }
1667
getRuinSuccessPic()1668 PixMask *ImageCache::getRuinSuccessPic()
1669 {
1670 PixMask *i = ScenarioMedia::getInstance()->getRuinSuccessImage();
1671 if (i)
1672 return i;
1673 if (!d_ruinsuccess)
1674 {
1675 bool broken = false;
1676 i = PixMask::create(ScenarioMedia::getDefaultRuinSuccessImageFilename(),
1677 broken);
1678 if (!broken)
1679 d_ruinsuccess = i;
1680 }
1681 return d_ruinsuccess;
1682 }
1683
getRuinDefeatPic()1684 PixMask *ImageCache::getRuinDefeatPic()
1685 {
1686 PixMask *i = ScenarioMedia::getInstance()->getRuinDefeatImage();
1687 if (i)
1688 return i;
1689 if (!d_ruindefeat)
1690 {
1691 bool broken = false;
1692 i = PixMask::create(ScenarioMedia::getDefaultRuinDefeatImageFilename(),
1693 broken);
1694 if (!broken)
1695 d_ruindefeat = i;
1696 }
1697 return d_ruindefeat;
1698 }
1699
getParleyOfferedPic()1700 PixMask* ImageCache::getParleyOfferedPic ()
1701 {
1702 PixMask *i = ScenarioMedia::getInstance()->getParleyOfferedImage();
1703 if (i)
1704 return i;
1705 if (!d_parleyoffered)
1706 {
1707 bool broken = false;
1708 i = PixMask::create(ScenarioMedia::getDefaultParleyOfferedImageFilename(),
1709 broken);
1710 if (!broken)
1711 d_parleyoffered = i;
1712 }
1713 return d_parleyoffered;
1714 }
1715
getParleyRefusedPic()1716 PixMask* ImageCache::getParleyRefusedPic ()
1717 {
1718 PixMask *i = ScenarioMedia::getInstance()->getParleyRefusedImage();
1719 if (i)
1720 return i;
1721 if (!d_parleyrefused)
1722 {
1723 bool broken = false;
1724 i = PixMask::create(ScenarioMedia::getDefaultParleyRefusedImageFilename(),
1725 broken);
1726 if (!broken)
1727 d_parleyrefused = i;
1728 }
1729 return d_parleyrefused;
1730 }
1731
getCommentatorPic()1732 PixMask* ImageCache::getCommentatorPic ()
1733 {
1734 PixMask *i = ScenarioMedia::getInstance()->getCommentatorImage();
1735 if (i)
1736 return i;
1737 if (!d_commentator)
1738 {
1739 bool broken = false;
1740 i = PixMask::create(ScenarioMedia::getDefaultCommentatorImageFilename(),
1741 broken);
1742 if (!broken)
1743 d_commentator = i;
1744 }
1745 return d_commentator;
1746 }
1747
add_underline(PixMask ** p,Gdk::RGBA color,guint32 font_size)1748 void ImageCache::add_underline (PixMask **p, Gdk::RGBA color, guint32 font_size)
1749 {
1750 int height = (*p)->get_height () +
1751 (font_size * TURN_INDICATOR_FONT_SIZE_MULTIPLE);
1752 int width = (*p)->get_width ();
1753 Glib::RefPtr<Gdk::Pixbuf> pixbuf
1754 = Gdk::Pixbuf::create(Gdk::COLORSPACE_RGB, true, 8, width, height);
1755 pixbuf->fill(0x00000000);
1756 PixMask *box = PixMask::create (pixbuf);
1757 (*p)->blit (box->get_pixmap(), 0, 0);
1758 Cairo::RefPtr<Cairo::Context> cr = Cairo::Context::create(box->get_pixmap());
1759 cr->set_line_width(1.0);
1760 cr->set_source_rgba(color.get_red (), color.get_green(), color.get_blue (),
1761 color.get_alpha ());
1762 cr->rectangle(0, (*p)->get_height (), width, height - (*p)->get_height ());
1763 cr->fill ();
1764 //cr->stroke();
1765 delete *p;
1766 *p = box;
1767 }
1768
calculate_width_from_adjusted_height(PixMask * p,double new_height)1769 int ImageCache::calculate_width_from_adjusted_height (PixMask *p, double new_height)
1770 {
1771 return p->get_width () * (new_height / p->get_height ());
1772 }
1773
generate(SelectorPixMaskCacheItem i)1774 PixMask *SelectorPixMaskCacheItem::generate(SelectorPixMaskCacheItem i)
1775 {
1776 Tileset *ts = Tilesetlist::getInstance()->get(i.tileset);
1777 Player *p = Playerlist::getInstance()->getPlayer(i.player_id);
1778 if (i.type == 0)
1779 return ImageCache::applyMask(ts->getSelectorImage(i.frame),
1780 ts->getSelectorMask(i.frame), p);
1781 else
1782 return ImageCache::applyMask(ts->getSmallSelectorImage(i.frame),
1783 ts->getSmallSelectorMask(i.frame), p);
1784 }
1785
comp(const SelectorPixMaskCacheItem item) const1786 int SelectorPixMaskCacheItem::comp(const SelectorPixMaskCacheItem item) const
1787 {
1788 return
1789 (tileset < item.tileset) ? -1 :
1790 (tileset> item.tileset)? 1 :
1791 (type < item.type) ? -1 :
1792 (type > item.type) ? 1 :
1793 (frame < item.frame) ? -1 :
1794 (frame > item.frame) ? 1 :
1795 (player_id < item.player_id) ? -1 :
1796 (player_id > item.player_id) ? 1 :
1797 0;
1798 }
1799
loadSelectorImages(Glib::ustring filename,guint32 size,std::vector<PixMask * > & images,std::vector<PixMask * > & masks,bool scale)1800 bool SelectorPixMaskCacheItem::loadSelectorImages(Glib::ustring filename, guint32 size, std::vector<PixMask* > &images, std::vector<PixMask* > &masks, bool scale)
1801 {
1802 bool broken = false;
1803 PixMask *p = PixMask::create (filename, broken);
1804 if (!broken)
1805 {
1806 broken = loadSelectors(p, size, images, masks, scale);
1807 delete p;
1808 }
1809 return broken;
1810 }
1811
loadSelectors(PixMask * p,guint32 size,std::vector<PixMask * > & images,std::vector<PixMask * > & masks,bool scale)1812 bool SelectorPixMaskCacheItem::loadSelectors(PixMask *p, guint32 size, std::vector<PixMask* > &images, std::vector<PixMask* > &masks, bool scale)
1813 {
1814 bool broken = false;
1815 int num_frames;
1816 guint32 width = p->get_unscaled_width ();
1817 num_frames = width / size;
1818 images = disassemble_row(p->to_pixbuf (), num_frames, true);
1819 if (broken)
1820 return false;
1821 if (scale)
1822 {
1823 for (int i = 0; i < num_frames; i++)
1824 {
1825 if (images[i]->get_width() != (int)size)
1826 PixMask::scale(images[i], size, size);
1827 }
1828 }
1829
1830 masks = disassemble_row(p->to_pixbuf (), num_frames, false);
1831 if (broken)
1832 return false;
1833 if (scale)
1834 {
1835 for (int i = 0; i < num_frames; i++)
1836 {
1837 if (masks[i]->get_width() != (int)size)
1838 PixMask::scale(masks[i], size, size);
1839 }
1840 }
1841
1842 return true;
1843 }
1844
generate(FlagPixMaskCacheItem i)1845 PixMask *FlagPixMaskCacheItem::generate(FlagPixMaskCacheItem i)
1846 {
1847 Tileset *ts = Tilesetlist::getInstance()->get(i.tileset);
1848 Player *p = Playerlist::getInstance()->getPlayer(i.player_id);
1849 // size of stack starts at 1, but we need the index, which starts at 0
1850 return ImageCache::applyMask (ts->getFlagImage(i.size-1),
1851 ts->getFlagMask(i.size-1), p);
1852 }
1853
comp(const FlagPixMaskCacheItem item) const1854 int FlagPixMaskCacheItem::comp(const FlagPixMaskCacheItem item) const
1855 {
1856 return
1857 (tileset < item.tileset) ? -1 :
1858 (tileset > item.tileset)? 1 :
1859 (size < item.size) ? -1 :
1860 (size > item.size) ? 1 :
1861 (player_id < item.player_id) ? -1 :
1862 (player_id > item.player_id) ? 1 :
1863 0;
1864 }
1865
loadFlagImages(Glib::ustring filename,guint32 size,std::vector<PixMask * > & images,std::vector<PixMask * > & masks,bool scale)1866 bool FlagPixMaskCacheItem::loadFlagImages(Glib::ustring filename, guint32 size, std::vector<PixMask* > &images, std::vector<PixMask* > &masks, bool scale)
1867 {
1868 bool broken = false;
1869 PixMask *p = PixMask::create (filename, broken);
1870 if (!broken)
1871 {
1872 broken = loadFlagImages (p, size, images, masks, scale);
1873 delete p;
1874 }
1875 return broken;
1876 }
1877
loadFlagImages(PixMask * p,guint32 size,std::vector<PixMask * > & images,std::vector<PixMask * > & masks,bool scale)1878 bool FlagPixMaskCacheItem::loadFlagImages(PixMask *p, guint32 size,
1879 std::vector<PixMask* > &images,
1880 std::vector<PixMask* > &masks,
1881 bool scale)
1882 {
1883 images = disassemble_row(p->to_pixbuf (), FLAG_TYPES, true);
1884 if (scale)
1885 {
1886 for (unsigned int i = 0; i < FLAG_TYPES; i++)
1887 {
1888 if (images[i]->get_width() != (int)size)
1889 PixMask::scale(images[i], size, size);
1890 }
1891 }
1892
1893 masks = disassemble_row(p->to_pixbuf (), FLAG_TYPES, false);
1894 if (scale)
1895 {
1896 for (unsigned int i = 0; i < FLAG_TYPES; i++)
1897 {
1898 if (masks[i]->get_width() !=(int) size)
1899 PixMask::scale(masks[i], size, size);
1900 }
1901 }
1902 return true;
1903 }
1904
generate(ArmyPixMaskCacheItem i)1905 PixMask *ArmyPixMaskCacheItem::generate(ArmyPixMaskCacheItem i)
1906 {
1907 PixMask *s;
1908 const ArmyProto * basearmy =
1909 Armysetlist::getInstance()->getArmy(i.armyset, i.army_id);
1910
1911 // copy the pixmap including player colors
1912 Player *p = Playerlist::getInstance()->getPlayer(i.player_id);
1913 Shield::Colour c = Shield::Colour(i.player_id);
1914 if (basearmy->getImage(c) == NULL || basearmy->getMask(c) == NULL)
1915 return NULL;
1916 PixMask *coloured = ImageCache::applyMask(basearmy->getImage(c),
1917 basearmy->getMask(c), p);
1918 if (i.greyed)
1919 {
1920 PixMask *greyed_out = ImageCache::greyOut(coloured);
1921 s = greyed_out;
1922 delete coloured;
1923 }
1924 else
1925 s = coloured;
1926
1927 for(int j = 0; j < 3; j++)
1928 {
1929 if (i.medals[j])
1930 ImageCache::getInstance()->getMedalImage(false, j)->blit(s->get_pixmap());
1931 }
1932 if (i.map == false)
1933 {
1934 int dialogsize = i.font_size * DIALOG_ARMY_PIC_FONTSIZE_MULTIPLE;
1935 PixMask::scale (s, dialogsize, dialogsize);
1936 }
1937 return s;
1938 }
1939
comp(const ArmyPixMaskCacheItem item) const1940 int ArmyPixMaskCacheItem::comp(const ArmyPixMaskCacheItem item) const
1941 {
1942 return
1943 (armyset < item.armyset) ? -1 :
1944 (armyset > item.armyset)? 1 :
1945 (army_id < item.army_id) ? -1 :
1946 (army_id > item.army_id) ? 1 :
1947 (player_id < item.player_id) ? -1 :
1948 (player_id > item.player_id) ? 1 :
1949 (memcmp(medals,item.medals,sizeof(medals)) < 0) ? -1 :
1950 (memcmp(medals,item.medals,sizeof(medals)) > 0) ? 1 :
1951 (map < item.map) ? -1 :
1952 (map > item.map) ? 1 :
1953 (font_size < item.font_size) ? -1 :
1954 (font_size > item.font_size) ? 1 :
1955 (greyed < item.greyed) ? -1 :
1956 (greyed > item.greyed) ? 1 :
1957 0;
1958 }
1959
generate(CircledArmyPixMaskCacheItem i)1960 PixMask *CircledArmyPixMaskCacheItem::generate(CircledArmyPixMaskCacheItem i)
1961 {
1962 PixMask *s;
1963 if (i.show_army)
1964 {
1965 Player *p = Playerlist::getInstance()->getPlayer(i.player_id);
1966 PixMask *pre_circle =
1967 ImageCache::getInstance()->getArmyPic(i.armyset, i.army_id, p,
1968 i.medals, false, i.font_size,
1969 i.greyed);
1970 s = ImageCache::circled(pre_circle, p->getColor(),
1971 i.circle_colour_id != Shield::NEUTRAL);
1972 }
1973 else
1974 {
1975 guint32 size = Armysetlist::getInstance()->get(i.armyset)->getTileSize();
1976 Glib::RefPtr<Gdk::Pixbuf> pixbuf
1977 = Gdk::Pixbuf::create(Gdk::COLORSPACE_RGB, true, 8, size, size);
1978 pixbuf->fill(0x00000000);
1979 PixMask *empty = PixMask::create(pixbuf);
1980 s = ImageCache::circled
1981 (empty, Shield::get_default_color_for_no(i.circle_colour_id),
1982 i.circle_colour_id != Shield::NEUTRAL);
1983 delete empty;
1984 }
1985 int dialogsize = i.font_size * DIALOG_ARMY_PIC_FONTSIZE_MULTIPLE;
1986 PixMask::scale (s, dialogsize, dialogsize);
1987 return s;
1988 }
1989
comp(const CircledArmyPixMaskCacheItem item) const1990 int CircledArmyPixMaskCacheItem::comp(const CircledArmyPixMaskCacheItem item) const
1991 {
1992 return
1993 (armyset < item.armyset) ? -1 :
1994 (armyset > item.armyset)? 1 :
1995 (army_id < item.army_id) ? -1 :
1996 (army_id > item.army_id) ? 1 :
1997 (player_id < item.player_id) ? -1 :
1998 (player_id > item.player_id) ? 1 :
1999 (memcmp(medals,item.medals,sizeof(medals)) < 0) ? -1 :
2000 (memcmp(medals,item.medals,sizeof(medals)) > 0) ? 1 :
2001 (greyed < item.greyed) ? -1 :
2002 (greyed > item.greyed) ? 1 :
2003 (circle_colour_id < item.circle_colour_id) ? -1 :
2004 (circle_colour_id > item.circle_colour_id) ? 1 :
2005 (show_army < item.show_army) ? -1 :
2006 (show_army > item.show_army) ? 1 :
2007 (font_size < item.font_size) ? -1 :
2008 (font_size > item.font_size) ? 1 :
2009 0;
2010 }
2011
generate(TilePixMaskCacheItem i)2012 PixMask *TilePixMaskCacheItem::generate(TilePixMaskCacheItem i)
2013 {
2014 PixMask *s;
2015 Tileset *t = Tilesetlist::getInstance()->get(i.tileset);
2016 guint32 uts = t->getUnscaledTileSize();
2017 if (i.fog_type_id == FogMap::ALL)
2018 s = t->getFogImage(i.fog_type_id - 1)->copy();
2019 else
2020 {
2021 TileStyle *tilestyle = t->getTileStyle(i.tile_style_id);
2022 s = tilestyle->getImage()->copy();
2023 const Player *player;
2024 Cairo::RefPtr<Cairo::Surface> pixmap = s->get_pixmap();
2025
2026 switch (i.building_type)
2027 {
2028 case Maptile::CITY:
2029 {
2030 player = Playerlist::getInstance()->getPlayer(i.building_player_id);
2031 ImageCache::getInstance()->getCityPic(i.building_subtype, player, i.cityset)->blit(i.building_tile, uts, pixmap);
2032 }
2033 break;
2034 case Maptile::RUIN:
2035 ImageCache::getInstance()->getRuinPic(i.building_subtype, i.cityset)->blit(i.building_tile, uts, pixmap);
2036 break;
2037 case Maptile::TEMPLE:
2038 ImageCache::getInstance()->getTemplePic(i.building_subtype, i.cityset)->blit(i.building_tile, uts, pixmap);
2039 break;
2040 case Maptile::SIGNPOST:
2041 ImageCache::getInstance()->getSignpostPic(i.cityset)->blit(i.building_tile, uts, pixmap);
2042 break;
2043 case Maptile::ROAD:
2044 ImageCache::getInstance()->getRoadPic(i.building_subtype)->blit(i.building_tile, uts, pixmap);
2045 if (i.stone_type != -1)
2046 {
2047 Tileset *ts = Tilesetlist::getInstance()->get(i.tileset);
2048 PixMask *p = ts->getStoneImage(i.stone_type);
2049 if (p)
2050 p->blit(i.building_tile, uts, pixmap);
2051 }
2052 break;
2053 case Maptile::STONE:
2054 {
2055 Tileset *ts = Tilesetlist::getInstance()->get(i.tileset);
2056 PixMask *p = ts->getStoneImage(i.stone_type);
2057 if (p)
2058 p->blit(i.building_tile, uts, pixmap);
2059 }
2060 break;
2061 case Maptile::PORT:
2062 ImageCache::getInstance()->getPortPic(i.cityset)->blit(i.building_tile, uts, pixmap);
2063 break;
2064 case Maptile::BRIDGE:
2065 ImageCache::getInstance()->getBridgePic(i.building_subtype)->blit(i.building_tile, uts, pixmap);
2066 break;
2067 case Maptile::NONE: default:
2068 break;
2069 }
2070
2071 if (i.has_standard)
2072 {
2073 player = Playerlist::getInstance()->getPlayer(i.standard_player_id) ;
2074 ImageCache::getInstance()->getPlantedStandardPic(player)->blit(pixmap);
2075 }
2076
2077 if (i.has_bag)
2078 {
2079 PixMask *pic = ImageCache::getInstance()->getBagPic();
2080 Vector<int>bagsize = Vector<int>(pic->get_width(), pic->get_height());
2081 pic->blit(pixmap, Vector<int>(uts,uts)-bagsize);
2082 }
2083
2084 if (i.stack_player_id > -1)
2085 {
2086 player = Playerlist::getInstance()->getPlayer(i.stack_player_id);
2087 if (i.has_tower)
2088 ImageCache::getInstance()->getTowerPic(player)->blit(pixmap);
2089 else
2090 {
2091 if (i.stack_size > -1)
2092 ImageCache::getInstance()->getFlagPic(i.stack_size, player)->blit(pixmap);
2093 if (i.has_ship)
2094 ImageCache::getInstance()->getShipPic(player)->blit(pixmap);
2095 else
2096 ImageCache::getInstance()->getArmyPic(player->getArmyset(), i.army_type_id, player, NULL, true, 0)->blit(pixmap);
2097 }
2098 }
2099 if (i.has_grid)
2100 {
2101 Cairo::RefPtr<Cairo::Context> context = s->get_gc();
2102 context->set_source_rgba(GRID_BOX_COLOUR.get_red(), GRID_BOX_COLOUR.get_blue(), GRID_BOX_COLOUR.get_green(), GRID_BOX_COLOUR.get_alpha());
2103 context->move_to(0, 0);
2104 context->rel_line_to(uts, 0);
2105 context->rel_line_to(0, uts);
2106 context->rel_line_to(-uts, 0);
2107 context->rel_line_to(0, -uts);
2108 context->set_line_width(1.0);
2109 context->stroke();
2110 }
2111
2112 if (i.fog_type_id)
2113 t->getFogImage(i.fog_type_id - 1)->blit(pixmap);
2114 }
2115 int ts = t->getTileSize();
2116 if (s->get_width () != ts)
2117 s->scale (s, ts, ts);
2118 return s;
2119 }
2120
comp(const TilePixMaskCacheItem item) const2121 int TilePixMaskCacheItem::comp(const TilePixMaskCacheItem item) const
2122 {
2123 return
2124 (tile_style_id < item.tile_style_id) ? -1 :
2125 (tile_style_id > item.tile_style_id) ? 1 :
2126 (fog_type_id < item.fog_type_id) ? -1 :
2127 (fog_type_id > item.fog_type_id) ? 1 :
2128 (has_bag < item.has_bag) ? -1 :
2129 (has_bag > item.has_bag) ? 1 :
2130 (has_standard < item.has_standard) ? -1 :
2131 (has_standard > item.has_standard) ? 1 :
2132 (standard_player_id < item.standard_player_id) ? -1 :
2133 (standard_player_id > item.standard_player_id) ? 1 :
2134 (stack_size < item.stack_size) ? -1 :
2135 (stack_size > item.stack_size) ? 1 :
2136 (stack_player_id < item.stack_player_id) ? -1 :
2137 (stack_player_id > item.stack_player_id) ? 1 :
2138 (army_type_id < item.army_type_id) ? -1 :
2139 (army_type_id > item.army_type_id) ? 1 :
2140 (has_tower < item.has_tower) ? -1 :
2141 (has_tower > item.has_tower) ? 1 :
2142 (has_ship < item.has_ship) ? -1 :
2143 (has_ship > item.has_ship) ? 1 :
2144 (building_type < item.building_type) ? -1 :
2145 (building_type > item.building_type) ? 1 :
2146 (building_subtype < item.building_subtype) ? -1 :
2147 (building_subtype > item.building_subtype) ? 1 :
2148 (building_tile < item.building_tile) ? -1 :
2149 (building_tile > item.building_tile) ? 1 :
2150 (building_player_id < item.building_player_id) ? -1 :
2151 (building_player_id > item.building_player_id) ? 1 :
2152 (tilesize < item.tilesize) ? -1 :
2153 (tilesize > item.tilesize) ? 1 :
2154 (has_grid < item.has_grid) ? -1 :
2155 (has_grid > item.has_grid) ? 1 :
2156 (tileset < item.tileset) ? -1 :
2157 (tileset > item.tileset) ? 1 :
2158 (cityset < item.cityset) ? -1 :
2159 (cityset > item.cityset) ? 1 :
2160 (shieldset < item.shieldset) ? -1 :
2161 (shieldset > item.shieldset) ? 1 :
2162 (stone_type < item.stone_type) ? -1 :
2163 (stone_type > item.stone_type) ? 1 :
2164 0;
2165 }
2166
generate(CityPixMaskCacheItem i)2167 PixMask *CityPixMaskCacheItem::generate(CityPixMaskCacheItem i)
2168 {
2169 Cityset *cs = Citysetlist::getInstance()->get(i.cityset);
2170 Player *p = Playerlist::getInstance()->getPlayer(i.player_id);
2171 if (i.type == -1)
2172 return cs->getRazedCityImage(p->getId())->copy();
2173 else
2174 return cs->getCityImage(p->getId())->copy();
2175 }
2176
comp(const CityPixMaskCacheItem item) const2177 int CityPixMaskCacheItem::comp(const CityPixMaskCacheItem item) const
2178 {
2179 return
2180 (cityset < item.cityset) ? -1 :
2181 (cityset > item.cityset)? 1 :
2182 (type < item.type) ? -1 :
2183 (type > item.type) ? 1 :
2184 (player_id < item.player_id) ? -1 :
2185 (player_id > item.player_id) ? 1 :
2186 0;
2187 }
2188
generate(TowerPixMaskCacheItem i)2189 PixMask *TowerPixMaskCacheItem::generate(TowerPixMaskCacheItem i)
2190 {
2191 Cityset *cs = Citysetlist::getInstance()->get(i.cityset);
2192 return cs->getTowerImage(i.player_id)->copy();
2193 }
2194
comp(const TowerPixMaskCacheItem item) const2195 int TowerPixMaskCacheItem::comp(const TowerPixMaskCacheItem item) const
2196 {
2197 return
2198 (cityset < item.cityset) ? -1 :
2199 (cityset > item.cityset)? 1 :
2200 (player_id < item.player_id) ? -1 :
2201 (player_id > item.player_id) ? 1 :
2202 0;
2203 }
2204
generate(TemplePixMaskCacheItem i)2205 PixMask *TemplePixMaskCacheItem::generate(TemplePixMaskCacheItem i)
2206 {
2207 Cityset *cs = Citysetlist::getInstance()->get(i.cityset);
2208 return cs->getTempleImage(i.type)->copy();
2209 }
2210
comp(const TemplePixMaskCacheItem item) const2211 int TemplePixMaskCacheItem::comp(const TemplePixMaskCacheItem item) const
2212 {
2213 return
2214 (cityset < item.cityset) ? -1 :
2215 (cityset > item.cityset)? 1 :
2216 (type < item.type) ? -1 :
2217 (type > item.type) ? 1 :
2218 0;
2219 }
2220
generate(RuinPixMaskCacheItem i)2221 PixMask *RuinPixMaskCacheItem::generate(RuinPixMaskCacheItem i)
2222 {
2223 Cityset *cs = Citysetlist::getInstance()->get(i.cityset);
2224 return cs->getRuinImage(i.type)->copy();
2225 }
2226
comp(const RuinPixMaskCacheItem item) const2227 int RuinPixMaskCacheItem::comp(const RuinPixMaskCacheItem item) const
2228 {
2229 return
2230 (cityset < item.cityset) ? -1 :
2231 (cityset > item.cityset)? 1 :
2232 (type < item.type) ? -1 :
2233 (type > item.type) ? 1 :
2234 0;
2235 }
2236
generate(DiplomacyPixMaskCacheItem i)2237 PixMask *DiplomacyPixMaskCacheItem::generate(DiplomacyPixMaskCacheItem i)
2238 {
2239 PixMask *p =
2240 ImageCache::getInstance()->getDiplomacyImage
2241 (i.type, Player::DiplomaticState(i.state - Player::AT_PEACE))->copy();
2242 double ratio = 1;
2243 switch (i.type)
2244 {
2245 case 0:
2246 ratio = DIALOG_DIPLOMACY_TYPE_0_PIC_FONTSIZE_MULTIPLE;
2247 break;
2248 case 1:
2249 ratio = DIALOG_DIPLOMACY_TYPE_1_PIC_FONTSIZE_MULTIPLE;
2250 break;
2251 }
2252
2253 double new_height = i.font_size * ratio;
2254 int new_width =
2255 ImageCache::calculate_width_from_adjusted_height (p, new_height);
2256 PixMask::scale (p, new_width, new_height);
2257 return p;
2258 }
2259
comp(const DiplomacyPixMaskCacheItem item) const2260 int DiplomacyPixMaskCacheItem::comp(const DiplomacyPixMaskCacheItem item) const
2261 {
2262 return
2263 (type < item.type) ? -1 :
2264 (type > item.type) ? 1 :
2265 (state < item.state) ? -1 :
2266 (state > item.state) ? 1 :
2267 (font_size < item.font_size) ? -1 :
2268 (font_size > item.font_size) ? 1 :
2269 0;
2270 }
2271
generate(RoadPixMaskCacheItem i)2272 PixMask *RoadPixMaskCacheItem::generate(RoadPixMaskCacheItem i)
2273 {
2274 Tileset *ts = Tilesetlist::getInstance()->get(i.tileset);
2275 return ts->getRoadImage(i.type)->copy();
2276 }
2277
comp(const RoadPixMaskCacheItem item) const2278 int RoadPixMaskCacheItem::comp(const RoadPixMaskCacheItem item) const
2279 {
2280 return
2281 (tileset < item.tileset) ? -1 :
2282 (tileset > item.tileset)? 1 :
2283 (type < item.type) ? -1 :
2284 (type > item.type) ? 1 :
2285 0;
2286 }
2287
generate(FogPixMaskCacheItem i)2288 PixMask *FogPixMaskCacheItem::generate(FogPixMaskCacheItem i)
2289 {
2290 Tileset *ts = Tilesetlist::getInstance()->get(i.tileset);
2291 return ts->getFogImage(i.type - 1)->copy();
2292 }
2293
comp(const FogPixMaskCacheItem item) const2294 int FogPixMaskCacheItem::comp(const FogPixMaskCacheItem item) const
2295 {
2296 return
2297 (tileset < item.tileset) ? -1 :
2298 (tileset > item.tileset)? 1 :
2299 (type < item.type) ? -1 :
2300 (type > item.type) ? 1 :
2301 0;
2302 }
2303
generate(BridgePixMaskCacheItem i)2304 PixMask *BridgePixMaskCacheItem::generate(BridgePixMaskCacheItem i)
2305 {
2306 Tileset *ts = Tilesetlist::getInstance()->get(i.tileset);
2307 return ts->getBridgeImage(i.type)->copy();
2308 }
2309
comp(const BridgePixMaskCacheItem item) const2310 int BridgePixMaskCacheItem::comp(const BridgePixMaskCacheItem item) const
2311 {
2312 return
2313 (tileset < item.tileset) ? -1 :
2314 (tileset > item.tileset)? 1 :
2315 (type < item.type) ? -1 :
2316 (type > item.type) ? 1 :
2317 0;
2318 }
2319
generate(CursorPixMaskCacheItem i)2320 PixMask *CursorPixMaskCacheItem::generate(CursorPixMaskCacheItem i)
2321 {
2322 PixMask *p =
2323 ImageCache::getInstance()->getCursorImage(i.type)->copy();
2324 double ratio = DIALOG_CURSOR_PIC_FONTSIZE_MULTIPLE;
2325 double new_height = i.font_size * ratio;
2326 int new_width =
2327 ImageCache::calculate_width_from_adjusted_height (p, new_height);
2328 PixMask::scale (p, new_width, new_height);
2329 return p;
2330 }
2331
comp(const CursorPixMaskCacheItem item) const2332 int CursorPixMaskCacheItem::comp(const CursorPixMaskCacheItem item) const
2333 {
2334 return
2335 (type < item.type) ? -1 :
2336 (type > item.type) ? 1 :
2337 (font_size < item.font_size) ? -1 :
2338 (font_size > item.font_size) ? 1 :
2339 0;
2340 }
2341
generate(ShieldPixMaskCacheItem i)2342 PixMask *ShieldPixMaskCacheItem::generate(ShieldPixMaskCacheItem i)
2343 {
2344 ShieldStyle *sh = Shieldsetlist::getInstance()->getShield(i.shieldset,
2345 i.type, i.colour);
2346 Gdk::RGBA colour =
2347 Shieldsetlist::getInstance()->getColor(i.shieldset, i.colour);
2348 PixMask *p = ImageCache::applyMask(sh->getImage(), sh->getMask(), colour);
2349 if (i.map)
2350 return p;
2351 //okay now we size things accordingly.
2352 double height_ratio = 1.0;
2353 switch (i.type)
2354 {
2355 case 0:
2356 height_ratio = DIALOG_SMALL_SHIELD_PIC_FONTSIZE_MULTIPLE;
2357 break;
2358 case 1:
2359 height_ratio = DIALOG_MEDIUM_SHIELD_PIC_FONTSIZE_MULTIPLE;
2360 break;
2361 case 2:
2362 height_ratio = DIALOG_LARGE_SHIELD_PIC_FONTSIZE_MULTIPLE;
2363 break;
2364 }
2365 int new_height = i.font_size * height_ratio;
2366 int new_width =
2367 ImageCache::calculate_width_from_adjusted_height (p, new_height);
2368 PixMask::scale (p, new_width, new_height);
2369 return p;
2370 }
2371
comp(const ShieldPixMaskCacheItem item) const2372 int ShieldPixMaskCacheItem::comp(const ShieldPixMaskCacheItem item) const
2373 {
2374 return
2375 (shieldset < item.shieldset) ? -1 :
2376 (shieldset > item.shieldset) ? 1 :
2377 (type < item.type) ? -1 :
2378 (type > item.type) ? 1 :
2379 (colour < item.colour) ? -1 :
2380 (colour > item.colour) ? 1 :
2381 (font_size < item.font_size) ? -1 :
2382 (font_size > item.font_size) ? 1 :
2383 0;
2384 }
2385
generate(ProdShieldPixMaskCacheItem i)2386 PixMask *ProdShieldPixMaskCacheItem::generate(ProdShieldPixMaskCacheItem i)
2387 {
2388 switch (i.type)
2389 {
2390 case 0: //home city
2391 if (i.prod) //production
2392 return ImageCache::getInstance()->getProdShieldImage(1)->copy();
2393 else //no production
2394 return ImageCache::getInstance()->getProdShieldImage(0)->copy();
2395 break;
2396 case 1: //away city
2397 if (i.prod) //production
2398 return ImageCache::getInstance()->getProdShieldImage(3)->copy();
2399 else //no production
2400 return ImageCache::getInstance()->getProdShieldImage(2)->copy();
2401 break;
2402 case 2: //destination city
2403 if (i.prod) //production
2404 return ImageCache::getInstance()->getProdShieldImage(5)->copy();
2405 else //no production
2406 return ImageCache::getInstance()->getProdShieldImage(4)->copy();
2407 break;
2408 case 3: //source city
2409 return ImageCache::getInstance()->getProdShieldImage(6)->copy();
2410 break;
2411 case 4: //invalid
2412 return ImageCache::getInstance()->getProdShieldImage(7)->copy();
2413 break;
2414 }
2415 return NULL;
2416 }
2417
comp(const ProdShieldPixMaskCacheItem item) const2418 int ProdShieldPixMaskCacheItem::comp(const ProdShieldPixMaskCacheItem item) const
2419 {
2420 return
2421 (type < item.type) ? -1 :
2422 (type > item.type) ? 1 :
2423 (prod < item.prod) ? -1 :
2424 (prod > item.prod) ? 1 :
2425 0;
2426 }
2427
generate(MoveBonusPixMaskCacheItem i)2428 PixMask *MoveBonusPixMaskCacheItem::generate(MoveBonusPixMaskCacheItem i)
2429 {
2430 PixMask *p = ImageCache::getInstance()->getMoveBonusImage(i.type)->copy();
2431 double ratio = DIALOG_MOVE_BONUS_PIC_FONTSIZE_MULTIPLE;
2432 double new_height = i.font_size * ratio;
2433 int new_width =
2434 ImageCache::calculate_width_from_adjusted_height (p, new_height);
2435 PixMask::scale (p, new_width, new_height);
2436 return p;
2437 }
2438
comp(const MoveBonusPixMaskCacheItem item) const2439 int MoveBonusPixMaskCacheItem::comp(const MoveBonusPixMaskCacheItem item) const
2440 {
2441 return
2442 (type < item.type) ? -1 :
2443 (type > item.type) ? 1 :
2444 (font_size < item.font_size) ? -1 :
2445 (font_size > item.font_size) ? 1 :
2446 0;
2447 }
2448
generate(ShipPixMaskCacheItem i)2449 PixMask *ShipPixMaskCacheItem::generate(ShipPixMaskCacheItem i)
2450 {
2451 // copy the pixmap including player colors
2452 return ImageCache::applyMask
2453 (Armysetlist::getInstance()->getShipPic(i.armyset),
2454 Armysetlist::getInstance()->getShipMask(i.armyset),
2455 Playerlist::getInstance()->getPlayer(i.player_id));
2456 }
2457
comp(const ShipPixMaskCacheItem item) const2458 int ShipPixMaskCacheItem::comp(const ShipPixMaskCacheItem item) const
2459 {
2460 return
2461 (player_id < item.player_id) ? -1 :
2462 (player_id > item.player_id) ? 1 :
2463 (armyset < item.armyset) ? -1 :
2464 (armyset > item.armyset) ? 1 :
2465 0;
2466 }
2467
generate(PlantedStandardPixMaskCacheItem i)2468 PixMask *PlantedStandardPixMaskCacheItem::generate(PlantedStandardPixMaskCacheItem i)
2469 {
2470 // copy the pixmap including player colors
2471 return ImageCache::applyMask
2472 (Armysetlist::getInstance()->getStandardPic(i.armyset),
2473 Armysetlist::getInstance()->getStandardMask(i.armyset),
2474 Playerlist::getInstance()->getPlayer(i.player_id));
2475 }
2476
comp(const PlantedStandardPixMaskCacheItem item) const2477 int PlantedStandardPixMaskCacheItem::comp(const PlantedStandardPixMaskCacheItem item) const
2478 {
2479 return
2480 (player_id < item.player_id) ? -1 :
2481 (player_id > item.player_id) ? 1 :
2482 (armyset < item.armyset) ? -1 :
2483 (armyset > item.armyset) ? 1 :
2484 0;
2485 }
2486
generate(PortPixMaskCacheItem i)2487 PixMask *PortPixMaskCacheItem::generate(PortPixMaskCacheItem i)
2488 {
2489 return Citysetlist::getInstance()->get(i.cityset)->getPortImage()->copy();
2490 }
2491
comp(const PortPixMaskCacheItem item) const2492 int PortPixMaskCacheItem::comp(const PortPixMaskCacheItem item) const
2493 {
2494 return
2495 (cityset < item.cityset) ? -1 :
2496 (cityset > item.cityset) ? 1 :
2497 0;
2498 }
2499
generate(SignpostPixMaskCacheItem i)2500 PixMask *SignpostPixMaskCacheItem::generate(SignpostPixMaskCacheItem i)
2501 {
2502 return Citysetlist::getInstance()->get(i.cityset)->getSignpostImage()->copy();
2503 }
2504
comp(const SignpostPixMaskCacheItem item) const2505 int SignpostPixMaskCacheItem::comp(const SignpostPixMaskCacheItem item) const
2506 {
2507 return
2508 (cityset < item.cityset) ? -1 :
2509 (cityset > item.cityset) ? 1 :
2510 0;
2511 }
2512
generate(BagPixMaskCacheItem i)2513 PixMask *BagPixMaskCacheItem::generate(BagPixMaskCacheItem i)
2514 {
2515 return Armysetlist::getInstance()->getBagPic(i.armyset)->copy();
2516 }
2517
comp(const BagPixMaskCacheItem item) const2518 int BagPixMaskCacheItem::comp(const BagPixMaskCacheItem item) const
2519 {
2520 return
2521 (armyset < item.armyset) ? -1 :
2522 (armyset > item.armyset) ? 1 :
2523 0;
2524 }
2525
generate(ExplosionPixMaskCacheItem i)2526 PixMask *ExplosionPixMaskCacheItem::generate(ExplosionPixMaskCacheItem i)
2527 {
2528 return Tilesetlist::getInstance()->get(i.tileset)->getExplosionImage()->copy();
2529 }
2530
comp(const ExplosionPixMaskCacheItem item) const2531 int ExplosionPixMaskCacheItem::comp(const ExplosionPixMaskCacheItem item) const
2532 {
2533 return
2534 (tileset < item.tileset) ? -1 :
2535 (tileset > item.tileset) ? 1 :
2536 0;
2537 }
2538
generate(NewLevelPixMaskCacheItem i)2539 PixMask *NewLevelPixMaskCacheItem::generate(NewLevelPixMaskCacheItem i)
2540 {
2541 bool female = i.gender == Hero::FEMALE;
2542 PixMask *p = ImageCache::applyMask
2543 (ImageCache::getInstance()->getNewLevelImage(female, false),
2544 ImageCache::getInstance()->getNewLevelImage(female, true),
2545 Playerlist::getInstance()->getPlayer(i.player_id));
2546
2547 double ratio = DIALOG_NEW_LEVEL_PIC_FONTSIZE_MULTIPLE;
2548 double new_height = i.font_size * ratio;
2549 int new_width =
2550 ImageCache::calculate_width_from_adjusted_height (p, new_height);
2551 PixMask::scale (p, new_width, new_height);
2552 return p;
2553 }
2554
comp(const NewLevelPixMaskCacheItem item) const2555 int NewLevelPixMaskCacheItem::comp(const NewLevelPixMaskCacheItem item) const
2556 {
2557 return
2558 (player_id < item.player_id) ? -1 :
2559 (player_id > item.player_id) ? 1 :
2560 (gender < item.gender) ? -1 :
2561 (gender > item.gender) ? 1 :
2562 (font_size < item.font_size) ? -1 :
2563 (font_size > item.font_size) ? 1 :
2564 0;
2565 }
2566
generate(DefaultTileStylePixMaskCacheItem i)2567 PixMask *DefaultTileStylePixMaskCacheItem::generate(DefaultTileStylePixMaskCacheItem i)
2568 {
2569 PixMask *t =
2570 ImageCache::getInstance()->getDefaultTileStyleImage(i.tilestyle_type);
2571 PixMask *s = t->copy();
2572 PixMask::scale(s, i.tilesize, i.tilesize);
2573 return s;
2574 }
2575
comp(const DefaultTileStylePixMaskCacheItem item) const2576 int DefaultTileStylePixMaskCacheItem::comp(const DefaultTileStylePixMaskCacheItem item) const
2577 {
2578 return
2579 (tilestyle_type < item.tilestyle_type) ? -1 :
2580 (tilestyle_type > item.tilestyle_type) ? 1 :
2581 (tilesize < item.tilesize) ? -1 :
2582 (tilesize > item.tilesize) ? 1 :
2583 0;
2584 }
2585
calculateWidth(guint32 iwidth,PixMask * left,PixMask * center,PixMask * right,guint32 & width,guint32 & centers,bool & include_right)2586 void TartanPixMaskCacheItem::calculateWidth(guint32 iwidth, PixMask *left, PixMask *center, PixMask *right, guint32 &width, guint32 ¢ers, bool &include_right)
2587 {
2588 //calculate the width, ugh.
2589 for (width = left->get_width(); width < iwidth - right->get_width();
2590 width += center->get_width())
2591 centers++;
2592 width += right->get_width();
2593 include_right = true;
2594 for (guint32 j = 0; j < centers; j++)
2595 {
2596 if (width > iwidth)
2597 {
2598 width -= center->get_width();
2599 if (centers)
2600 centers--;
2601 }
2602 else
2603 break;
2604 }
2605 if (width > iwidth)
2606 {
2607 width -= right->get_width();
2608 include_right = false;
2609 }
2610 }
2611
generate(TartanPixMaskCacheItem i)2612 PixMask *TartanPixMaskCacheItem::generate(TartanPixMaskCacheItem i)
2613 {
2614 //okay, here's where we fashion the new image.
2615 //we take the leftmost tartan image for this player
2616 //and then we repeat the center tartan image a bunch of times
2617 //and then finally we cap it off with the rightmost tartan image
2618 //the images are all masked in the player's colour.
2619
2620 Gdk::RGBA colour =
2621 Shieldsetlist::getInstance()->getColor(i.shieldset, i.player_id);
2622 PixMask *image = NULL, *mask = NULL;
2623 Shieldsetlist::getInstance()->getTartan(i.shieldset, i.player_id,
2624 Tartan::LEFT, &image, &mask);
2625 PixMask *left = ImageCache::applyMask(image, mask, colour);
2626 double ratio = DIALOG_TARTAN_PIC_FONTSIZE_MULTIPLE;
2627 double new_height = i.font_size * ratio;
2628 int new_width =
2629 ImageCache::calculate_width_from_adjusted_height (left, new_height);
2630 PixMask::scale (left, new_width, new_height);
2631
2632 image = NULL;
2633 mask = NULL;
2634 Shieldsetlist::getInstance()->getTartan(i.shieldset, i.player_id,
2635 Tartan::CENTER, &image, &mask);
2636 PixMask *center = ImageCache::applyMask(image, mask, colour);
2637 new_width =
2638 ImageCache::calculate_width_from_adjusted_height (center, new_height);
2639 PixMask::scale (center, new_width, new_height);
2640 image = NULL;
2641 mask = NULL;
2642 Shieldsetlist::getInstance()->getTartan(i.shieldset, i.player_id,
2643 Tartan::RIGHT, &image, &mask);
2644 PixMask *right = ImageCache::applyMask(image, mask, colour);
2645 new_width =
2646 ImageCache::calculate_width_from_adjusted_height (right, new_height);
2647 PixMask::scale (right, new_width, new_height);
2648 //okay, so we have our left, right and center images, now we need to
2649 //concatenate them together
2650
2651 guint32 w = 0, num_centers = 0;
2652 bool include_right = false;
2653 calculateWidth(i.width, left, center, right, w, num_centers, include_right);
2654 //okay w is the actual width of the image, which is the same or less than
2655 //the width we asked for. it has NUM_CENTERS center pieces and it may or may
2656 //not have an ending piece (if we can fit it.)
2657 //we always have the leftmost piece though because we have to show something.
2658 Glib::RefPtr<Gdk::Pixbuf> pixbuf
2659 = Gdk::Pixbuf::create(Gdk::COLORSPACE_RGB, true, 8, w, left->get_height());
2660 pixbuf->fill(0x00000000);
2661 PixMask *tartan = PixMask::create(pixbuf);
2662
2663 //blit the left image
2664 guint32 l = 0;
2665 left->blit (tartan->get_pixmap(), l, 0);
2666 l += left->get_width();
2667
2668 //blit the center images
2669 for (guint32 j = 0; j < num_centers; j++)
2670 {
2671 center->blit (tartan->get_pixmap(), l, 0);
2672 l += center->get_width();
2673 }
2674
2675 //blit the right image
2676 if (include_right)
2677 right->blit (tartan->get_pixmap(), l, 0);
2678 delete left;
2679 delete center;
2680 delete right;
2681 return tartan;
2682 }
2683
comp(const TartanPixMaskCacheItem item) const2684 int TartanPixMaskCacheItem::comp(const TartanPixMaskCacheItem item) const
2685 {
2686 return
2687 (player_id < item.player_id) ? -1 :
2688 (player_id > item.player_id) ? 1 :
2689 (width < item.width) ? -1 :
2690 (width > item.width) ? 1 :
2691 (shieldset < item.shieldset) ? -1 :
2692 (shieldset > item.shieldset) ? 1 :
2693 (font_size < item.font_size) ? -1 :
2694 (font_size > item.font_size) ? 1 :
2695 0;
2696 }
2697
generate(EmptyTartanPixMaskCacheItem i)2698 PixMask *EmptyTartanPixMaskCacheItem::generate(EmptyTartanPixMaskCacheItem i)
2699 {
2700 //okay, here's where we fashion the new image.
2701 //we take the leftmost tartan image for this player
2702 //and then we repeat the center tartan image a bunch of times
2703 //and then finally we cap it off with the rightmost tartan image
2704 //the images are all masked in the player's colour.
2705
2706 //the empty tartan pictures are the same as the regular tartan pictures
2707 //except they're not coloured in the player's colour.
2708
2709 PixMask *image = NULL, *mask = NULL;
2710 Shieldsetlist::getInstance()->getTartan(i.shieldset, i.player_id,
2711 Tartan::LEFT, &image, &mask);
2712 PixMask *left = image->copy();
2713 double ratio = DIALOG_TARTAN_PIC_FONTSIZE_MULTIPLE;
2714 double new_height = i.font_size * ratio;
2715 int new_width =
2716 ImageCache::calculate_width_from_adjusted_height (left, new_height);
2717 PixMask::scale (left, new_width, new_height);
2718
2719 image = NULL;
2720 mask = NULL;
2721 Shieldsetlist::getInstance()->getTartan(i.shieldset, i.player_id,
2722 Tartan::CENTER, &image, &mask);
2723 PixMask *center = image->copy();
2724 new_width =
2725 ImageCache::calculate_width_from_adjusted_height (center, new_height);
2726 PixMask::scale (center, new_width, new_height);
2727
2728 image = NULL;
2729 mask = NULL;
2730 Shieldsetlist::getInstance()->getTartan(i.shieldset, i.player_id,
2731 Tartan::RIGHT, &image, &mask);
2732 PixMask *right = image->copy();
2733 new_width =
2734 ImageCache::calculate_width_from_adjusted_height (right, new_height);
2735 PixMask::scale (right, new_width, new_height);
2736
2737 //okay, so we have our left, right and center images, now we need to
2738 //concatenate them together
2739
2740 guint32 w = 0, num_centers = 0;
2741 bool include_right = false;
2742 TartanPixMaskCacheItem::calculateWidth(i.width, left, center, right, w, num_centers, include_right);
2743 //okay w is the actual width of the image, which is the same or less than
2744 //the width we asked for. it has NUM_CENTERS center pieces and it may or may
2745 //not have an ending piece (if we can fit it.)
2746 //we always have the leftmost piece though because we have to show something.
2747 Glib::RefPtr<Gdk::Pixbuf> pixbuf
2748 = Gdk::Pixbuf::create(Gdk::COLORSPACE_RGB, true, 8, w, left->get_height());
2749 pixbuf->fill(0x00000000);
2750 PixMask *tartan = PixMask::create(pixbuf);
2751
2752 //blit the left image
2753 guint32 l = 0;
2754 left->blit (tartan->get_pixmap(), l, 0);
2755 l += left->get_width();
2756
2757 //blit the center images
2758 for (guint32 j = 0; j < num_centers; j++)
2759 {
2760 center->blit (tartan->get_pixmap(), l, 0);
2761 l += center->get_width();
2762 }
2763
2764 //blit the right image
2765 if (include_right)
2766 right->blit (tartan->get_pixmap(), l, 0);
2767 delete left;
2768 delete center;
2769 delete right;
2770 return tartan;
2771 }
2772
comp(const EmptyTartanPixMaskCacheItem item) const2773 int EmptyTartanPixMaskCacheItem::comp(const EmptyTartanPixMaskCacheItem item) const
2774 {
2775 return
2776 (player_id < item.player_id) ? -1 :
2777 (player_id > item.player_id) ? 1 :
2778 (width < item.width) ? -1 :
2779 (width > item.width) ? 1 :
2780 (shieldset < item.shieldset) ? -1 :
2781 (shieldset > item.shieldset) ? 1 :
2782 (font_size < item.font_size) ? -1 :
2783 (font_size > item.font_size) ? 1 :
2784 0;
2785 }
2786
generate(StatusPixMaskCacheItem i)2787 PixMask *StatusPixMaskCacheItem::generate(StatusPixMaskCacheItem i)
2788 {
2789 Glib::ustring file = "";
2790 switch (i.type)
2791 {
2792 case ImageCache::STATUS_CITY:
2793 file = File::getVariousFile ("smallcity.png");
2794 break;
2795 case ImageCache::STATUS_TREASURY:
2796 file = File::getVariousFile ("smalltreasury.png");
2797 break;
2798 case ImageCache::STATUS_INCOME:
2799 file = File::getVariousFile ("smallincome.png");
2800 break;
2801 case ImageCache::STATUS_UPKEEP:
2802 file = File::getVariousFile ("smallupkeep.png");
2803 break;
2804 case ImageCache::STATUS_DEFENSE:
2805 file = File::getVariousFile ("smalldefense.png");
2806 break;
2807 }
2808
2809 bool broken = false;
2810 PixMask *p = PixMask::create (file, broken);
2811 if (!broken)
2812 {
2813 double ratio = DIALOG_STATUS_PIC_FONTSIZE_MULTIPLE;
2814 if (i.type == ImageCache::STATUS_DEFENSE)
2815 ratio = DIALOG_DEFENSE_PIC_FONTSIZE_MULTIPLE;
2816 double new_height = i.font_size * ratio;
2817 int new_width =
2818 ImageCache::calculate_width_from_adjusted_height (p, new_height);
2819 PixMask::scale (p, new_width, new_height);
2820 }
2821 return p;
2822 }
2823
comp(const StatusPixMaskCacheItem item) const2824 int StatusPixMaskCacheItem::comp(const StatusPixMaskCacheItem item) const
2825 {
2826 return
2827 (type < item.type) ? -1 :
2828 (type > item.type) ? 1 :
2829 (font_size < item.font_size) ? -1 :
2830 (font_size > item.font_size) ? 1 :
2831 0;
2832 }
2833
generate(GameButtonPixMaskCacheItem i)2834 PixMask *GameButtonPixMaskCacheItem::generate(GameButtonPixMaskCacheItem i)
2835 {
2836 PixMask *p =
2837 ImageCache::getInstance ()->getGameButtonImage (i.type)->copy ();
2838
2839 if (p)
2840 {
2841 double ratio = DIALOG_GAME_BUTTON_PIC_FONTSIZE_MULTIPLE;
2842 double new_height = i.font_size * ratio;
2843 int new_width =
2844 ImageCache::calculate_width_from_adjusted_height (p, new_height);
2845 PixMask::scale (p, new_width, new_height);
2846 }
2847 return p;
2848 }
2849
comp(const GameButtonPixMaskCacheItem item) const2850 int GameButtonPixMaskCacheItem::comp(const GameButtonPixMaskCacheItem item) const
2851 {
2852 return
2853 (type < item.type) ? -1 :
2854 (type > item.type) ? 1 :
2855 (font_size < item.font_size) ? -1 :
2856 (font_size > item.font_size) ? 1 :
2857 0;
2858 }
2859
generate(DialogPixMaskCacheItem i)2860 PixMask *DialogPixMaskCacheItem::generate(DialogPixMaskCacheItem i)
2861 {
2862 PixMask *p = NULL;
2863 double ratio = 1;
2864 switch (i.type)
2865 {
2866 case ImageCache::DIALOG_NEXT_TURN:
2867 p = ImageCache::getInstance ()->getNextTurnPic ()->copy ();
2868 ratio = DIALOG_NEXT_TURN_PIC_FONT_SIZE_MULTIPLE;
2869 break;
2870 case ImageCache::DIALOG_NEW_HERO_MALE:
2871 p = ImageCache::getInstance ()->getHeroPic (Hero::MALE)->copy ();
2872 ratio = DIALOG_NEW_HERO_PIC_FONT_SIZE_MULTIPLE;
2873 break;
2874 case ImageCache::DIALOG_NEW_HERO_FEMALE:
2875 p = ImageCache::getInstance ()->getHeroPic (Hero::FEMALE)->copy ();
2876 ratio = DIALOG_NEW_HERO_PIC_FONT_SIZE_MULTIPLE;
2877 break;
2878 case ImageCache::DIALOG_CONQUERED_CITY:
2879 p = ImageCache::getInstance ()->getCityDefeatedPic ()->copy ();
2880 ratio = DIALOG_CONQUERED_CITY_PIC_FONT_SIZE_MULTIPLE;
2881 break;
2882 case ImageCache::DIALOG_WINNING:
2883 p = ImageCache::getInstance ()->getWinningPic()->copy ();
2884 ratio = DIALOG_WINNING_PIC_FONT_SIZE_MULTIPLE;
2885 break;
2886 case ImageCache::DIALOG_RUIN_SUCCESS:
2887 p = ImageCache::getInstance ()->getRuinSuccessPic()->copy ();
2888 ratio = DIALOG_RUIN_PIC_FONT_SIZE_MULTIPLE;
2889 break;
2890 case ImageCache::DIALOG_RUIN_DEFEAT:
2891 p = ImageCache::getInstance ()->getRuinDefeatPic()->copy ();
2892 ratio = DIALOG_RUIN_PIC_FONT_SIZE_MULTIPLE;
2893 break;
2894 case ImageCache::DIALOG_PARLEY_OFFERED:
2895 p = ImageCache::getInstance ()->getParleyOfferedPic()->copy ();
2896 ratio = DIALOG_PARLEY_PIC_FONT_SIZE_MULTIPLE;
2897 break;
2898 case ImageCache::DIALOG_PARLEY_REFUSED:
2899 p = ImageCache::getInstance ()->getParleyRefusedPic()->copy ();
2900 ratio = DIALOG_PARLEY_PIC_FONT_SIZE_MULTIPLE;
2901 break;
2902 case ImageCache::DIALOG_COMMENTATOR:
2903 p = ImageCache::getInstance ()->getCommentatorPic()->copy ();
2904 ratio = DIALOG_COMMENTATOR_PIC_FONT_SIZE_MULTIPLE;
2905 break;
2906 }
2907 if (p)
2908 {
2909 double new_height = i.font_size * ratio;
2910 int new_width =
2911 ImageCache::calculate_width_from_adjusted_height (p, new_height);
2912 PixMask::scale (p, new_width, new_height);
2913 }
2914 return p;
2915 }
2916
comp(const DialogPixMaskCacheItem item) const2917 int DialogPixMaskCacheItem::comp(const DialogPixMaskCacheItem item) const
2918 {
2919 return
2920 (type < item.type) ? -1 :
2921 (type > item.type) ? 1 :
2922 (font_size < item.font_size) ? -1 :
2923 (font_size > item.font_size) ? 1 :
2924 0;
2925 }
2926
2927
generate(MedalPixMaskCacheItem i)2928 PixMask *MedalPixMaskCacheItem::generate(MedalPixMaskCacheItem i)
2929 {
2930 PixMask *p =
2931 ImageCache::getInstance ()->getMedalImage (i.large, i.type)->copy ();
2932
2933 if (i.large == false)
2934 return p;
2935
2936 if (p)
2937 {
2938 double ratio = DIALOG_MEDAL_PIC_FONTSIZE_MULTIPLE;
2939 double new_height = i.font_size * ratio;
2940 int new_width =
2941 ImageCache::calculate_width_from_adjusted_height (p, new_height);
2942 PixMask::scale (p, new_width, new_height);
2943 }
2944 return p;
2945 }
2946
comp(const MedalPixMaskCacheItem item) const2947 int MedalPixMaskCacheItem::comp(const MedalPixMaskCacheItem item) const
2948 {
2949 return
2950 (large < item.large) ? -1 :
2951 (large > item.large) ? 1 :
2952 (type < item.type) ? -1 :
2953 (type > item.type) ? 1 :
2954 (font_size < item.font_size) ? -1 :
2955 (font_size > item.font_size) ? 1 :
2956 0;
2957 }
2958