1 /*
2  *  This file is part of Dune Legacy.
3  *
4  *  Dune Legacy is free software: you can redistribute it and/or modify
5  *  it under the terms of the GNU General Public License as published by
6  *  the Free Software Foundation, either version 2 of the License, or
7  *  (at your option) any later version.
8  *
9  *  Dune Legacy is distributed in the hope that it will be useful,
10  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  *  GNU General Public License for more details.
13  *
14  *  You should have received a copy of the GNU General Public License
15  *  along with Dune Legacy.  If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 #include <FileClasses/GFXManager.h>
19 
20 #include <globals.h>
21 
22 #include <FileClasses/FileManager.h>
23 #include <FileClasses/TextManager.h>
24 #include <FileClasses/PictureFactory.h>
25 #include <FileClasses/LoadSavePNG.h>
26 #include <FileClasses/Shpfile.h>
27 #include <FileClasses/Cpsfile.h>
28 #include <FileClasses/Icnfile.h>
29 #include <FileClasses/Wsafile.h>
30 #include <FileClasses/Palfile.h>
31 
32 #include <misc/draw_util.h>
33 #include <misc/Scaler.h>
34 #include <misc/exceptions.h>
35 
36 using std::shared_ptr;
37 
38 /**
39     Number of columns and rows each obj pic has
40 */
41 static Coord objPicTiles[] {
42     { 8, 1 },   // ObjPic_Tank_Base
43     { 8, 1 },   // ObjPic_Tank_Gun
44     { 8, 1 },   // ObjPic_Siegetank_Base
45     { 8, 1 },   // ObjPic_Siegetank_Gun
46     { 8, 1 },   // ObjPic_Devastator_Base
47     { 8, 1 },   // ObjPic_Devastator_Gun
48     { 8, 1 },   // ObjPic_Sonictank_Gun
49     { 8, 1 },   // ObjPic_Launcher_Gun
50     { 8, 1 },   // ObjPic_Quad
51     { 8, 1 },   // ObjPic_Trike
52     { 8, 1 },   // ObjPic_Harvester
53     { 8, 3 },   // ObjPic_Harvester_Sand
54     { 8, 1 },   // ObjPic_MCV
55     { 8, 2 },   // ObjPic_Carryall
56     { 8, 2 },   // ObjPic_CarryallShadow
57     { 8, 1 },   // ObjPic_Frigate
58     { 8, 1 },   // ObjPic_FrigateShadow
59     { 8, 3 },   // ObjPic_Ornithopter
60     { 8, 3 },   // ObjPic_OrnithopterShadow
61     { 4, 3 },   // ObjPic_Trooper
62     { 4, 3 },   // ObjPic_Troopers
63     { 4, 3 },   // ObjPic_Soldier
64     { 4, 3 },   // ObjPic_Infantry
65     { 4, 3 },   // ObjPic_Saboteur
66     { 1, 9 },   // ObjPic_Sandworm
67     { 4, 1 },   // ObjPic_ConstructionYard
68     { 4, 1 },   // ObjPic_Windtrap
69     { 10, 1 },  // ObjPic_Refinery
70     { 4, 1 },   // ObjPic_Barracks
71     { 4, 1 },   // ObjPic_WOR
72     { 4, 1 },   // ObjPic_Radar
73     { 6, 1 },   // ObjPic_LightFactory
74     { 4, 1 },   // ObjPic_Silo
75     { 8, 1 },   // ObjPic_HeavyFactory
76     { 8, 1 },   // ObjPic_HighTechFactory
77     { 4, 1 },   // ObjPic_IX
78     { 4, 1 },   // ObjPic_Palace
79     { 10, 1 },  // ObjPic_RepairYard
80     { 10, 1 },  // ObjPic_Starport
81     { 10, 1 },  // ObjPic_GunTurret
82     { 10, 1 },  // ObjPic_RocketTurret
83     { 25, 3 },  // ObjPic_Wall
84     { 16, 1 },  // ObjPic_Bullet_SmallRocket
85     { 16, 1 },  // ObjPic_Bullet_MediumRocket
86     { 16, 1 },  // ObjPic_Bullet_LargeRocket
87     { 1, 1 },   // ObjPic_Bullet_Small
88     { 1, 1 },   // ObjPic_Bullet_Medium
89     { 1, 1 },   // ObjPic_Bullet_Large
90     { 1, 1 },   // ObjPic_Bullet_Sonic
91     { 1, 1 },   // ObjPic_Bullet_SonicTemp
92     { 5, 1 },   // ObjPic_Hit_Gas
93     { 1, 1 },   // ObjPic_Hit_ShellSmall
94     { 1, 1 },   // ObjPic_Hit_ShellMedium
95     { 1, 1 },   // ObjPic_Hit_ShellLarge
96     { 5, 1 },   // ObjPic_ExplosionSmall
97     { 5, 1 },   // ObjPic_ExplosionMedium1
98     { 5, 1 },   // ObjPic_ExplosionMedium2
99     { 5, 1 },   // ObjPic_ExplosionLarge1
100     { 5, 1 },   // ObjPic_ExplosionLarge2
101     { 2, 1 },   // ObjPic_ExplosionSmallUnit
102     { 21, 1 },  // ObjPic_ExplosionFlames
103     { 3, 1 },   // ObjPic_ExplosionSpiceBloom
104     { 6, 1 },   // ObjPic_DeadInfantry
105     { 6, 1 },   // ObjPic_DeadAirUnit
106     { 3, 1 },   // ObjPic_Smoke
107     { 1, 1 },   // ObjPic_SandwormShimmerMask
108     { 1, 1 },   // ObjPic_SandwormShimmerTemp
109     { NUM_TERRAIN_TILES_X, NUM_TERRAIN_TILES_Y },  // ObjPic_Terrain
110     { 14, 1 },  // ObjPic_DestroyedStructure
111     { 6, 1 },   // ObjPic_RockDamage
112     { 3, 1 },   // ObjPic_SandDamage
113     { 16, 1 },  // ObjPic_Terrain_Hidden
114     { 16, 1 },  // ObjPic_Terrain_HiddenFog
115     { 8, 1 },   // ObjPic_Terrain_Tracks
116     { 1, 1 },   // ObjPic_Star
117 };
118 
119 
GFXManager()120 GFXManager::GFXManager() {
121     // init whole objPic and objPicTex arrays
122     for(int i = 0; i < NUM_OBJPICS; i++) {
123         for(int j = 0; j < (int) NUM_HOUSES; j++) {
124             for(int z=0; z < NUM_ZOOMLEVEL; z++) {
125                 objPic[i][j][z] = nullptr;
126                 objPicTex[i][j][z] = nullptr;
127             }
128         }
129     }
130 
131     // init whole smallDetailPicTex array
132     for(int i = 0; i < NUM_SMALLDETAILPICS; i++) {
133         smallDetailPicTex[i] = nullptr;
134     }
135 
136     // init whole tinyPictureTex array
137     for(int i = 0; i < NUM_SMALLDETAILPICS; i++) {
138         tinyPictureTex[i] = nullptr;
139     }
140 
141     // init whole UIGraphic array
142     for(int i = 0; i < NUM_UIGRAPHICS; i++) {
143         for(int j = 0; j < (int) NUM_HOUSES; j++) {
144             uiGraphic[i][j] = nullptr;
145             uiGraphicTex[i][j] = nullptr;
146         }
147     }
148 
149     // init whole mapChoicePieces and mapChoicePiecesTex array
150     for(int i = 0; i < NUM_MAPCHOICEPIECES; i++) {
151         for(int j = 0; j < (int) NUM_HOUSES; j++) {
152             mapChoicePieces[i][j] = nullptr;
153             mapChoicePiecesTex[i][j] = nullptr;
154         }
155     }
156 
157     // init whole Anim array
158     for(int i = 0; i < NUM_ANIMATION; i++) {
159         animation[i] = nullptr;
160     }
161 
162     // open all shp files
163     shared_ptr<Shpfile> units = loadShpfile("UNITS.SHP");
164     shared_ptr<Shpfile> units1 = loadShpfile("UNITS1.SHP");
165     shared_ptr<Shpfile> units2 = loadShpfile("UNITS2.SHP");
166     shared_ptr<Shpfile> mouse = loadShpfile("MOUSE.SHP");
167     shared_ptr<Shpfile> shapes = loadShpfile("SHAPES.SHP");
168     shared_ptr<Shpfile> menshpa = loadShpfile("MENSHPA.SHP");
169     shared_ptr<Shpfile> menshph = loadShpfile("MENSHPH.SHP");
170     shared_ptr<Shpfile> menshpo = loadShpfile("MENSHPO.SHP");
171     shared_ptr<Shpfile> menshpm = loadShpfile("MENSHPM.SHP");
172 
173     shared_ptr<Shpfile> choam;
174     if(pFileManager->exists("CHOAM." + _("LanguageFileExtension"))) {
175         choam = loadShpfile("CHOAM." + _("LanguageFileExtension"));
176     } else if(pFileManager->exists("CHOAMSHP.SHP")) {
177         choam = loadShpfile("CHOAMSHP.SHP");
178     } else {
179         THROW(std::runtime_error, "GFXManager::GFXManager(): Cannot open CHOAMSHP.SHP or CHOAM."+_("LanguageFileExtension")+"!");
180     }
181 
182     shared_ptr<Shpfile> bttn;
183     if(pFileManager->exists("BTTN." + _("LanguageFileExtension"))) {
184         bttn = loadShpfile("BTTN." + _("LanguageFileExtension"));
185     } else {
186         // The US-Version has the buttons in SHAPES.SHP
187         // => bttn == nullptr
188     }
189 
190     shared_ptr<Shpfile> mentat;
191     if(pFileManager->exists("MENTAT." + _("LanguageFileExtension"))) {
192         mentat = loadShpfile("MENTAT." + _("LanguageFileExtension"));
193     } else {
194         mentat = loadShpfile("MENTAT.SHP");
195     }
196 
197     shared_ptr<Shpfile> pieces = loadShpfile("PIECES.SHP");
198     shared_ptr<Shpfile> arrows = loadShpfile("ARROWS.SHP");
199 
200     // Load icon file
201     shared_ptr<Icnfile> icon = shared_ptr<Icnfile>(new Icnfile(pFileManager->openFile("ICON.ICN"),pFileManager->openFile("ICON.MAP"), true));
202 
203     // Load radar static
204     shared_ptr<Wsafile> radar = loadWsafile("STATIC.WSA");
205 
206     // open bene palette
207     Palette benePalette = LoadPalette_RW(pFileManager->openFile("BENE.PAL"), true);
208 
209     //create PictureFactory
210     shared_ptr<PictureFactory> PicFactory = shared_ptr<PictureFactory>(new PictureFactory());
211 
212 
213 
214     // load object pics in the original resolution
215     objPic[ObjPic_Tank_Base][HOUSE_HARKONNEN][0] = units2->getPictureArray(8,1,GROUNDUNIT_ROW(0));
216     objPic[ObjPic_Tank_Gun][HOUSE_HARKONNEN][0] = units2->getPictureArray(8,1,GROUNDUNIT_ROW(5));
217     objPic[ObjPic_Siegetank_Base][HOUSE_HARKONNEN][0] = units2->getPictureArray(8,1,GROUNDUNIT_ROW(10));
218     objPic[ObjPic_Siegetank_Gun][HOUSE_HARKONNEN][0] = units2->getPictureArray(8,1,GROUNDUNIT_ROW(15));
219     objPic[ObjPic_Devastator_Base][HOUSE_HARKONNEN][0] = units2->getPictureArray(8,1,GROUNDUNIT_ROW(20));
220     objPic[ObjPic_Devastator_Gun][HOUSE_HARKONNEN][0] = units2->getPictureArray(8,1,GROUNDUNIT_ROW(25));
221     objPic[ObjPic_Sonictank_Gun][HOUSE_HARKONNEN][0] = units2->getPictureArray(8,1,GROUNDUNIT_ROW(30));
222     objPic[ObjPic_Launcher_Gun][HOUSE_HARKONNEN][0] = units2->getPictureArray(8,1,GROUNDUNIT_ROW(35));
223     objPic[ObjPic_Quad][HOUSE_HARKONNEN][0] = units->getPictureArray(8,1,GROUNDUNIT_ROW(0));
224     objPic[ObjPic_Trike][HOUSE_HARKONNEN][0] = units->getPictureArray(8,1,GROUNDUNIT_ROW(5));
225     objPic[ObjPic_Harvester][HOUSE_HARKONNEN][0] = units->getPictureArray(8,1,GROUNDUNIT_ROW(10));
226     objPic[ObjPic_Harvester_Sand][HOUSE_HARKONNEN][0] = units1->getPictureArray(8,3,HARVESTERSAND_ROW(72),HARVESTERSAND_ROW(73),HARVESTERSAND_ROW(74));
227     objPic[ObjPic_MCV][HOUSE_HARKONNEN][0] = units->getPictureArray(8,1,GROUNDUNIT_ROW(15));
228     objPic[ObjPic_Carryall][HOUSE_HARKONNEN][0] = units->getPictureArray(8,2,AIRUNIT_ROW(45),AIRUNIT_ROW(48));
229     objPic[ObjPic_CarryallShadow][HOUSE_HARKONNEN][0] = nullptr;    // create shadow after scaling
230     objPic[ObjPic_Frigate][HOUSE_HARKONNEN][0] = units->getPictureArray(8,1,AIRUNIT_ROW(60));
231     objPic[ObjPic_FrigateShadow][HOUSE_HARKONNEN][0] = nullptr;     // create shadow after scaling
232     objPic[ObjPic_Ornithopter][HOUSE_HARKONNEN][0] = units->getPictureArray(8,3,ORNITHOPTER_ROW(51),ORNITHOPTER_ROW(52),ORNITHOPTER_ROW(53));
233     objPic[ObjPic_OrnithopterShadow][HOUSE_HARKONNEN][0] = nullptr; // create shadow after scaling
234     objPic[ObjPic_Trooper][HOUSE_HARKONNEN][0] = units->getPictureArray(4,3,INFANTRY_ROW(82),INFANTRY_ROW(83),INFANTRY_ROW(84));
235     objPic[ObjPic_Troopers][HOUSE_HARKONNEN][0] = units->getPictureArray(4,4,MULTIINFANTRY_ROW(103),MULTIINFANTRY_ROW(104),MULTIINFANTRY_ROW(105),MULTIINFANTRY_ROW(106));
236     objPic[ObjPic_Soldier][HOUSE_HARKONNEN][0] = units->getPictureArray(4,3,INFANTRY_ROW(73),INFANTRY_ROW(74),INFANTRY_ROW(75));
237     objPic[ObjPic_Infantry][HOUSE_HARKONNEN][0] = units->getPictureArray(4,4,MULTIINFANTRY_ROW(91),MULTIINFANTRY_ROW(92),MULTIINFANTRY_ROW(93),MULTIINFANTRY_ROW(94));
238     objPic[ObjPic_Saboteur][HOUSE_HARKONNEN][0] = units->getPictureArray(4,3,INFANTRY_ROW(63),INFANTRY_ROW(64),INFANTRY_ROW(65));
239     objPic[ObjPic_Sandworm][HOUSE_HARKONNEN][0] = units1->getPictureArray(1,9,71|TILE_NORMAL,70|TILE_NORMAL,69|TILE_NORMAL,68|TILE_NORMAL,67|TILE_NORMAL,68|TILE_NORMAL,69|TILE_NORMAL,70|TILE_NORMAL,71|TILE_NORMAL);
240     objPic[ObjPic_ConstructionYard][HOUSE_HARKONNEN][0] = icon->getPictureArray(17);
241     objPic[ObjPic_Windtrap][HOUSE_HARKONNEN][0] = icon->getPictureArray(19);
242     objPic[ObjPic_Refinery][HOUSE_HARKONNEN][0] = icon->getPictureArray(21);
243     objPic[ObjPic_Barracks][HOUSE_HARKONNEN][0] = icon->getPictureArray(18);
244     objPic[ObjPic_WOR][HOUSE_HARKONNEN][0] = icon->getPictureArray(16);
245     objPic[ObjPic_Radar][HOUSE_HARKONNEN][0] = icon->getPictureArray(26);
246     objPic[ObjPic_LightFactory][HOUSE_HARKONNEN][0] = icon->getPictureArray(12);
247     objPic[ObjPic_Silo][HOUSE_HARKONNEN][0] = icon->getPictureArray(25);
248     objPic[ObjPic_HeavyFactory][HOUSE_HARKONNEN][0] = icon->getPictureArray(13);
249     objPic[ObjPic_HighTechFactory][HOUSE_HARKONNEN][0] = icon->getPictureArray(14);
250     objPic[ObjPic_IX][HOUSE_HARKONNEN][0] = icon->getPictureArray(15);
251     objPic[ObjPic_Palace][HOUSE_HARKONNEN][0] = icon->getPictureArray(11);
252     objPic[ObjPic_RepairYard][HOUSE_HARKONNEN][0] = icon->getPictureArray(22);
253     objPic[ObjPic_Starport][HOUSE_HARKONNEN][0] = icon->getPictureArray(20);
254     objPic[ObjPic_GunTurret][HOUSE_HARKONNEN][0] = icon->getPictureArray(23);
255     objPic[ObjPic_RocketTurret][HOUSE_HARKONNEN][0] = icon->getPictureArray(24);
256     objPic[ObjPic_Wall][HOUSE_HARKONNEN][0] = icon->getPictureArray(6,25,3,1);
257     objPic[ObjPic_Bullet_SmallRocket][HOUSE_HARKONNEN][0] = units->getPictureArray(16,1,ROCKET_ROW(35));
258     objPic[ObjPic_Bullet_MediumRocket][HOUSE_HARKONNEN][0] = units->getPictureArray(16,1,ROCKET_ROW(20));
259     objPic[ObjPic_Bullet_LargeRocket][HOUSE_HARKONNEN][0] = units->getPictureArray(16,1,ROCKET_ROW(40));
260     objPic[ObjPic_Bullet_Small][HOUSE_HARKONNEN][0] = units1->getPicture(23);
261     objPic[ObjPic_Bullet_Medium][HOUSE_HARKONNEN][0] = units1->getPicture(24);
262     objPic[ObjPic_Bullet_Large][HOUSE_HARKONNEN][0] = units1->getPicture(25);
263     objPic[ObjPic_Bullet_Sonic][HOUSE_HARKONNEN][0] = units1->getPicture(10);
264     replaceColor(objPic[ObjPic_Bullet_Sonic][HOUSE_HARKONNEN][0], PALCOLOR_WHITE, PALCOLOR_BLACK);
265     objPic[ObjPic_Bullet_SonicTemp][HOUSE_HARKONNEN][0] = units1->getPicture(10);
266     objPic[ObjPic_Hit_Gas][HOUSE_ORDOS][0] = units1->getPictureArray(5,1,57|TILE_NORMAL,58|TILE_NORMAL,59|TILE_NORMAL,60|TILE_NORMAL,61|TILE_NORMAL);
267     objPic[ObjPic_Hit_Gas][HOUSE_HARKONNEN][0] = mapSurfaceColorRange(objPic[ObjPic_Hit_Gas][HOUSE_ORDOS][0], PALCOLOR_ORDOS, PALCOLOR_HARKONNEN);
268     objPic[ObjPic_Hit_ShellSmall][HOUSE_HARKONNEN][0] = units1->getPicture(2);
269     objPic[ObjPic_Hit_ShellMedium][HOUSE_HARKONNEN][0] = units1->getPicture(3);
270     objPic[ObjPic_Hit_ShellLarge][HOUSE_HARKONNEN][0] = units1->getPicture(4);
271     objPic[ObjPic_ExplosionSmall][HOUSE_HARKONNEN][0] = units1->getPictureArray(5,1,32|TILE_NORMAL,33|TILE_NORMAL,34|TILE_NORMAL,35|TILE_NORMAL,36|TILE_NORMAL);
272     objPic[ObjPic_ExplosionMedium1][HOUSE_HARKONNEN][0] = units1->getPictureArray(5,1,47|TILE_NORMAL,48|TILE_NORMAL,49|TILE_NORMAL,50|TILE_NORMAL,51|TILE_NORMAL);
273     objPic[ObjPic_ExplosionMedium2][HOUSE_HARKONNEN][0] = units1->getPictureArray(5,1,52|TILE_NORMAL,53|TILE_NORMAL,54|TILE_NORMAL,55|TILE_NORMAL,56|TILE_NORMAL);
274     objPic[ObjPic_ExplosionLarge1][HOUSE_HARKONNEN][0] = units1->getPictureArray(5,1,37|TILE_NORMAL,38|TILE_NORMAL,39|TILE_NORMAL,40|TILE_NORMAL,41|TILE_NORMAL);
275     objPic[ObjPic_ExplosionLarge2][HOUSE_HARKONNEN][0] = units1->getPictureArray(5,1,42|TILE_NORMAL,43|TILE_NORMAL,44|TILE_NORMAL,45|TILE_NORMAL,46|TILE_NORMAL);
276     objPic[ObjPic_ExplosionSmallUnit][HOUSE_HARKONNEN][0] = units1->getPictureArray(2,1,0|TILE_NORMAL,1|TILE_NORMAL);
277     objPic[ObjPic_ExplosionFlames][HOUSE_HARKONNEN][0] = units1->getPictureArray(21,1,  11|TILE_NORMAL,12|TILE_NORMAL,13|TILE_NORMAL,17|TILE_NORMAL,18|TILE_NORMAL,19|TILE_NORMAL,17|TILE_NORMAL,
278                                                                                     18|TILE_NORMAL,19|TILE_NORMAL,17|TILE_NORMAL,18|TILE_NORMAL,19|TILE_NORMAL,17|TILE_NORMAL,18|TILE_NORMAL,
279                                                                                     19|TILE_NORMAL,17|TILE_NORMAL,18|TILE_NORMAL,19|TILE_NORMAL,20|TILE_NORMAL,21|TILE_NORMAL,22|TILE_NORMAL);
280     objPic[ObjPic_ExplosionSpiceBloom][HOUSE_HARKONNEN][0] = units1->getPictureArray(3,1,7|TILE_NORMAL,6|TILE_NORMAL,5|TILE_NORMAL);
281     objPic[ObjPic_DeadInfantry][HOUSE_HARKONNEN][0] = icon->getPictureArray(4,1,1,6);
282     objPic[ObjPic_DeadAirUnit][HOUSE_HARKONNEN][0] = icon->getPictureArray(3,1,1,6);
283     objPic[ObjPic_Smoke][HOUSE_HARKONNEN][0] = units1->getPictureArray(3,1,29|TILE_NORMAL,30|TILE_NORMAL,31|TILE_NORMAL);
284     objPic[ObjPic_SandwormShimmerMask][HOUSE_HARKONNEN][0] = units1->getPicture(10);
285     replaceColor(objPic[ObjPic_SandwormShimmerMask][HOUSE_HARKONNEN][0], PALCOLOR_WHITE, PALCOLOR_BLACK);
286     objPic[ObjPic_SandwormShimmerTemp][HOUSE_HARKONNEN][0] = units1->getPicture(10);
287     objPic[ObjPic_Terrain][HOUSE_HARKONNEN][0] = icon->getPictureRow(124,209,NUM_TERRAIN_TILES_X);
288     objPic[ObjPic_DestroyedStructure][HOUSE_HARKONNEN][0] = icon->getPictureRow2(14, 33, 125, 213, 214, 215, 223, 224, 225, 232, 233, 234, 240, 246, 247);
289     objPic[ObjPic_RockDamage][HOUSE_HARKONNEN][0] = icon->getPictureRow(1,6);
290     objPic[ObjPic_SandDamage][HOUSE_HARKONNEN][0] = icon->getPictureRow(7,12);
291     objPic[ObjPic_Terrain_Hidden][HOUSE_HARKONNEN][0] = icon->getPictureRow(108,123);
292     objPic[ObjPic_Terrain_HiddenFog][HOUSE_HARKONNEN][0] = icon->getPictureRow(108,123);
293     objPic[ObjPic_Terrain_Tracks][HOUSE_HARKONNEN][0] = icon->getPictureRow(25,32);
294     objPic[ObjPic_Star][HOUSE_HARKONNEN][0] = LoadPNG_RW(pFileManager->openFile("Star5x5.png"),true);
295     objPic[ObjPic_Star][HOUSE_HARKONNEN][1] = LoadPNG_RW(pFileManager->openFile("Star7x7.png"),true);
296     objPic[ObjPic_Star][HOUSE_HARKONNEN][2] = LoadPNG_RW(pFileManager->openFile("Star11x11.png"),true);
297 
298     // scale obj pics and apply color key
299     for(int id = 0; id < NUM_OBJPICS; id++) {
300         for(int h = 0; h < (int) NUM_HOUSES; h++) {
301             if(objPic[id][h][0] != nullptr) {
302                 if(objPic[id][h][1] == nullptr) {
303                     objPic[id][h][1] = generateDoubledObjPic(id, h);
304                 }
305                 SDL_SetColorKey(objPic[id][h][1], SDL_TRUE, PALCOLOR_TRANSPARENT);
306 
307                 if(objPic[id][h][2] == nullptr) {
308                     objPic[id][h][2] = generateTripledObjPic(id, h);
309                 }
310                 SDL_SetColorKey(objPic[id][h][2], SDL_TRUE, PALCOLOR_TRANSPARENT);
311 
312                 SDL_SetColorKey(objPic[id][h][0], SDL_TRUE, PALCOLOR_TRANSPARENT);
313             }
314         }
315     }
316 
317     objPic[ObjPic_CarryallShadow][HOUSE_HARKONNEN][0] = createShadowSurface(objPic[ObjPic_Carryall][HOUSE_HARKONNEN][0]);
318     objPic[ObjPic_CarryallShadow][HOUSE_HARKONNEN][1] = createShadowSurface(objPic[ObjPic_Carryall][HOUSE_HARKONNEN][1]);
319     objPic[ObjPic_CarryallShadow][HOUSE_HARKONNEN][2] = createShadowSurface(objPic[ObjPic_Carryall][HOUSE_HARKONNEN][2]);
320     objPic[ObjPic_FrigateShadow][HOUSE_HARKONNEN][0] = createShadowSurface(objPic[ObjPic_Frigate][HOUSE_HARKONNEN][0]);
321     objPic[ObjPic_FrigateShadow][HOUSE_HARKONNEN][1] = createShadowSurface(objPic[ObjPic_Frigate][HOUSE_HARKONNEN][1]);
322     objPic[ObjPic_FrigateShadow][HOUSE_HARKONNEN][2] = createShadowSurface(objPic[ObjPic_Frigate][HOUSE_HARKONNEN][2]);
323     objPic[ObjPic_OrnithopterShadow][HOUSE_HARKONNEN][0] = createShadowSurface(objPic[ObjPic_Ornithopter][HOUSE_HARKONNEN][0]);
324     objPic[ObjPic_OrnithopterShadow][HOUSE_HARKONNEN][1] = createShadowSurface(objPic[ObjPic_Ornithopter][HOUSE_HARKONNEN][1]);
325     objPic[ObjPic_OrnithopterShadow][HOUSE_HARKONNEN][2] = createShadowSurface(objPic[ObjPic_Ornithopter][HOUSE_HARKONNEN][2]);
326 
327     // load small detail pics
328     smallDetailPicTex[Picture_Barracks] = extractSmallDetailPic("BARRAC.WSA");
329     smallDetailPicTex[Picture_ConstructionYard] = extractSmallDetailPic("CONSTRUC.WSA");
330     smallDetailPicTex[Picture_Carryall] = extractSmallDetailPic("CARRYALL.WSA");
331     smallDetailPicTex[Picture_Devastator] = extractSmallDetailPic("HARKTANK.WSA");
332     smallDetailPicTex[Picture_Deviator] = extractSmallDetailPic("ORDRTANK.WSA");
333     smallDetailPicTex[Picture_DeathHand] = extractSmallDetailPic("GOLD-BB.WSA");
334     smallDetailPicTex[Picture_Fremen] = extractSmallDetailPic("FREMEN.WSA");
335     if(pFileManager->exists("FRIGATE.WSA")) {
336         smallDetailPicTex[Picture_Frigate] = extractSmallDetailPic("FRIGATE.WSA");
337     } else {
338         // US-Version 1.07 does not contain FRIGATE.WSA
339         // We replace it with the starport
340         smallDetailPicTex[Picture_Frigate] = extractSmallDetailPic("STARPORT.WSA");
341     }
342     smallDetailPicTex[Picture_GunTurret] = extractSmallDetailPic("TURRET.WSA");
343     smallDetailPicTex[Picture_Harvester] = extractSmallDetailPic("HARVEST.WSA");
344     smallDetailPicTex[Picture_HeavyFactory] = extractSmallDetailPic("HVYFTRY.WSA");
345     smallDetailPicTex[Picture_HighTechFactory] = extractSmallDetailPic("HITCFTRY.WSA");
346     smallDetailPicTex[Picture_Soldier] = extractSmallDetailPic("INFANTRY.WSA");
347     smallDetailPicTex[Picture_IX] = extractSmallDetailPic("IX.WSA");
348     smallDetailPicTex[Picture_Launcher] = extractSmallDetailPic("RTANK.WSA");
349     smallDetailPicTex[Picture_LightFactory] = extractSmallDetailPic("LITEFTRY.WSA");
350     smallDetailPicTex[Picture_MCV] = extractSmallDetailPic("MCV.WSA");
351     smallDetailPicTex[Picture_Ornithopter] = extractSmallDetailPic("ORNI.WSA");
352     smallDetailPicTex[Picture_Palace] = extractSmallDetailPic("PALACE.WSA");
353     smallDetailPicTex[Picture_Quad] = extractSmallDetailPic("QUAD.WSA");
354     smallDetailPicTex[Picture_Radar] = extractSmallDetailPic("HEADQRTS.WSA");
355     smallDetailPicTex[Picture_RaiderTrike] = extractSmallDetailPic("OTRIKE.WSA");
356     smallDetailPicTex[Picture_Refinery] = extractSmallDetailPic("REFINERY.WSA");
357     smallDetailPicTex[Picture_RepairYard] = extractSmallDetailPic("REPAIR.WSA");
358     smallDetailPicTex[Picture_RocketTurret] = extractSmallDetailPic("RTURRET.WSA");
359     smallDetailPicTex[Picture_Saboteur] = extractSmallDetailPic("SABOTURE.WSA");
360     smallDetailPicTex[Picture_Sandworm] = extractSmallDetailPic("WORM.WSA");
361     smallDetailPicTex[Picture_Sardaukar] = extractSmallDetailPic("SARDUKAR.WSA");
362     smallDetailPicTex[Picture_SiegeTank] = extractSmallDetailPic("HTANK.WSA");
363     smallDetailPicTex[Picture_Silo] = extractSmallDetailPic("STORAGE.WSA");
364     smallDetailPicTex[Picture_Slab1] = extractSmallDetailPic("SLAB.WSA");
365     smallDetailPicTex[Picture_Slab4] = extractSmallDetailPic("4SLAB.WSA");
366     smallDetailPicTex[Picture_SonicTank] = extractSmallDetailPic("STANK.WSA");
367     smallDetailPicTex[Picture_Special]  = nullptr;
368     smallDetailPicTex[Picture_StarPort] = extractSmallDetailPic("STARPORT.WSA");
369     smallDetailPicTex[Picture_Tank] = extractSmallDetailPic("LTANK.WSA");
370     smallDetailPicTex[Picture_Trike] = extractSmallDetailPic("TRIKE.WSA");
371     smallDetailPicTex[Picture_Trooper] = extractSmallDetailPic("HYINFY.WSA");
372     smallDetailPicTex[Picture_Wall] = extractSmallDetailPic("WALL.WSA");
373     smallDetailPicTex[Picture_WindTrap] = extractSmallDetailPic("WINDTRAP.WSA");
374     smallDetailPicTex[Picture_WOR] = extractSmallDetailPic("WOR.WSA");
375     // unused: FARTR.WSA, FHARK.WSA, FORDOS.WSA
376 
377 
378     tinyPictureTex[TinyPicture_Spice] = convertSurfaceToTexture(shapes->getPicture(94), true);
379     tinyPictureTex[TinyPicture_Barracks] = convertSurfaceToTexture(shapes->getPicture(62), true);
380     tinyPictureTex[TinyPicture_ConstructionYard] = convertSurfaceToTexture(shapes->getPicture(60), true);
381     tinyPictureTex[TinyPicture_GunTurret] = convertSurfaceToTexture(shapes->getPicture(67), true);
382     tinyPictureTex[TinyPicture_HeavyFactory] = convertSurfaceToTexture(shapes->getPicture(56), true);
383     tinyPictureTex[TinyPicture_HighTechFactory] = convertSurfaceToTexture(shapes->getPicture(57), true);
384     tinyPictureTex[TinyPicture_IX] = convertSurfaceToTexture(shapes->getPicture(58), true);
385     tinyPictureTex[TinyPicture_LightFactory] = convertSurfaceToTexture(shapes->getPicture(55), true);
386     tinyPictureTex[TinyPicture_Palace] = convertSurfaceToTexture(shapes->getPicture(54), true);
387     tinyPictureTex[TinyPicture_Radar] = convertSurfaceToTexture(shapes->getPicture(70), true);
388     tinyPictureTex[TinyPicture_Refinery] = convertSurfaceToTexture(shapes->getPicture(64), true);
389     tinyPictureTex[TinyPicture_RepairYard] = convertSurfaceToTexture(shapes->getPicture(65), true);
390     tinyPictureTex[TinyPicture_RocketTurret] = convertSurfaceToTexture(shapes->getPicture(68), true);
391     tinyPictureTex[TinyPicture_Silo] = convertSurfaceToTexture(shapes->getPicture(69), true);
392     tinyPictureTex[TinyPicture_Slab1] = convertSurfaceToTexture(shapes->getPicture(53), true);
393     tinyPictureTex[TinyPicture_Slab4] = convertSurfaceToTexture(shapes->getPicture(71), true);
394     tinyPictureTex[TinyPicture_StarPort] = convertSurfaceToTexture(shapes->getPicture(63), true);
395     tinyPictureTex[TinyPicture_Wall] = convertSurfaceToTexture(shapes->getPicture(66), true);
396     tinyPictureTex[TinyPicture_WindTrap] = convertSurfaceToTexture(shapes->getPicture(61), true);
397     tinyPictureTex[TinyPicture_WOR] = convertSurfaceToTexture(shapes->getPicture(59), true);
398     tinyPictureTex[TinyPicture_Carryall] = convertSurfaceToTexture(shapes->getPicture(77), true);
399     tinyPictureTex[TinyPicture_Devastator] = convertSurfaceToTexture(shapes->getPicture(75), true);
400     tinyPictureTex[TinyPicture_Deviator] = convertSurfaceToTexture(shapes->getPicture(86), true);
401     tinyPictureTex[TinyPicture_Frigate] = convertSurfaceToTexture(shapes->getPicture(77), true);    // use carryall picture
402     tinyPictureTex[TinyPicture_Harvester] = convertSurfaceToTexture(shapes->getPicture(88), true);
403     tinyPictureTex[TinyPicture_Soldier] = convertSurfaceToTexture(shapes->getPicture(90), true);
404     tinyPictureTex[TinyPicture_Launcher] = convertSurfaceToTexture(shapes->getPicture(73), true);
405     tinyPictureTex[TinyPicture_MCV] = convertSurfaceToTexture(shapes->getPicture(89), true);
406     tinyPictureTex[TinyPicture_Ornithopter] = convertSurfaceToTexture(shapes->getPicture(85), true);
407     tinyPictureTex[TinyPicture_Quad] = convertSurfaceToTexture(shapes->getPicture(74), true);
408     tinyPictureTex[TinyPicture_Saboteur] = convertSurfaceToTexture(shapes->getPicture(84), true);
409     tinyPictureTex[TinyPicture_Sandworm] = convertSurfaceToTexture(shapes->getPicture(93), true);
410     tinyPictureTex[TinyPicture_SiegeTank] = convertSurfaceToTexture(shapes->getPicture(72), true);
411     tinyPictureTex[TinyPicture_SonicTank] = convertSurfaceToTexture(shapes->getPicture(79), true);
412     tinyPictureTex[TinyPicture_Tank] = convertSurfaceToTexture(shapes->getPicture(78), true);
413     tinyPictureTex[TinyPicture_Trike] = convertSurfaceToTexture(shapes->getPicture(80), true);
414     tinyPictureTex[TinyPicture_RaiderTrike] = convertSurfaceToTexture(shapes->getPicture(87), true);
415     tinyPictureTex[TinyPicture_Trooper] = convertSurfaceToTexture(shapes->getPicture(76), true);
416     tinyPictureTex[TinyPicture_Special] = convertSurfaceToTexture(shapes->getPicture(75), true);    // use devastator picture
417     tinyPictureTex[TinyPicture_Infantry] = convertSurfaceToTexture(shapes->getPicture(81), true);
418     tinyPictureTex[TinyPicture_Troopers] = convertSurfaceToTexture(shapes->getPicture(91), true);
419 
420     // load UI graphics
421     uiGraphic[UI_RadarAnimation][HOUSE_HARKONNEN] = Scaler::doubleSurfaceNN(radar->getAnimationAsPictureRow(NUM_STATIC_ANIMATIONS_PER_ROW));
422 
423     uiGraphic[UI_CursorNormal][HOUSE_HARKONNEN] = mouse->getPicture(0);
424     SDL_SetColorKey(uiGraphic[UI_CursorNormal][HOUSE_HARKONNEN], SDL_TRUE, 0);
425     uiGraphic[UI_CursorUp][HOUSE_HARKONNEN] = mouse->getPicture(1);
426     SDL_SetColorKey(uiGraphic[UI_CursorUp][HOUSE_HARKONNEN], SDL_TRUE, 0);
427     uiGraphic[UI_CursorRight][HOUSE_HARKONNEN] = mouse->getPicture(2);
428     SDL_SetColorKey(uiGraphic[UI_CursorRight][HOUSE_HARKONNEN], SDL_TRUE, 0);
429     uiGraphic[UI_CursorDown][HOUSE_HARKONNEN] = mouse->getPicture(3);
430     SDL_SetColorKey(uiGraphic[UI_CursorDown][HOUSE_HARKONNEN], SDL_TRUE, 0);
431     uiGraphic[UI_CursorLeft][HOUSE_HARKONNEN] = mouse->getPicture(4);
432     SDL_SetColorKey(uiGraphic[UI_CursorLeft][HOUSE_HARKONNEN], SDL_TRUE, 0);
433 
434     uiGraphic[UI_CursorMove_Zoomlevel0][HOUSE_HARKONNEN] = mouse->getPicture(5);
435     SDL_SetColorKey(uiGraphic[UI_CursorMove_Zoomlevel0][HOUSE_HARKONNEN], SDL_TRUE, 0);
436     uiGraphic[UI_CursorMove_Zoomlevel1][HOUSE_HARKONNEN] = Scaler::defaultDoubleTiledSurface(uiGraphic[UI_CursorMove_Zoomlevel0][HOUSE_HARKONNEN], 1, 1, false);
437     SDL_SetColorKey(uiGraphic[UI_CursorMove_Zoomlevel1][HOUSE_HARKONNEN], SDL_TRUE, 0);
438     uiGraphic[UI_CursorMove_Zoomlevel2][HOUSE_HARKONNEN] = Scaler::defaultTripleTiledSurface(uiGraphic[UI_CursorMove_Zoomlevel0][HOUSE_HARKONNEN], 1, 1, false);
439     SDL_SetColorKey(uiGraphic[UI_CursorMove_Zoomlevel2][HOUSE_HARKONNEN], SDL_TRUE, 0);
440 
441     uiGraphic[UI_CursorAttack_Zoomlevel0][HOUSE_HARKONNEN] = mapSurfaceColorRange(uiGraphic[UI_CursorMove_Zoomlevel0][HOUSE_HARKONNEN], 232, PALCOLOR_HARKONNEN);
442     SDL_SetColorKey(uiGraphic[UI_CursorAttack_Zoomlevel0][HOUSE_HARKONNEN], SDL_TRUE, 0);
443     uiGraphic[UI_CursorAttack_Zoomlevel1][HOUSE_HARKONNEN] = Scaler::defaultDoubleTiledSurface(uiGraphic[UI_CursorAttack_Zoomlevel0][HOUSE_HARKONNEN], 1, 1, false);
444     SDL_SetColorKey(uiGraphic[UI_CursorAttack_Zoomlevel1][HOUSE_HARKONNEN], SDL_TRUE, 0);
445     uiGraphic[UI_CursorAttack_Zoomlevel2][HOUSE_HARKONNEN] = Scaler::defaultTripleTiledSurface(uiGraphic[UI_CursorAttack_Zoomlevel0][HOUSE_HARKONNEN], 1, 1, false);
446     SDL_SetColorKey(uiGraphic[UI_CursorAttack_Zoomlevel2][HOUSE_HARKONNEN], SDL_TRUE, 0);
447 
448     uiGraphic[UI_CursorCapture_Zoomlevel0][HOUSE_HARKONNEN] = LoadPNG_RW(pFileManager->openFile("Capture.png"),true);
449     SDL_SetColorKey(uiGraphic[UI_CursorCapture_Zoomlevel0][HOUSE_HARKONNEN], SDL_TRUE, 0);
450     uiGraphic[UI_CursorCapture_Zoomlevel1][HOUSE_HARKONNEN] = Scaler::defaultDoubleTiledSurface(uiGraphic[UI_CursorCapture_Zoomlevel0][HOUSE_HARKONNEN], 1, 1, false);
451     SDL_SetColorKey(uiGraphic[UI_CursorCapture_Zoomlevel1][HOUSE_HARKONNEN], SDL_TRUE, 0);
452     uiGraphic[UI_CursorCapture_Zoomlevel2][HOUSE_HARKONNEN] = Scaler::defaultTripleTiledSurface(uiGraphic[UI_CursorCapture_Zoomlevel0][HOUSE_HARKONNEN], 1, 1, false);
453     SDL_SetColorKey(uiGraphic[UI_CursorCapture_Zoomlevel2][HOUSE_HARKONNEN], SDL_TRUE, 0);
454 
455     uiGraphic[UI_CursorCarryallDrop_Zoomlevel0][HOUSE_HARKONNEN] = LoadPNG_RW(pFileManager->openFile("CarryallDrop.png"),true);
456     SDL_SetColorKey(uiGraphic[UI_CursorCarryallDrop_Zoomlevel0][HOUSE_HARKONNEN], SDL_TRUE, 0);
457     uiGraphic[UI_CursorCarryallDrop_Zoomlevel1][HOUSE_HARKONNEN] = Scaler::defaultDoubleTiledSurface(uiGraphic[UI_CursorCarryallDrop_Zoomlevel0][HOUSE_HARKONNEN], 1, 1, false);
458     SDL_SetColorKey(uiGraphic[UI_CursorCarryallDrop_Zoomlevel1][HOUSE_HARKONNEN], SDL_TRUE, 0);
459     uiGraphic[UI_CursorCarryallDrop_Zoomlevel2][HOUSE_HARKONNEN] = Scaler::defaultTripleTiledSurface(uiGraphic[UI_CursorCarryallDrop_Zoomlevel0][HOUSE_HARKONNEN], 1, 1, false);
460     SDL_SetColorKey(uiGraphic[UI_CursorCarryallDrop_Zoomlevel2][HOUSE_HARKONNEN], SDL_TRUE, 0);
461 
462     uiGraphic[UI_ReturnIcon][HOUSE_HARKONNEN] = LoadPNG_RW(pFileManager->openFile("Return.png"),true);
463     SDL_SetColorKey(uiGraphic[UI_ReturnIcon][HOUSE_HARKONNEN], SDL_TRUE, 0);
464 
465     uiGraphic[UI_DeployIcon][HOUSE_HARKONNEN] = LoadPNG_RW(pFileManager->openFile("Deploy.png"),true);
466     SDL_SetColorKey(uiGraphic[UI_DeployIcon][HOUSE_HARKONNEN], SDL_TRUE, 0);
467 
468     uiGraphic[UI_DestructIcon][HOUSE_HARKONNEN] = LoadPNG_RW(pFileManager->openFile("Destruct.png"),true);
469     SDL_SetColorKey(uiGraphic[UI_DestructIcon][HOUSE_HARKONNEN], SDL_TRUE, 0);
470 
471     uiGraphic[UI_SendToRepairIcon][HOUSE_HARKONNEN] = LoadPNG_RW(pFileManager->openFile("SendToRepair.png"),true);
472     SDL_SetColorKey(uiGraphic[UI_SendToRepairIcon][HOUSE_HARKONNEN], SDL_TRUE, 0);
473 
474     uiGraphic[UI_CreditsDigits][HOUSE_HARKONNEN] = shapes->getPictureArray(10,1,2|TILE_NORMAL,3|TILE_NORMAL,4|TILE_NORMAL,5|TILE_NORMAL,6|TILE_NORMAL,
475                                                                                 7|TILE_NORMAL,8|TILE_NORMAL,9|TILE_NORMAL,10|TILE_NORMAL,11|TILE_NORMAL);
476     uiGraphic[UI_SideBar][HOUSE_HARKONNEN] = PicFactory->createSideBar(false);
477     uiGraphic[UI_Indicator][HOUSE_HARKONNEN] = units1->getPictureArray(3,1,8|TILE_NORMAL,9|TILE_NORMAL,10|TILE_NORMAL);
478     SDL_SetColorKey(uiGraphic[UI_Indicator][HOUSE_HARKONNEN], SDL_TRUE, 0);
479     uiGraphic[UI_InvalidPlace_Zoomlevel0][HOUSE_HARKONNEN] = PicFactory->createPlacingGrid(16, PALCOLOR_LIGHTRED);
480     uiGraphic[UI_InvalidPlace_Zoomlevel1][HOUSE_HARKONNEN] = PicFactory->createPlacingGrid(32, PALCOLOR_LIGHTRED);
481     uiGraphic[UI_InvalidPlace_Zoomlevel2][HOUSE_HARKONNEN] = PicFactory->createPlacingGrid(48, PALCOLOR_LIGHTRED);
482     uiGraphic[UI_ValidPlace_Zoomlevel0][HOUSE_HARKONNEN] = PicFactory->createPlacingGrid(16, PALCOLOR_LIGHTGREEN);
483     uiGraphic[UI_ValidPlace_Zoomlevel1][HOUSE_HARKONNEN] = PicFactory->createPlacingGrid(32, PALCOLOR_LIGHTGREEN);
484     uiGraphic[UI_ValidPlace_Zoomlevel2][HOUSE_HARKONNEN] = PicFactory->createPlacingGrid(48, PALCOLOR_LIGHTGREEN);
485     uiGraphic[UI_GreyPlace_Zoomlevel0][HOUSE_HARKONNEN] = PicFactory->createPlacingGrid(16, PALCOLOR_LIGHTGREY);
486     uiGraphic[UI_GreyPlace_Zoomlevel1][HOUSE_HARKONNEN] = PicFactory->createPlacingGrid(32, PALCOLOR_LIGHTGREY);
487     uiGraphic[UI_GreyPlace_Zoomlevel2][HOUSE_HARKONNEN] = PicFactory->createPlacingGrid(48, PALCOLOR_LIGHTGREY);
488     uiGraphic[UI_MenuBackground][HOUSE_HARKONNEN] = PicFactory->createMainBackground();
489     uiGraphic[UI_GameStatsBackground][HOUSE_HARKONNEN] = PicFactory->createGameStatsBackground(HOUSE_HARKONNEN);
490     uiGraphic[UI_GameStatsBackground][HOUSE_ATREIDES] = PicFactory->createGameStatsBackground(HOUSE_ATREIDES);
491     uiGraphic[UI_GameStatsBackground][HOUSE_ORDOS] = PicFactory->createGameStatsBackground(HOUSE_ORDOS);
492     uiGraphic[UI_GameStatsBackground][HOUSE_FREMEN] = PicFactory->createGameStatsBackground(HOUSE_FREMEN);
493     uiGraphic[UI_GameStatsBackground][HOUSE_SARDAUKAR] = PicFactory->createGameStatsBackground(HOUSE_SARDAUKAR);
494     uiGraphic[UI_GameStatsBackground][HOUSE_MERCENARY] = PicFactory->createGameStatsBackground(HOUSE_MERCENARY);
495     uiGraphic[UI_SelectionBox_Zoomlevel0][HOUSE_HARKONNEN] = LoadPNG_RW(pFileManager->openFile("UI_SelectionBox.png"),true);
496     SDL_SetColorKey(uiGraphic[UI_SelectionBox_Zoomlevel0][HOUSE_HARKONNEN], SDL_TRUE, 0);
497     uiGraphic[UI_SelectionBox_Zoomlevel1][HOUSE_HARKONNEN] = Scaler::defaultDoubleTiledSurface(uiGraphic[UI_SelectionBox_Zoomlevel0][HOUSE_HARKONNEN], 1, 1, false);
498     SDL_SetColorKey(uiGraphic[UI_SelectionBox_Zoomlevel1][HOUSE_HARKONNEN], SDL_TRUE, 0);
499     uiGraphic[UI_SelectionBox_Zoomlevel2][HOUSE_HARKONNEN] = Scaler::defaultTripleTiledSurface(uiGraphic[UI_SelectionBox_Zoomlevel0][HOUSE_HARKONNEN], 1, 1, false);
500     SDL_SetColorKey(uiGraphic[UI_SelectionBox_Zoomlevel2][HOUSE_HARKONNEN], SDL_TRUE, 0);
501     uiGraphic[UI_OtherPlayerSelectionBox_Zoomlevel0][HOUSE_HARKONNEN] = LoadPNG_RW(pFileManager->openFile("UI_OtherPlayerSelectionBox.png"),true);
502     SDL_SetColorKey(uiGraphic[UI_OtherPlayerSelectionBox_Zoomlevel0][HOUSE_HARKONNEN], SDL_TRUE, 0);
503     uiGraphic[UI_OtherPlayerSelectionBox_Zoomlevel1][HOUSE_HARKONNEN] = Scaler::defaultDoubleTiledSurface(uiGraphic[UI_OtherPlayerSelectionBox_Zoomlevel0][HOUSE_HARKONNEN], 1, 1, false);
504     SDL_SetColorKey(uiGraphic[UI_OtherPlayerSelectionBox_Zoomlevel1][HOUSE_HARKONNEN], SDL_TRUE, 0);
505     uiGraphic[UI_OtherPlayerSelectionBox_Zoomlevel2][HOUSE_HARKONNEN] = Scaler::defaultTripleTiledSurface(uiGraphic[UI_OtherPlayerSelectionBox_Zoomlevel0][HOUSE_HARKONNEN], 1, 1, false);
506     SDL_SetColorKey(uiGraphic[UI_OtherPlayerSelectionBox_Zoomlevel2][HOUSE_HARKONNEN], SDL_TRUE, 0);
507     uiGraphic[UI_TopBar][HOUSE_HARKONNEN] = PicFactory->createTopBar();
508     uiGraphic[UI_ButtonUp][HOUSE_HARKONNEN] = choam->getPicture(0);
509     uiGraphic[UI_ButtonUp_Pressed][HOUSE_HARKONNEN] = choam->getPicture(1);
510     uiGraphic[UI_ButtonDown][HOUSE_HARKONNEN] = choam->getPicture(2);
511     uiGraphic[UI_ButtonDown_Pressed][HOUSE_HARKONNEN] = choam->getPicture(3);
512     uiGraphic[UI_BuilderListUpperCap][HOUSE_HARKONNEN] = PicFactory->createBuilderListUpperCap();
513     uiGraphic[UI_BuilderListLowerCap][HOUSE_HARKONNEN] = PicFactory->createBuilderListLowerCap();
514     uiGraphic[UI_CustomGamePlayersArrow][HOUSE_HARKONNEN] = LoadPNG_RW(pFileManager->openFile("CustomGamePlayers_Arrow.png"),true);
515     SDL_SetColorKey(uiGraphic[UI_CustomGamePlayersArrow][HOUSE_HARKONNEN], SDL_TRUE, 0);
516     uiGraphic[UI_CustomGamePlayersArrowNeutral][HOUSE_HARKONNEN] = LoadPNG_RW(pFileManager->openFile("CustomGamePlayers_ArrowNeutral.png"),true);
517     SDL_SetColorKey(uiGraphic[UI_CustomGamePlayersArrowNeutral][HOUSE_HARKONNEN], SDL_TRUE, 0);
518     uiGraphic[UI_MessageBox][HOUSE_HARKONNEN] = PicFactory->createMessageBoxBorder();
519 
520     if(bttn.get() != nullptr) {
521         uiGraphic[UI_Mentat][HOUSE_HARKONNEN] = bttn->getPicture(0);
522         uiGraphic[UI_Mentat_Pressed][HOUSE_HARKONNEN] = bttn->getPicture(1);
523         uiGraphic[UI_Options][HOUSE_HARKONNEN] = bttn->getPicture(2);
524         uiGraphic[UI_Options_Pressed][HOUSE_HARKONNEN] = bttn->getPicture(3);
525     } else {
526         uiGraphic[UI_Mentat][HOUSE_HARKONNEN] = shapes->getPicture(94);
527         uiGraphic[UI_Mentat_Pressed][HOUSE_HARKONNEN] = shapes->getPicture(95);
528         uiGraphic[UI_Options][HOUSE_HARKONNEN] = shapes->getPicture(96);
529         uiGraphic[UI_Options_Pressed][HOUSE_HARKONNEN] = shapes->getPicture(97);
530     }
531 
532     uiGraphic[UI_Upgrade][HOUSE_HARKONNEN] = choam->getPicture(4);
533     SDL_SetColorKey(uiGraphic[UI_Upgrade][HOUSE_HARKONNEN], SDL_TRUE, 0);
534     uiGraphic[UI_Upgrade_Pressed][HOUSE_HARKONNEN] = choam->getPicture(5);
535     SDL_SetColorKey(uiGraphic[UI_Upgrade_Pressed][HOUSE_HARKONNEN], SDL_TRUE, 0);
536     uiGraphic[UI_Repair][HOUSE_HARKONNEN] = LoadPNG_RW(pFileManager->openFile("Button_Repair.png"),true);
537     uiGraphic[UI_Repair_Pressed][HOUSE_HARKONNEN] = LoadPNG_RW(pFileManager->openFile("Button_RepairPushed.png"),true);
538     uiGraphic[UI_Minus][HOUSE_HARKONNEN] = LoadPNG_RW(pFileManager->openFile("Button_Minus.png"),true);
539     uiGraphic[UI_Minus_Active][HOUSE_HARKONNEN] = mapSurfaceColorRange(uiGraphic[UI_Minus][HOUSE_HARKONNEN], PALCOLOR_HARKONNEN, PALCOLOR_HARKONNEN-2);
540     uiGraphic[UI_Minus_Pressed][HOUSE_HARKONNEN] = LoadPNG_RW(pFileManager->openFile("Button_MinusPushed.png"),true);
541     uiGraphic[UI_Plus][HOUSE_HARKONNEN] = LoadPNG_RW(pFileManager->openFile("Button_Plus.png"),true);
542     uiGraphic[UI_Plus_Active][HOUSE_HARKONNEN] = mapSurfaceColorRange(uiGraphic[UI_Plus][HOUSE_HARKONNEN], PALCOLOR_HARKONNEN, PALCOLOR_HARKONNEN-2);
543     uiGraphic[UI_Plus_Pressed][HOUSE_HARKONNEN] = LoadPNG_RW(pFileManager->openFile("Button_PlusPushed.png"),true);
544     uiGraphic[UI_MissionSelect][HOUSE_HARKONNEN] = LoadPNG_RW(pFileManager->openFile("Menu_MissionSelect.png"),true);
545     PicFactory->drawFrame(uiGraphic[UI_MissionSelect][HOUSE_HARKONNEN],PictureFactory::SimpleFrame,nullptr);
546     SDL_SetColorKey(uiGraphic[UI_MissionSelect][HOUSE_HARKONNEN], SDL_TRUE, 0);
547     uiGraphic[UI_OptionsMenu][HOUSE_HARKONNEN] = PicFactory->createOptionsMenu();
548     uiGraphic[UI_LoadSaveWindow][HOUSE_HARKONNEN] = PicFactory->createMenu(280,228);
549     uiGraphic[UI_NewMapWindow][HOUSE_HARKONNEN] = PicFactory->createMenu(600,440);
550     uiGraphic[UI_DuneLegacy][HOUSE_HARKONNEN] = LoadPNG_RW(pFileManager->openFile("DuneLegacy.png"),true);
551     uiGraphic[UI_GameMenu][HOUSE_HARKONNEN] = PicFactory->createMenu(uiGraphic[UI_DuneLegacy][HOUSE_HARKONNEN],158);
552     PicFactory->drawFrame(uiGraphic[UI_DuneLegacy][HOUSE_HARKONNEN],PictureFactory::SimpleFrame);
553 
554     uiGraphic[UI_PlanetBackground][HOUSE_HARKONNEN] = LoadCPS_RW(pFileManager->openFile("BIGPLAN.CPS"),true);
555     PicFactory->drawFrame(uiGraphic[UI_PlanetBackground][HOUSE_HARKONNEN],PictureFactory::SimpleFrame);
556     uiGraphic[UI_MenuButtonBorder][HOUSE_HARKONNEN] = PicFactory->createFrame(PictureFactory::DecorationFrame1,190,123,false);
557 
558     PicFactory->drawFrame(uiGraphic[UI_DuneLegacy][HOUSE_HARKONNEN],PictureFactory::SimpleFrame);
559 
560     uiGraphic[UI_MentatBackground][HOUSE_HARKONNEN] = Scaler::defaultDoubleSurface(LoadCPS_RW(pFileManager->openFile("MENTATH.CPS"),true),true);
561     uiGraphic[UI_MentatBackground][HOUSE_ATREIDES] = Scaler::defaultDoubleSurface(LoadCPS_RW(pFileManager->openFile("MENTATA.CPS"),true),true);
562     uiGraphic[UI_MentatBackground][HOUSE_ORDOS] = Scaler::defaultDoubleSurface(LoadCPS_RW(pFileManager->openFile("MENTATO.CPS"),true),true);
563     uiGraphic[UI_MentatBackground][HOUSE_FREMEN] = PictureFactory::mapMentatSurfaceToFremen(uiGraphic[UI_MentatBackground][HOUSE_ATREIDES]);
564     uiGraphic[UI_MentatBackground][HOUSE_SARDAUKAR] = PictureFactory::mapMentatSurfaceToSardaukar(uiGraphic[UI_MentatBackground][HOUSE_HARKONNEN]);
565     uiGraphic[UI_MentatBackground][HOUSE_MERCENARY] = PictureFactory::mapMentatSurfaceToMercenary(uiGraphic[UI_MentatBackground][HOUSE_ORDOS]);
566 
567     uiGraphic[UI_MentatBackgroundBene][HOUSE_HARKONNEN] = Scaler::defaultDoubleSurface(LoadCPS_RW(pFileManager->openFile("MENTATM.CPS"),true),true);
568     if(uiGraphic[UI_MentatBackgroundBene][HOUSE_HARKONNEN] != nullptr) {
569         benePalette.applyToSurface(uiGraphic[UI_MentatBackgroundBene][HOUSE_HARKONNEN]);
570     }
571 
572     uiGraphic[UI_MentatHouseChoiceInfoQuestion][HOUSE_HARKONNEN] = PicFactory->createMentatHouseChoiceQuestion(HOUSE_HARKONNEN, benePalette);
573     uiGraphic[UI_MentatHouseChoiceInfoQuestion][HOUSE_ATREIDES] = PicFactory->createMentatHouseChoiceQuestion(HOUSE_ATREIDES, benePalette);
574     uiGraphic[UI_MentatHouseChoiceInfoQuestion][HOUSE_ORDOS] = PicFactory->createMentatHouseChoiceQuestion(HOUSE_ORDOS, benePalette);
575     uiGraphic[UI_MentatHouseChoiceInfoQuestion][HOUSE_SARDAUKAR] = PicFactory->createMentatHouseChoiceQuestion(HOUSE_SARDAUKAR, benePalette);
576     uiGraphic[UI_MentatHouseChoiceInfoQuestion][HOUSE_FREMEN] = PicFactory->createMentatHouseChoiceQuestion(HOUSE_FREMEN, benePalette);
577     uiGraphic[UI_MentatHouseChoiceInfoQuestion][HOUSE_MERCENARY] = PicFactory->createMentatHouseChoiceQuestion(HOUSE_MERCENARY, benePalette);
578 
579     uiGraphic[UI_MentatYes][HOUSE_HARKONNEN] = Scaler::defaultDoubleSurface(mentat->getPicture(0),true);
580     uiGraphic[UI_MentatYes_Pressed][HOUSE_HARKONNEN] = Scaler::defaultDoubleSurface(mentat->getPicture(1),true);
581     uiGraphic[UI_MentatNo][HOUSE_HARKONNEN] = Scaler::defaultDoubleSurface(mentat->getPicture(2),true);
582     uiGraphic[UI_MentatNo_Pressed][HOUSE_HARKONNEN] = Scaler::defaultDoubleSurface(mentat->getPicture(3),true);
583     uiGraphic[UI_MentatExit][HOUSE_HARKONNEN] = Scaler::defaultDoubleSurface(mentat->getPicture(4),true);
584     uiGraphic[UI_MentatExit_Pressed][HOUSE_HARKONNEN] = Scaler::defaultDoubleSurface(mentat->getPicture(5),true);
585     uiGraphic[UI_MentatProcced][HOUSE_HARKONNEN] = Scaler::defaultDoubleSurface(mentat->getPicture(6),true);
586     uiGraphic[UI_MentatProcced_Pressed][HOUSE_HARKONNEN] = Scaler::defaultDoubleSurface(mentat->getPicture(7),true);
587     uiGraphic[UI_MentatRepeat][HOUSE_HARKONNEN] = Scaler::defaultDoubleSurface(mentat->getPicture(8),true);
588     uiGraphic[UI_MentatRepeat_Pressed][HOUSE_HARKONNEN] = Scaler::defaultDoubleSurface(mentat->getPicture(9),true);
589 
590     SDL_Surface* pHouseChoiceBackground;
591     if(pFileManager->exists("HERALD." + _("LanguageFileExtension"))) {
592         pHouseChoiceBackground = LoadCPS_RW(pFileManager->openFile("HERALD." + _("LanguageFileExtension")),true);
593     } else {
594         pHouseChoiceBackground = LoadCPS_RW(pFileManager->openFile("HERALD.CPS"),true);
595     }
596 
597     uiGraphic[UI_HouseSelect][HOUSE_HARKONNEN] = PicFactory->createHouseSelect(pHouseChoiceBackground);
598     uiGraphic[UI_SelectYourHouseLarge][HOUSE_HARKONNEN] = Scaler::defaultDoubleSurface(getSubPicture(pHouseChoiceBackground, 0, 0, 320, 50), true);
599     uiGraphic[UI_Herald_Colored][HOUSE_ATREIDES] = getSubPicture(pHouseChoiceBackground,20,54,83,91);
600     uiGraphic[UI_Herald_ColoredLarge][HOUSE_ATREIDES] = Scaler::defaultDoubleSurface(uiGraphic[UI_Herald_Colored][HOUSE_ATREIDES], false);
601     uiGraphic[UI_Herald_Colored][HOUSE_ORDOS] = getSubPicture(pHouseChoiceBackground,117,54,83,91);
602     uiGraphic[UI_Herald_ColoredLarge][HOUSE_ORDOS] = Scaler::defaultDoubleSurface(uiGraphic[UI_Herald_Colored][HOUSE_ORDOS], false);
603     uiGraphic[UI_Herald_Colored][HOUSE_HARKONNEN] = getSubPicture(pHouseChoiceBackground,215,54,83,91);
604     uiGraphic[UI_Herald_ColoredLarge][HOUSE_HARKONNEN] = Scaler::defaultDoubleSurface(uiGraphic[UI_Herald_Colored][HOUSE_HARKONNEN], false);
605     uiGraphic[UI_Herald_Colored][HOUSE_FREMEN] = PicFactory->createHeraldFre(uiGraphic[UI_Herald_Colored][HOUSE_HARKONNEN]);
606     uiGraphic[UI_Herald_ColoredLarge][HOUSE_FREMEN] = Scaler::defaultDoubleSurface(uiGraphic[UI_Herald_Colored][HOUSE_FREMEN], false);
607     uiGraphic[UI_Herald_Colored][HOUSE_SARDAUKAR] = PicFactory->createHeraldSard(uiGraphic[UI_Herald_Colored][HOUSE_ORDOS], uiGraphic[UI_Herald_Colored][HOUSE_ATREIDES]);
608     uiGraphic[UI_Herald_ColoredLarge][HOUSE_SARDAUKAR] = Scaler::defaultDoubleSurface(uiGraphic[UI_Herald_Colored][HOUSE_SARDAUKAR], false);
609     uiGraphic[UI_Herald_Colored][HOUSE_MERCENARY] = PicFactory->createHeraldMerc(uiGraphic[UI_Herald_Colored][HOUSE_ATREIDES], uiGraphic[UI_Herald_Colored][HOUSE_ORDOS]);
610     uiGraphic[UI_Herald_ColoredLarge][HOUSE_MERCENARY] = Scaler::defaultDoubleSurface(uiGraphic[UI_Herald_Colored][HOUSE_MERCENARY], false);
611 
612     SDL_FreeSurface(pHouseChoiceBackground);
613 
614     uiGraphic[UI_Herald_Grey][HOUSE_HARKONNEN] = PicFactory->createGreyHouseChoice(uiGraphic[UI_Herald_Colored][HOUSE_HARKONNEN]);
615     uiGraphic[UI_Herald_Grey][HOUSE_ATREIDES] = PicFactory->createGreyHouseChoice(uiGraphic[UI_Herald_Colored][HOUSE_ATREIDES]);
616     uiGraphic[UI_Herald_Grey][HOUSE_ORDOS] = PicFactory->createGreyHouseChoice(uiGraphic[UI_Herald_Colored][HOUSE_ORDOS]);
617     uiGraphic[UI_Herald_Grey][HOUSE_FREMEN] = PicFactory->createGreyHouseChoice(uiGraphic[UI_Herald_Colored][HOUSE_FREMEN]);
618     uiGraphic[UI_Herald_Grey][HOUSE_SARDAUKAR] = PicFactory->createGreyHouseChoice(uiGraphic[UI_Herald_Colored][HOUSE_SARDAUKAR]);
619     uiGraphic[UI_Herald_Grey][HOUSE_MERCENARY] = PicFactory->createGreyHouseChoice(uiGraphic[UI_Herald_Colored][HOUSE_MERCENARY]);
620 
621     uiGraphic[UI_Herald_ArrowLeft][HOUSE_HARKONNEN] = LoadPNG_RW(pFileManager->openFile("ArrowLeft.png"),true);
622     uiGraphic[UI_Herald_ArrowLeftLarge][HOUSE_HARKONNEN] = Scaler::defaultDoubleSurface(uiGraphic[UI_Herald_ArrowLeft][HOUSE_HARKONNEN], false);
623     uiGraphic[UI_Herald_ArrowLeftHighlight][HOUSE_HARKONNEN] = LoadPNG_RW(pFileManager->openFile("ArrowLeftHighlight.png"),true);
624     uiGraphic[UI_Herald_ArrowLeftHighlightLarge][HOUSE_HARKONNEN] = Scaler::defaultDoubleSurface(uiGraphic[UI_Herald_ArrowLeftHighlight][HOUSE_HARKONNEN], false);
625     uiGraphic[UI_Herald_ArrowRight][HOUSE_HARKONNEN] = LoadPNG_RW(pFileManager->openFile("ArrowRight.png"),true);
626     uiGraphic[UI_Herald_ArrowRightLarge][HOUSE_HARKONNEN] = Scaler::defaultDoubleSurface(uiGraphic[UI_Herald_ArrowRight][HOUSE_HARKONNEN], false);
627     uiGraphic[UI_Herald_ArrowRightHighlight][HOUSE_HARKONNEN] = LoadPNG_RW(pFileManager->openFile("ArrowRightHighlight.png"),true);
628     uiGraphic[UI_Herald_ArrowRightHighlightLarge][HOUSE_HARKONNEN] = Scaler::defaultDoubleSurface(uiGraphic[UI_Herald_ArrowRightHighlight][HOUSE_HARKONNEN], false);
629 
630     uiGraphic[UI_MapChoiceScreen][HOUSE_HARKONNEN] = PicFactory->createMapChoiceScreen(HOUSE_HARKONNEN);
631     uiGraphic[UI_MapChoiceScreen][HOUSE_ATREIDES] = PicFactory->createMapChoiceScreen(HOUSE_ATREIDES);
632     uiGraphic[UI_MapChoiceScreen][HOUSE_ORDOS] = PicFactory->createMapChoiceScreen(HOUSE_ORDOS);
633     uiGraphic[UI_MapChoiceScreen][HOUSE_FREMEN] = PicFactory->createMapChoiceScreen(HOUSE_FREMEN);
634     uiGraphic[UI_MapChoiceScreen][HOUSE_SARDAUKAR] = PicFactory->createMapChoiceScreen(HOUSE_SARDAUKAR);
635     uiGraphic[UI_MapChoiceScreen][HOUSE_MERCENARY] = PicFactory->createMapChoiceScreen(HOUSE_MERCENARY);
636     uiGraphic[UI_MapChoicePlanet][HOUSE_HARKONNEN] = Scaler::doubleSurfaceNN(LoadCPS_RW(pFileManager->openFile("PLANET.CPS"),true));
637     SDL_SetColorKey(uiGraphic[UI_MapChoicePlanet][HOUSE_HARKONNEN], SDL_TRUE, 0);
638     uiGraphic[UI_MapChoiceMapOnly][HOUSE_HARKONNEN] = Scaler::doubleSurfaceNN(LoadCPS_RW(pFileManager->openFile("DUNEMAP.CPS"),true));
639     SDL_SetColorKey(uiGraphic[UI_MapChoiceMapOnly][HOUSE_HARKONNEN], SDL_TRUE, 0);
640     uiGraphic[UI_MapChoiceMap][HOUSE_HARKONNEN] = Scaler::doubleSurfaceNN(LoadCPS_RW(pFileManager->openFile("DUNERGN.CPS"),true));
641     SDL_SetColorKey(uiGraphic[UI_MapChoiceMap][HOUSE_HARKONNEN], SDL_TRUE, 0);
642 
643     // make black lines inside the map non-transparent
644     if(!SDL_MUSTLOCK(uiGraphic[UI_MapChoiceMap][HOUSE_HARKONNEN]) || (SDL_LockSurface(uiGraphic[UI_MapChoiceMap][HOUSE_HARKONNEN]) == 0)) {
645         for(int y = 48; y < 48+240; y++) {
646             for(int x = 16; x < 16 + 608; x++) {
647                 if(getPixel(uiGraphic[UI_MapChoiceMap][HOUSE_HARKONNEN], x, y) == 0) {
648                     putPixel(uiGraphic[UI_MapChoiceMap][HOUSE_HARKONNEN], x, y, PALCOLOR_BLACK);
649                 }
650             }
651         }
652 
653         if(SDL_MUSTLOCK(uiGraphic[UI_MapChoiceMap][HOUSE_HARKONNEN])) {
654             SDL_UnlockSurface(uiGraphic[UI_MapChoiceMap][HOUSE_HARKONNEN]);
655         }
656     }
657 
658     uiGraphic[UI_MapChoiceClickMap][HOUSE_HARKONNEN] = Scaler::doubleSurfaceNN(LoadCPS_RW(pFileManager->openFile("RGNCLK.CPS"),true));
659     uiGraphic[UI_MapChoiceArrow_None][HOUSE_HARKONNEN] = Scaler::defaultDoubleSurface(arrows->getPicture(0),true);
660     SDL_SetColorKey(uiGraphic[UI_MapChoiceArrow_None][HOUSE_HARKONNEN], SDL_TRUE, 0);
661     uiGraphic[UI_MapChoiceArrow_LeftUp][HOUSE_HARKONNEN] = Scaler::defaultDoubleSurface(arrows->getPicture(1),true);
662     SDL_SetColorKey(uiGraphic[UI_MapChoiceArrow_LeftUp][HOUSE_HARKONNEN], SDL_TRUE, 0);
663     uiGraphic[UI_MapChoiceArrow_Up][HOUSE_HARKONNEN] = Scaler::defaultDoubleSurface(arrows->getPicture(2),true);
664     SDL_SetColorKey(uiGraphic[UI_MapChoiceArrow_Up][HOUSE_HARKONNEN], SDL_TRUE, 0);
665     uiGraphic[UI_MapChoiceArrow_RightUp][HOUSE_HARKONNEN] = Scaler::defaultDoubleSurface(arrows->getPicture(3),true);
666     SDL_SetColorKey(uiGraphic[UI_MapChoiceArrow_RightUp][HOUSE_HARKONNEN], SDL_TRUE, 0);
667     uiGraphic[UI_MapChoiceArrow_Right][HOUSE_HARKONNEN] = Scaler::defaultDoubleSurface(arrows->getPicture(4),true);
668     SDL_SetColorKey(uiGraphic[UI_MapChoiceArrow_Right][HOUSE_HARKONNEN], SDL_TRUE, 0);
669     uiGraphic[UI_MapChoiceArrow_RightDown][HOUSE_HARKONNEN] = Scaler::defaultDoubleSurface(arrows->getPicture(5),true);
670     SDL_SetColorKey(uiGraphic[UI_MapChoiceArrow_RightDown][HOUSE_HARKONNEN], SDL_TRUE, 0);
671     uiGraphic[UI_MapChoiceArrow_Down][HOUSE_HARKONNEN] = Scaler::defaultDoubleSurface(arrows->getPicture(6),true);
672     SDL_SetColorKey(uiGraphic[UI_MapChoiceArrow_Down][HOUSE_HARKONNEN], SDL_TRUE, 0);
673     uiGraphic[UI_MapChoiceArrow_LeftDown][HOUSE_HARKONNEN] = Scaler::defaultDoubleSurface(arrows->getPicture(7),true);
674     SDL_SetColorKey(uiGraphic[UI_MapChoiceArrow_LeftDown][HOUSE_HARKONNEN], SDL_TRUE, 0);
675     uiGraphic[UI_MapChoiceArrow_Left][HOUSE_HARKONNEN] = Scaler::defaultDoubleSurface(arrows->getPicture(8),true);
676     SDL_SetColorKey(uiGraphic[UI_MapChoiceArrow_Left][HOUSE_HARKONNEN], SDL_TRUE, 0);
677 
678     uiGraphic[UI_StructureSizeLattice][HOUSE_HARKONNEN] = LoadPNG_RW(pFileManager->openFile("StructureSizeLattice.png"),true);
679     SDL_SetColorKey(uiGraphic[UI_StructureSizeLattice][HOUSE_HARKONNEN], SDL_TRUE, 0);
680     uiGraphic[UI_StructureSizeConcrete][HOUSE_HARKONNEN] = LoadPNG_RW(pFileManager->openFile("StructureSizeConcrete.png"),true);
681     SDL_SetColorKey(uiGraphic[UI_StructureSizeConcrete][HOUSE_HARKONNEN], SDL_TRUE, 0);
682 
683     uiGraphic[UI_MapEditor_SideBar][HOUSE_HARKONNEN] = PicFactory->createSideBar(true);
684     uiGraphic[UI_MapEditor_BottomBar][HOUSE_HARKONNEN] = PicFactory->createBottomBar();
685 
686     uiGraphic[UI_MapEditor_ExitIcon][HOUSE_HARKONNEN] = LoadPNG_RW(pFileManager->openFile("MapEditorExitIcon.png"),true);
687     SDL_SetColorKey(uiGraphic[UI_MapEditor_ExitIcon][HOUSE_HARKONNEN], SDL_TRUE, 0);
688     uiGraphic[UI_MapEditor_NewIcon][HOUSE_HARKONNEN] = LoadPNG_RW(pFileManager->openFile("MapEditorNewIcon.png"),true);
689     SDL_SetColorKey(uiGraphic[UI_MapEditor_NewIcon][HOUSE_HARKONNEN], SDL_TRUE, 0);
690     uiGraphic[UI_MapEditor_LoadIcon][HOUSE_HARKONNEN] = LoadPNG_RW(pFileManager->openFile("MapEditorLoadIcon.png"),true);
691     SDL_SetColorKey(uiGraphic[UI_MapEditor_LoadIcon][HOUSE_HARKONNEN], SDL_TRUE, 0);
692     uiGraphic[UI_MapEditor_SaveIcon][HOUSE_HARKONNEN] = LoadPNG_RW(pFileManager->openFile("MapEditorSaveIcon.png"),true);
693     SDL_SetColorKey(uiGraphic[UI_MapEditor_SaveIcon][HOUSE_HARKONNEN], SDL_TRUE, 0);
694     uiGraphic[UI_MapEditor_UndoIcon][HOUSE_HARKONNEN] = LoadPNG_RW(pFileManager->openFile("MapEditorUndoIcon.png"),true);
695     SDL_SetColorKey(uiGraphic[UI_MapEditor_UndoIcon][HOUSE_HARKONNEN], SDL_TRUE, 0);
696     uiGraphic[UI_MapEditor_RedoIcon][HOUSE_HARKONNEN] = LoadPNG_RW(pFileManager->openFile("MapEditorRedoIcon.png"),true);
697     SDL_SetColorKey(uiGraphic[UI_MapEditor_RedoIcon][HOUSE_HARKONNEN], SDL_TRUE, 0);
698     uiGraphic[UI_MapEditor_PlayerIcon][HOUSE_HARKONNEN] = LoadPNG_RW(pFileManager->openFile("MapEditorPlayerIcon.png"),true);
699     SDL_SetColorKey(uiGraphic[UI_MapEditor_PlayerIcon][HOUSE_HARKONNEN], SDL_TRUE, 0);
700     uiGraphic[UI_MapEditor_MapSettingsIcon][HOUSE_HARKONNEN] = LoadPNG_RW(pFileManager->openFile("MapEditorMapSettingsIcon.png"),true);
701     SDL_SetColorKey(uiGraphic[UI_MapEditor_MapSettingsIcon][HOUSE_HARKONNEN], SDL_TRUE, 0);
702     uiGraphic[UI_MapEditor_ChoamIcon][HOUSE_HARKONNEN] = scaleSurface(getSubFrame(objPic[ObjPic_Frigate][HOUSE_HARKONNEN][0],1,0,8,1), 0.5);
703     SDL_SetColorKey(uiGraphic[UI_MapEditor_ChoamIcon][HOUSE_HARKONNEN], SDL_TRUE, 0);
704     uiGraphic[UI_MapEditor_ReinforcementsIcon][HOUSE_HARKONNEN] = scaleSurface(getSubFrame(objPic[ObjPic_Carryall][HOUSE_HARKONNEN][0],1,0,8,2), 0.66667);
705     SDL_SetColorKey(uiGraphic[UI_MapEditor_ReinforcementsIcon][HOUSE_HARKONNEN], SDL_TRUE, 0);
706     uiGraphic[UI_MapEditor_TeamsIcon][HOUSE_HARKONNEN] = getSubFrame(objPic[ObjPic_Troopers][HOUSE_HARKONNEN][0],0,0,4,4);
707     SDL_SetColorKey(uiGraphic[UI_MapEditor_TeamsIcon][HOUSE_HARKONNEN], SDL_TRUE, 0);
708     uiGraphic[UI_MapEditor_MirrorNoneIcon][HOUSE_HARKONNEN] = LoadPNG_RW(pFileManager->openFile("MapEditorMirrorNone.png"),true);
709     SDL_SetColorKey(uiGraphic[UI_MapEditor_MirrorNoneIcon][HOUSE_HARKONNEN], SDL_TRUE, 0);
710     uiGraphic[UI_MapEditor_MirrorHorizontalIcon][HOUSE_HARKONNEN] = LoadPNG_RW(pFileManager->openFile("MapEditorMirrorHorizontal.png"),true);
711     SDL_SetColorKey(uiGraphic[UI_MapEditor_MirrorHorizontalIcon][HOUSE_HARKONNEN], SDL_TRUE, 0);
712     uiGraphic[UI_MapEditor_MirrorVerticalIcon][HOUSE_HARKONNEN] = LoadPNG_RW(pFileManager->openFile("MapEditorMirrorVertical.png"),true);
713     SDL_SetColorKey(uiGraphic[UI_MapEditor_MirrorVerticalIcon][HOUSE_HARKONNEN], SDL_TRUE, 0);
714     uiGraphic[UI_MapEditor_MirrorBothIcon][HOUSE_HARKONNEN] = LoadPNG_RW(pFileManager->openFile("MapEditorMirrorBoth.png"),true);
715     SDL_SetColorKey(uiGraphic[UI_MapEditor_MirrorBothIcon][HOUSE_HARKONNEN], SDL_TRUE, 0);
716     uiGraphic[UI_MapEditor_MirrorPointIcon][HOUSE_HARKONNEN] = LoadPNG_RW(pFileManager->openFile("MapEditorMirrorPoint.png"),true);
717     SDL_SetColorKey(uiGraphic[UI_MapEditor_MirrorPointIcon][HOUSE_HARKONNEN], SDL_TRUE, 0);
718     uiGraphic[UI_MapEditor_ArrowUp][HOUSE_HARKONNEN] = LoadPNG_RW(pFileManager->openFile("MapEditorArrowUp.png"),true);
719     SDL_SetColorKey(uiGraphic[UI_MapEditor_ArrowUp][HOUSE_HARKONNEN], SDL_TRUE, 0);
720     uiGraphic[UI_MapEditor_ArrowUp_Active][HOUSE_HARKONNEN] = mapSurfaceColorRange(uiGraphic[UI_MapEditor_ArrowUp][HOUSE_HARKONNEN], PALCOLOR_HARKONNEN, PALCOLOR_HARKONNEN-3);
721     uiGraphic[UI_MapEditor_ArrowDown][HOUSE_HARKONNEN] = LoadPNG_RW(pFileManager->openFile("MapEditorArrowDown.png"),true);
722     SDL_SetColorKey(uiGraphic[UI_MapEditor_ArrowDown][HOUSE_HARKONNEN], SDL_TRUE, 0);
723     uiGraphic[UI_MapEditor_ArrowDown_Active][HOUSE_HARKONNEN] = mapSurfaceColorRange(uiGraphic[UI_MapEditor_ArrowDown][HOUSE_HARKONNEN], PALCOLOR_HARKONNEN, PALCOLOR_HARKONNEN-3);
724     uiGraphic[UI_MapEditor_Plus][HOUSE_HARKONNEN] = LoadPNG_RW(pFileManager->openFile("MapEditorPlus.png"),true);
725     SDL_SetColorKey(uiGraphic[UI_MapEditor_Plus][HOUSE_HARKONNEN], SDL_TRUE, 0);
726     uiGraphic[UI_MapEditor_Plus_Active][HOUSE_HARKONNEN] = mapSurfaceColorRange(uiGraphic[UI_MapEditor_Plus][HOUSE_HARKONNEN], PALCOLOR_HARKONNEN, PALCOLOR_HARKONNEN-3);
727     uiGraphic[UI_MapEditor_Minus][HOUSE_HARKONNEN] = LoadPNG_RW(pFileManager->openFile("MapEditorMinus.png"),true);
728     SDL_SetColorKey(uiGraphic[UI_MapEditor_Minus][HOUSE_HARKONNEN], SDL_TRUE, 0);
729     uiGraphic[UI_MapEditor_Minus_Active][HOUSE_HARKONNEN] = mapSurfaceColorRange(uiGraphic[UI_MapEditor_Minus][HOUSE_HARKONNEN], PALCOLOR_HARKONNEN, PALCOLOR_HARKONNEN-3);
730     uiGraphic[UI_MapEditor_RotateLeftIcon][HOUSE_HARKONNEN] = LoadPNG_RW(pFileManager->openFile("MapEditorRotateLeft.png"),true);
731     SDL_SetColorKey(uiGraphic[UI_MapEditor_RotateLeftIcon][HOUSE_HARKONNEN], SDL_TRUE, 0);
732     uiGraphic[UI_MapEditor_RotateLeftHighlightIcon][HOUSE_HARKONNEN] = mapSurfaceColorRange(uiGraphic[UI_MapEditor_RotateLeftIcon][HOUSE_HARKONNEN], PALCOLOR_HARKONNEN, PALCOLOR_HARKONNEN-3);
733     SDL_SetColorKey(uiGraphic[UI_MapEditor_RotateLeftHighlightIcon][HOUSE_HARKONNEN], SDL_TRUE, 0);
734     uiGraphic[UI_MapEditor_RotateRightIcon][HOUSE_HARKONNEN] = LoadPNG_RW(pFileManager->openFile("MapEditorRotateRight.png"),true);
735     SDL_SetColorKey(uiGraphic[UI_MapEditor_RotateRightIcon][HOUSE_HARKONNEN], SDL_TRUE, 0);
736     uiGraphic[UI_MapEditor_RotateRightHighlightIcon][HOUSE_HARKONNEN] = mapSurfaceColorRange(uiGraphic[UI_MapEditor_RotateRightIcon][HOUSE_HARKONNEN], PALCOLOR_HARKONNEN, PALCOLOR_HARKONNEN-3);
737     SDL_SetColorKey(uiGraphic[UI_MapEditor_RotateRightHighlightIcon][HOUSE_HARKONNEN], SDL_TRUE, 0);
738 
739     uiGraphic[UI_MapEditor_Sand][HOUSE_HARKONNEN] = Scaler::defaultDoubleSurface(icon->getPicture(127),true);
740     uiGraphic[UI_MapEditor_Dunes][HOUSE_HARKONNEN] = Scaler::defaultDoubleSurface(icon->getPicture(159),true);
741     uiGraphic[UI_MapEditor_SpecialBloom][HOUSE_HARKONNEN] = Scaler::defaultDoubleSurface(icon->getPicture(209),true);
742     uiGraphic[UI_MapEditor_Spice][HOUSE_HARKONNEN] = Scaler::defaultDoubleSurface(icon->getPicture(191),true);
743     uiGraphic[UI_MapEditor_ThickSpice][HOUSE_HARKONNEN] = Scaler::defaultDoubleSurface(icon->getPicture(207),true);
744     uiGraphic[UI_MapEditor_SpiceBloom][HOUSE_HARKONNEN] = Scaler::defaultDoubleSurface(icon->getPicture(208),true);
745     uiGraphic[UI_MapEditor_Slab][HOUSE_HARKONNEN] = Scaler::defaultDoubleSurface(icon->getPicture(126),true);
746     uiGraphic[UI_MapEditor_Rock][HOUSE_HARKONNEN] = Scaler::defaultDoubleSurface(icon->getPicture(143),true);
747     uiGraphic[UI_MapEditor_Mountain][HOUSE_HARKONNEN] = Scaler::defaultDoubleSurface(icon->getPicture(175),true);
748 
749     uiGraphic[UI_MapEditor_Slab1][HOUSE_HARKONNEN] = icon->getPicture(126);
750     uiGraphic[UI_MapEditor_Wall][HOUSE_HARKONNEN] = getSubPicture(objPic[ObjPic_Wall][HOUSE_HARKONNEN][0],2*D2_TILESIZE,0,D2_TILESIZE,D2_TILESIZE);
751     uiGraphic[UI_MapEditor_GunTurret][HOUSE_HARKONNEN] = getSubPicture(objPic[ObjPic_GunTurret][HOUSE_HARKONNEN][0],2*D2_TILESIZE,0,D2_TILESIZE,D2_TILESIZE);
752     uiGraphic[UI_MapEditor_RocketTurret][HOUSE_HARKONNEN] = getSubPicture(objPic[ObjPic_RocketTurret][HOUSE_HARKONNEN][0],2*D2_TILESIZE,0,D2_TILESIZE,D2_TILESIZE);
753     uiGraphic[UI_MapEditor_ConstructionYard][HOUSE_HARKONNEN] = getSubPicture(objPic[ObjPic_ConstructionYard][HOUSE_HARKONNEN][0],2*2*D2_TILESIZE,0,2*D2_TILESIZE,2*D2_TILESIZE);
754     uiGraphic[UI_MapEditor_Windtrap][HOUSE_HARKONNEN] = getSubPicture(objPic[ObjPic_Windtrap][HOUSE_HARKONNEN][0],2*2*D2_TILESIZE,0,2*D2_TILESIZE,2*D2_TILESIZE);
755     SDL_Color windtrapColor = { 70, 70, 70, 255};
756     SDL_SetPaletteColors(uiGraphic[UI_MapEditor_Windtrap][HOUSE_HARKONNEN]->format->palette, &windtrapColor, PALCOLOR_WINDTRAP_COLORCYCLE, 1);
757     uiGraphic[UI_MapEditor_Radar][HOUSE_HARKONNEN] = getSubPicture(objPic[ObjPic_Radar][HOUSE_HARKONNEN][0],2*2*D2_TILESIZE,0,2*D2_TILESIZE,2*D2_TILESIZE);
758     uiGraphic[UI_MapEditor_Silo][HOUSE_HARKONNEN] = getSubPicture(objPic[ObjPic_Silo][HOUSE_HARKONNEN][0],2*2*D2_TILESIZE,0,2*D2_TILESIZE,2*D2_TILESIZE);
759     uiGraphic[UI_MapEditor_IX][HOUSE_HARKONNEN] = getSubPicture(objPic[ObjPic_IX][HOUSE_HARKONNEN][0],2*2*D2_TILESIZE,0,2*D2_TILESIZE,2*D2_TILESIZE);
760     uiGraphic[UI_MapEditor_Barracks][HOUSE_HARKONNEN] = getSubPicture(objPic[ObjPic_Barracks][HOUSE_HARKONNEN][0],2*2*D2_TILESIZE,0,2*D2_TILESIZE,2*D2_TILESIZE);
761     uiGraphic[UI_MapEditor_WOR][HOUSE_HARKONNEN] = getSubPicture(objPic[ObjPic_WOR][HOUSE_HARKONNEN][0],2*2*D2_TILESIZE,0,2*D2_TILESIZE,2*D2_TILESIZE);
762     uiGraphic[UI_MapEditor_LightFactory][HOUSE_HARKONNEN] = getSubPicture(objPic[ObjPic_LightFactory][HOUSE_HARKONNEN][0],2*2*D2_TILESIZE,0,2*D2_TILESIZE,2*D2_TILESIZE);
763     uiGraphic[UI_MapEditor_Refinery][HOUSE_HARKONNEN] = getSubPicture(objPic[ObjPic_Refinery][HOUSE_HARKONNEN][0],2*3*D2_TILESIZE,0,3*D2_TILESIZE,2*D2_TILESIZE);
764     uiGraphic[UI_MapEditor_HighTechFactory][HOUSE_HARKONNEN] = getSubPicture(objPic[ObjPic_HighTechFactory][HOUSE_HARKONNEN][0],2*3*D2_TILESIZE,0,3*D2_TILESIZE,2*D2_TILESIZE);
765     uiGraphic[UI_MapEditor_HeavyFactory][HOUSE_HARKONNEN] = getSubPicture(objPic[ObjPic_HeavyFactory][HOUSE_HARKONNEN][0],2*3*D2_TILESIZE,0,3*D2_TILESIZE,2*D2_TILESIZE);
766     uiGraphic[UI_MapEditor_RepairYard][HOUSE_HARKONNEN] = getSubPicture(objPic[ObjPic_RepairYard][HOUSE_HARKONNEN][0],2*3*D2_TILESIZE,0,3*D2_TILESIZE,2*D2_TILESIZE);
767     uiGraphic[UI_MapEditor_Starport][HOUSE_HARKONNEN] = getSubPicture(objPic[ObjPic_Starport][HOUSE_HARKONNEN][0],2*3*D2_TILESIZE,0,3*D2_TILESIZE,3*D2_TILESIZE);
768     uiGraphic[UI_MapEditor_Palace][HOUSE_HARKONNEN] = getSubPicture(objPic[ObjPic_Palace][HOUSE_HARKONNEN][0],2*3*D2_TILESIZE,0,3*D2_TILESIZE,3*D2_TILESIZE);
769 
770     uiGraphic[UI_MapEditor_Soldier][HOUSE_HARKONNEN] = getSubFrame(objPic[ObjPic_Soldier][HOUSE_HARKONNEN][0],0,0,4,3);
771     uiGraphic[UI_MapEditor_Trooper][HOUSE_HARKONNEN] = getSubFrame(objPic[ObjPic_Trooper][HOUSE_HARKONNEN][0],0,0,4,3);
772     uiGraphic[UI_MapEditor_Harvester][HOUSE_HARKONNEN] = getSubFrame(objPic[ObjPic_Harvester][HOUSE_HARKONNEN][0],0,0,8,1);
773     uiGraphic[UI_MapEditor_Infantry][HOUSE_HARKONNEN] = getSubFrame(objPic[ObjPic_Infantry][HOUSE_HARKONNEN][0],0,0,4,4);
774     uiGraphic[UI_MapEditor_Troopers][HOUSE_HARKONNEN] = getSubFrame(objPic[ObjPic_Troopers][HOUSE_HARKONNEN][0],0,0,4,4);
775     uiGraphic[UI_MapEditor_MCV][HOUSE_HARKONNEN] = getSubFrame(objPic[ObjPic_MCV][HOUSE_HARKONNEN][0],0,0,8,1);
776     uiGraphic[UI_MapEditor_Trike][HOUSE_HARKONNEN] = getSubFrame(objPic[ObjPic_Trike][HOUSE_HARKONNEN][0],0,0,8,1);
777     uiGraphic[UI_MapEditor_Raider][HOUSE_HARKONNEN] = getSubFrame(objPic[ObjPic_Trike][HOUSE_HARKONNEN][0],0,0,8,1);
778     uiGraphic[UI_MapEditor_Raider][HOUSE_HARKONNEN] = combinePictures(uiGraphic[UI_MapEditor_Raider][HOUSE_HARKONNEN], objPic[ObjPic_Star][HOUSE_HARKONNEN][1],
779                                                                       uiGraphic[UI_MapEditor_Raider][HOUSE_HARKONNEN]->w - objPic[ObjPic_Star][HOUSE_HARKONNEN][1]->w,
780                                                                       uiGraphic[UI_MapEditor_Raider][HOUSE_HARKONNEN]->h - objPic[ObjPic_Star][HOUSE_HARKONNEN][1]->h,
781                                                                       true, false);
782     uiGraphic[UI_MapEditor_Quad][HOUSE_HARKONNEN] = getSubFrame(objPic[ObjPic_Quad][HOUSE_HARKONNEN][0],0,0,8,1);
783     uiGraphic[UI_MapEditor_Tank][HOUSE_HARKONNEN] = combinePictures(getSubFrame(objPic[ObjPic_Tank_Base][HOUSE_HARKONNEN][0],0,0,8,1), getSubFrame(objPic[ObjPic_Tank_Gun][HOUSE_HARKONNEN][0],0,0,8,1), 0, 0);
784     uiGraphic[UI_MapEditor_SiegeTank][HOUSE_HARKONNEN] = combinePictures(getSubFrame(objPic[ObjPic_Siegetank_Base][HOUSE_HARKONNEN][0],0,0,8,1), getSubFrame(objPic[ObjPic_Siegetank_Gun][HOUSE_HARKONNEN][0],0,0,8,1), 2, -4);
785     uiGraphic[UI_MapEditor_Launcher][HOUSE_HARKONNEN] = combinePictures(getSubFrame(objPic[ObjPic_Tank_Base][HOUSE_HARKONNEN][0],0,0,8,1), getSubFrame(objPic[ObjPic_Launcher_Gun][HOUSE_HARKONNEN][0],0,0,8,1), 3, 0);
786     uiGraphic[UI_MapEditor_Devastator][HOUSE_HARKONNEN] = combinePictures(getSubFrame(objPic[ObjPic_Devastator_Base][HOUSE_HARKONNEN][0],0,0,8,1), getSubFrame(objPic[ObjPic_Devastator_Gun][HOUSE_HARKONNEN][0],0,0,8,1), 2, -4);
787     uiGraphic[UI_MapEditor_SonicTank][HOUSE_HARKONNEN] = combinePictures(getSubFrame(objPic[ObjPic_Tank_Base][HOUSE_HARKONNEN][0],0,0,8,1), getSubFrame(objPic[ObjPic_Sonictank_Gun][HOUSE_HARKONNEN][0],0,0,8,1), 3, 1);
788     uiGraphic[UI_MapEditor_Deviator][HOUSE_HARKONNEN] = combinePictures(getSubFrame(objPic[ObjPic_Tank_Base][HOUSE_HARKONNEN][0],0,0,8,1), getSubFrame(objPic[ObjPic_Launcher_Gun][HOUSE_HARKONNEN][0],0,0,8,1), 3, 0);
789     uiGraphic[UI_MapEditor_Deviator][HOUSE_HARKONNEN] = combinePictures(uiGraphic[UI_MapEditor_Deviator][HOUSE_HARKONNEN], objPic[ObjPic_Star][HOUSE_HARKONNEN][1],
790                                                                   uiGraphic[UI_MapEditor_Deviator][HOUSE_HARKONNEN]->w - objPic[ObjPic_Star][HOUSE_HARKONNEN][1]->w,
791                                                                   uiGraphic[UI_MapEditor_Deviator][HOUSE_HARKONNEN]->h - objPic[ObjPic_Star][HOUSE_HARKONNEN][1]->h,
792                                                                   true, false);
793     uiGraphic[UI_MapEditor_Saboteur][HOUSE_HARKONNEN] = getSubFrame(objPic[ObjPic_Saboteur][HOUSE_HARKONNEN][0],0,0,4,3);
794     uiGraphic[UI_MapEditor_Sandworm][HOUSE_HARKONNEN] = getSubFrame(objPic[ObjPic_Sandworm][HOUSE_HARKONNEN][0],0,5,1,9);
795     uiGraphic[UI_MapEditor_SpecialUnit][HOUSE_HARKONNEN] = combinePictures(getSubFrame(objPic[ObjPic_Devastator_Base][HOUSE_HARKONNEN][0],0,0,8,1), getSubFrame(objPic[ObjPic_Devastator_Gun][HOUSE_HARKONNEN][0],0,0,8,1), 2, -4);
796     uiGraphic[UI_MapEditor_SpecialUnit][HOUSE_HARKONNEN] = combinePictures(uiGraphic[UI_MapEditor_SpecialUnit][HOUSE_HARKONNEN], objPic[ObjPic_Star][HOUSE_HARKONNEN][1],
797                                                                   uiGraphic[UI_MapEditor_SpecialUnit][HOUSE_HARKONNEN]->w - objPic[ObjPic_Star][HOUSE_HARKONNEN][1]->w,
798                                                                   uiGraphic[UI_MapEditor_SpecialUnit][HOUSE_HARKONNEN]->h - objPic[ObjPic_Star][HOUSE_HARKONNEN][1]->h,
799                                                                   true, false);
800     uiGraphic[UI_MapEditor_Carryall][HOUSE_HARKONNEN] = getSubFrame(objPic[ObjPic_Carryall][HOUSE_HARKONNEN][0],0,0,8,2);
801     uiGraphic[UI_MapEditor_Ornithopter][HOUSE_HARKONNEN] = getSubFrame(objPic[ObjPic_Ornithopter][HOUSE_HARKONNEN][0],0,0,8,3);
802 
803     uiGraphic[UI_MapEditor_Pen1x1][HOUSE_HARKONNEN] = LoadPNG_RW(pFileManager->openFile("MapEditorPen1x1.png"),true);
804     SDL_SetColorKey(uiGraphic[UI_MapEditor_Pen1x1][HOUSE_HARKONNEN], SDL_TRUE, 0);
805     uiGraphic[UI_MapEditor_Pen3x3][HOUSE_HARKONNEN] = LoadPNG_RW(pFileManager->openFile("MapEditorPen3x3.png"),true);
806     SDL_SetColorKey(uiGraphic[UI_MapEditor_Pen3x3][HOUSE_HARKONNEN], SDL_TRUE, 0);
807     uiGraphic[UI_MapEditor_Pen5x5][HOUSE_HARKONNEN] = LoadPNG_RW(pFileManager->openFile("MapEditorPen5x5.png"),true);
808     SDL_SetColorKey(uiGraphic[UI_MapEditor_Pen5x5][HOUSE_HARKONNEN], SDL_TRUE, 0);
809 
810 
811 
812     // load animations
813     animation[Anim_HarkonnenEyes] = menshph->getAnimation(0,4,true,true);
814     animation[Anim_HarkonnenEyes]->setFrameRate(0.3);
815     animation[Anim_HarkonnenMouth] = menshph->getAnimation(5,9,true,true,true);
816     animation[Anim_HarkonnenMouth]->setFrameRate(5.0);
817     animation[Anim_HarkonnenShoulder] = menshph->getAnimation(10,10,true,true);
818     animation[Anim_HarkonnenShoulder]->setFrameRate(1.0);
819     animation[Anim_AtreidesEyes] = menshpa->getAnimation(0,4,true,true);
820     animation[Anim_AtreidesEyes]->setFrameRate(0.5);
821     animation[Anim_AtreidesMouth] = menshpa->getAnimation(5,9,true,true,true);
822     animation[Anim_AtreidesMouth]->setFrameRate(5.0);
823     animation[Anim_AtreidesShoulder] = menshpa->getAnimation(10,10,true,true);
824     animation[Anim_AtreidesShoulder]->setFrameRate(1.0);
825     animation[Anim_AtreidesBook] = menshpa->getAnimation(11,12,true,true,true);
826     animation[Anim_AtreidesBook]->setNumLoops(1);
827     animation[Anim_AtreidesBook]->setFrameRate(0.2);
828     animation[Anim_OrdosEyes] = menshpo->getAnimation(0,4,true,true);
829     animation[Anim_OrdosEyes]->setFrameRate(0.5);
830     animation[Anim_OrdosMouth] = menshpo->getAnimation(5,9,true,true,true);
831     animation[Anim_OrdosMouth]->setFrameRate(5.0);
832     animation[Anim_OrdosShoulder] = menshpo->getAnimation(10,10,true,true);
833     animation[Anim_OrdosShoulder]->setFrameRate(1.0);
834     animation[Anim_OrdosRing] = menshpo->getAnimation(11,14,true,true,true);
835     animation[Anim_OrdosRing]->setNumLoops(1);
836     animation[Anim_OrdosRing]->setFrameRate(6.0);
837     animation[Anim_FremenEyes] = PictureFactory::mapMentatAnimationToFremen(animation[Anim_AtreidesEyes]);
838     animation[Anim_FremenMouth] = PictureFactory::mapMentatAnimationToFremen(animation[Anim_AtreidesMouth]);
839     animation[Anim_FremenShoulder] = PictureFactory::mapMentatAnimationToFremen(animation[Anim_AtreidesShoulder]);
840     animation[Anim_FremenBook] = PictureFactory::mapMentatAnimationToFremen(animation[Anim_AtreidesBook]);
841     animation[Anim_SardaukarEyes] = PictureFactory::mapMentatAnimationToSardaukar(animation[Anim_HarkonnenEyes]);
842     animation[Anim_SardaukarMouth] = PictureFactory::mapMentatAnimationToSardaukar(animation[Anim_HarkonnenMouth]);
843     animation[Anim_SardaukarShoulder] = PictureFactory::mapMentatAnimationToSardaukar(animation[Anim_HarkonnenShoulder]);
844     animation[Anim_MercenaryEyes] = PictureFactory::mapMentatAnimationToMercenary(animation[Anim_OrdosEyes]);
845     animation[Anim_MercenaryMouth] = PictureFactory::mapMentatAnimationToMercenary(animation[Anim_OrdosMouth]);
846     animation[Anim_MercenaryShoulder] = PictureFactory::mapMentatAnimationToMercenary(animation[Anim_OrdosShoulder]);
847     animation[Anim_MercenaryRing] = PictureFactory::mapMentatAnimationToMercenary(animation[Anim_OrdosRing]);
848 
849     animation[Anim_BeneEyes] = menshpm->getAnimation(0,4,true,true);
850     if(animation[Anim_BeneEyes] != nullptr) {
851         animation[Anim_BeneEyes]->setPalette(benePalette);
852         animation[Anim_BeneEyes]->setFrameRate(0.5);
853     }
854     animation[Anim_BeneMouth] = menshpm->getAnimation(5,9,true,true,true);
855     if(animation[Anim_BeneMouth] != nullptr) {
856         animation[Anim_BeneMouth]->setPalette(benePalette);
857         animation[Anim_BeneMouth]->setFrameRate(5.0);
858     }
859     // the remaining animation are loaded on demand to save some loading time
860 
861     // load map choice pieces
862     for(int i = 0; i < NUM_MAPCHOICEPIECES; i++) {
863         mapChoicePieces[i][HOUSE_HARKONNEN] = Scaler::doubleSurfaceNN(pieces->getPicture(i));
864         SDL_SetColorKey(mapChoicePieces[i][HOUSE_HARKONNEN], SDL_TRUE, 0);
865     }
866 
867     // pBackgroundSurface is separate as we never draw it but use it to construct other sprites
868     pBackgroundSurface = convertSurfaceToDisplayFormat(PicFactory->createBackground(), true);
869 }
870 
~GFXManager()871 GFXManager::~GFXManager() {
872     for(int i = 0; i < NUM_OBJPICS; i++) {
873         for(int j = 0; j < (int) NUM_HOUSES; j++) {
874             for(int z = 0; z < NUM_ZOOMLEVEL; z++) {
875                 if(objPic[i][j][z] != nullptr) {
876                     SDL_FreeSurface(objPic[i][j][z]);
877                     objPic[i][j][z] = nullptr;
878                 }
879                 if(objPicTex[i][j][z] != nullptr) {
880                     SDL_DestroyTexture(objPicTex[i][j][z]);
881                     objPicTex[i][j][z] = nullptr;
882                 }
883             }
884         }
885     }
886 
887     for(int i = 0; i < NUM_SMALLDETAILPICS; i++) {
888         if(smallDetailPicTex[i] != nullptr) {
889             SDL_DestroyTexture(smallDetailPicTex[i]);
890             smallDetailPicTex[i] = nullptr;
891         }
892     }
893 
894     for(int i = 0; i < NUM_TINYPICTURE; i++) {
895         if(tinyPictureTex[i] != nullptr) {
896             SDL_DestroyTexture(tinyPictureTex[i]);
897             tinyPictureTex[i] = nullptr;
898         }
899     }
900 
901     for(int i = 0; i < NUM_UIGRAPHICS; i++) {
902         for(int j = 0; j < (int) NUM_HOUSES; j++) {
903             if(uiGraphic[i][j] != nullptr) {
904                 SDL_FreeSurface(uiGraphic[i][j]);
905                 uiGraphic[i][j] = nullptr;
906             }
907             if(uiGraphicTex[i][j] != nullptr) {
908                 SDL_DestroyTexture(uiGraphicTex[i][j]);
909                 uiGraphicTex[i][j] = nullptr;
910             }
911         }
912     }
913 
914     for(int i = 0; i < NUM_MAPCHOICEPIECES; i++) {
915         for(int j = 0; j < (int) NUM_HOUSES; j++) {
916             if(mapChoicePieces[i][j] != nullptr) {
917                 SDL_FreeSurface(mapChoicePieces[i][j]);
918                 mapChoicePieces[i][j] = nullptr;
919             }
920             if(mapChoicePiecesTex[i][j] != nullptr) {
921                 SDL_DestroyTexture(mapChoicePiecesTex[i][j]);
922                 mapChoicePiecesTex[i][j] = nullptr;
923             }
924         }
925     }
926 
927     for(int i = 0; i < NUM_ANIMATION; i++) {
928         if(animation[i] != nullptr) {
929             delete animation[i];
930             animation[i] = nullptr;
931         }
932     }
933 
934     SDL_FreeSurface(pBackgroundSurface);
935 }
936 
getObjPic(unsigned int id,int house)937 SDL_Texture** GFXManager::getObjPic(unsigned int id, int house) {
938     if(id >= NUM_OBJPICS) {
939         THROW(std::invalid_argument, "GFXManager::getObjPic(): Unit Picture with ID %u is not available!", id);
940     }
941 
942     for(int z = 0; z < NUM_ZOOMLEVEL; z++) {
943         if(objPic[id][house][z] == nullptr) {
944             // remap to this color
945             if(objPic[id][HOUSE_HARKONNEN][z] == nullptr) {
946                 THROW(std::runtime_error, "GFXManager::getObjPic(): Unit Picture with ID %u is not loaded!", id);
947             }
948 
949             objPic[id][house][z] = mapSurfaceColorRange(objPic[id][HOUSE_HARKONNEN][z], PALCOLOR_HARKONNEN, houseToPaletteIndex[house]);
950         }
951 
952         if(objPicTex[id][house][z] == nullptr) {
953             // now convert to display format
954             if(id == ObjPic_Windtrap) {
955                 // Windtrap uses palette animation on PALCOLOR_WINDTRAP_COLORCYCLE; fake this
956                 objPicTex[id][house][z] = convertSurfaceToTexture(generateWindtrapAnimationFrames(objPic[id][house][z]), true);
957             } else if(id == ObjPic_Terrain_HiddenFog) {
958                 SDL_Surface* pHiddenFog = convertSurfaceToDisplayFormat(objPic[id][house][z], false);
959                 replaceColor(pHiddenFog, COLOR_BLACK, COLOR_FOG_TRANSPARENT);
960                 objPicTex[id][house][z] = convertSurfaceToTexture(pHiddenFog, true);
961             } else if(id == ObjPic_CarryallShadow) {
962                 SDL_Surface* pShadow = convertSurfaceToDisplayFormat(objPic[id][house][z], false);
963                 replaceColor(pShadow, COLOR_BLACK, COLOR_SHADOW_TRANSPARENT);
964                 objPicTex[id][house][z] = convertSurfaceToTexture(pShadow, true);
965             } else if(id == ObjPic_FrigateShadow) {
966                 SDL_Surface* pShadow = convertSurfaceToDisplayFormat(objPic[id][house][z], false);
967                 replaceColor(pShadow, COLOR_BLACK, COLOR_SHADOW_TRANSPARENT);
968                 objPicTex[id][house][z] = convertSurfaceToTexture(pShadow, true);
969             } else if(id == ObjPic_OrnithopterShadow) {
970                 SDL_Surface* pShadow = convertSurfaceToDisplayFormat(objPic[id][house][z], false);
971                 replaceColor(pShadow, COLOR_BLACK, COLOR_SHADOW_TRANSPARENT);
972                 objPicTex[id][house][z] = convertSurfaceToTexture(pShadow, true);
973             } else if(id == ObjPic_Bullet_SonicTemp) {
974                 objPicTex[id][house][z] = SDL_CreateTexture(renderer, SCREEN_FORMAT, SDL_TEXTUREACCESS_TARGET, objPic[id][house][z]->w, objPic[id][house][z]->h);
975             } else if(id == ObjPic_SandwormShimmerTemp) {
976                 objPicTex[id][house][z] = SDL_CreateTexture(renderer, SCREEN_FORMAT, SDL_TEXTUREACCESS_TARGET, objPic[id][house][z]->w, objPic[id][house][z]->h);
977             } else {
978                 objPicTex[id][house][z] = convertSurfaceToTexture(objPic[id][house][z], false);
979             }
980         }
981     }
982 
983     return objPicTex[id][house];
984 }
985 
986 
getSmallDetailPic(unsigned int id)987 SDL_Texture* GFXManager::getSmallDetailPic(unsigned int id) {
988     if(id >= NUM_SMALLDETAILPICS) {
989         return nullptr;
990     }
991     return smallDetailPicTex[id];
992 }
993 
994 
getTinyPicture(unsigned int id)995 SDL_Texture* GFXManager::getTinyPicture(unsigned int id) {
996     if(id >= NUM_TINYPICTURE) {
997         return nullptr;
998     }
999     return tinyPictureTex[id];
1000 }
1001 
1002 
getUIGraphicSurface(unsigned int id,int house)1003 SDL_Surface* GFXManager::getUIGraphicSurface(unsigned int id, int house) {
1004     if(id >= NUM_UIGRAPHICS) {
1005         THROW(std::invalid_argument, "GFXManager::getUIGraphicSurface(): UI Graphic with ID %u is not available!", id);
1006     }
1007 
1008     if(uiGraphic[id][house] == nullptr) {
1009         // remap to this color
1010         if(uiGraphic[id][HOUSE_HARKONNEN] == nullptr) {
1011             THROW(std::runtime_error, "GFXManager::getUIGraphicSurface(): UI Graphic with ID %u is not loaded!", id);
1012         }
1013 
1014         uiGraphic[id][house] = mapSurfaceColorRange(uiGraphic[id][HOUSE_HARKONNEN], PALCOLOR_HARKONNEN, houseToPaletteIndex[house]);
1015     }
1016 
1017     return uiGraphic[id][house];
1018 }
1019 
getUIGraphic(unsigned int id,int house)1020 SDL_Texture* GFXManager::getUIGraphic(unsigned int id, int house) {
1021     if(id >= NUM_UIGRAPHICS) {
1022         THROW(std::invalid_argument, "GFXManager::getUIGraphic(): UI Graphic with ID %u is not available!", id);
1023     }
1024 
1025     if(uiGraphicTex[id][house] == nullptr) {
1026         SDL_Surface* pSurface = getUIGraphicSurface(id, house);
1027 
1028         if(id >= UI_MapChoiceArrow_None && id <= UI_MapChoiceArrow_Left) {
1029             uiGraphicTex[id][house] = convertSurfaceToTexture(generateMapChoiceArrowFrames(pSurface, house), true);
1030         } else if(id == UI_Indicator) {
1031             SDL_Surface* pIndicator = convertSurfaceToDisplayFormat(pSurface, false);
1032             replaceColor(pIndicator, COLOR_WHITE, COLOR_INDICATOR_TRANSPARENT);
1033             uiGraphicTex[UI_Indicator][house] = convertSurfaceToTexture(pIndicator, true);
1034         } else {
1035             uiGraphicTex[id][house] = convertSurfaceToTexture(pSurface, false);
1036         }
1037     }
1038 
1039     return uiGraphicTex[id][house];
1040 }
1041 
getMapChoicePieceSurface(unsigned int num,int house)1042 SDL_Surface* GFXManager::getMapChoicePieceSurface(unsigned int num, int house) {
1043     if(num >= NUM_MAPCHOICEPIECES) {
1044         THROW(std::invalid_argument, "GFXManager::getMapChoicePieceSurface(): Map Piece with number %u is not available!", num);
1045     }
1046 
1047     if(mapChoicePieces[num][house] == nullptr) {
1048         // remap to this color
1049         if(mapChoicePieces[num][HOUSE_HARKONNEN] == nullptr) {
1050             THROW(std::runtime_error, "GFXManager::getMapChoicePieceSurface(): Map Piece with number %u is not loaded!", num);
1051         }
1052 
1053         mapChoicePieces[num][house] = mapSurfaceColorRange(mapChoicePieces[num][HOUSE_HARKONNEN], PALCOLOR_HARKONNEN, houseToPaletteIndex[house]);
1054     }
1055 
1056     return mapChoicePieces[num][house];
1057 }
1058 
getMapChoicePiece(unsigned int num,int house)1059 SDL_Texture* GFXManager::getMapChoicePiece(unsigned int num, int house) {
1060     if(num >= NUM_MAPCHOICEPIECES) {
1061         THROW(std::invalid_argument, "GFXManager::getMapChoicePiece(): Map Piece with number %u is not available!", num);
1062     }
1063 
1064     if(mapChoicePiecesTex[num][house] == nullptr) {
1065         mapChoicePiecesTex[num][house] = convertSurfaceToTexture(getMapChoicePieceSurface(num, house), false);
1066     }
1067 
1068     return mapChoicePiecesTex[num][house];
1069 }
1070 
getAnimation(unsigned int id)1071 Animation* GFXManager::getAnimation(unsigned int id) {
1072     if(id >= NUM_ANIMATION) {
1073         THROW(std::invalid_argument, "GFXManager::getAnimation(): Animation with ID %u is not available!", id);
1074     }
1075 
1076     if(animation[id] == nullptr) {
1077         switch(id) {
1078             case Anim_HarkonnenPlanet: {
1079                 animation[Anim_HarkonnenPlanet] = loadAnimationFromWsa("FHARK.WSA");
1080                 animation[Anim_HarkonnenPlanet]->setFrameRate(10);
1081             } break;
1082 
1083             case Anim_AtreidesPlanet: {
1084                 animation[Anim_AtreidesPlanet] = loadAnimationFromWsa("FARTR.WSA");
1085                 animation[Anim_AtreidesPlanet]->setFrameRate(10);
1086             } break;
1087 
1088             case Anim_OrdosPlanet: {
1089                 animation[Anim_OrdosPlanet] = loadAnimationFromWsa("FORDOS.WSA");
1090                 animation[Anim_OrdosPlanet]->setFrameRate(10);
1091             } break;
1092 
1093             case Anim_FremenPlanet: {
1094                 animation[Anim_FremenPlanet] = PictureFactory::createFremenPlanet(uiGraphic[UI_Herald_ColoredLarge][HOUSE_FREMEN]);
1095                 animation[Anim_FremenPlanet]->setFrameRate(10);
1096             } break;
1097 
1098             case Anim_SardaukarPlanet: {
1099                 animation[Anim_SardaukarPlanet] = PictureFactory::createSardaukarPlanet(getAnimation(Anim_OrdosPlanet), uiGraphic[UI_Herald_ColoredLarge][HOUSE_SARDAUKAR]);
1100                 animation[Anim_SardaukarPlanet]->setFrameRate(10);
1101             } break;
1102 
1103             case Anim_MercenaryPlanet: {
1104                 animation[Anim_MercenaryPlanet] = PictureFactory::createMercenaryPlanet(getAnimation(Anim_AtreidesPlanet), uiGraphic[UI_Herald_ColoredLarge][HOUSE_MERCENARY]);
1105                 animation[Anim_MercenaryPlanet]->setFrameRate(10);
1106             } break;
1107 
1108             case Anim_Win1:             animation[Anim_Win1] = loadAnimationFromWsa("WIN1.WSA");                 break;
1109             case Anim_Win2:             animation[Anim_Win2] = loadAnimationFromWsa("WIN2.WSA");                 break;
1110             case Anim_Lose1:            animation[Anim_Lose1] = loadAnimationFromWsa("LOSTBILD.WSA");            break;
1111             case Anim_Lose2:            animation[Anim_Lose2] = loadAnimationFromWsa("LOSTVEHC.WSA");            break;
1112             case Anim_Barracks:         animation[Anim_Barracks] = loadAnimationFromWsa("BARRAC.WSA");           break;
1113             case Anim_Carryall:         animation[Anim_Carryall] = loadAnimationFromWsa("CARRYALL.WSA");         break;
1114             case Anim_ConstructionYard: animation[Anim_ConstructionYard] = loadAnimationFromWsa("CONSTRUC.WSA"); break;
1115             case Anim_Fremen:           animation[Anim_Fremen] = loadAnimationFromWsa("FREMEN.WSA");             break;
1116             case Anim_DeathHand:        animation[Anim_DeathHand] = loadAnimationFromWsa("GOLD-BB.WSA");         break;
1117             case Anim_Devastator:       animation[Anim_Devastator] = loadAnimationFromWsa("HARKTANK.WSA");       break;
1118             case Anim_Harvester:        animation[Anim_Harvester] = loadAnimationFromWsa("HARVEST.WSA");         break;
1119             case Anim_Radar:            animation[Anim_Radar] = loadAnimationFromWsa("HEADQRTS.WSA");            break;
1120             case Anim_HighTechFactory:  animation[Anim_HighTechFactory] = loadAnimationFromWsa("HITCFTRY.WSA");  break;
1121             case Anim_SiegeTank:        animation[Anim_SiegeTank] = loadAnimationFromWsa("HTANK.WSA");           break;
1122             case Anim_HeavyFactory:     animation[Anim_HeavyFactory] = loadAnimationFromWsa("HVYFTRY.WSA");      break;
1123             case Anim_Trooper:          animation[Anim_Trooper] = loadAnimationFromWsa("HYINFY.WSA");            break;
1124             case Anim_Infantry:         animation[Anim_Infantry] = loadAnimationFromWsa("INFANTRY.WSA");         break;
1125             case Anim_IX:               animation[Anim_IX] = loadAnimationFromWsa("IX.WSA");                     break;
1126             case Anim_LightFactory:     animation[Anim_LightFactory] = loadAnimationFromWsa("LITEFTRY.WSA");     break;
1127             case Anim_Tank:             animation[Anim_Tank] = loadAnimationFromWsa("LTANK.WSA");                break;
1128             case Anim_MCV:              animation[Anim_MCV] = loadAnimationFromWsa("MCV.WSA");                   break;
1129             case Anim_Deviator:         animation[Anim_Deviator] = loadAnimationFromWsa("ORDRTANK.WSA");         break;
1130             case Anim_Ornithopter:      animation[Anim_Ornithopter] = loadAnimationFromWsa("ORNI.WSA");          break;
1131             case Anim_Raider:           animation[Anim_Raider] = loadAnimationFromWsa("OTRIKE.WSA");             break;
1132             case Anim_Palace:           animation[Anim_Palace] = loadAnimationFromWsa("PALACE.WSA");             break;
1133             case Anim_Quad:             animation[Anim_Quad] = loadAnimationFromWsa("QUAD.WSA");                 break;
1134             case Anim_Refinery:         animation[Anim_Refinery] = loadAnimationFromWsa("REFINERY.WSA");         break;
1135             case Anim_RepairYard:       animation[Anim_RepairYard] = loadAnimationFromWsa("REPAIR.WSA");         break;
1136             case Anim_Launcher:         animation[Anim_Launcher] = loadAnimationFromWsa("RTANK.WSA");            break;
1137             case Anim_RocketTurret:     animation[Anim_RocketTurret] = loadAnimationFromWsa("RTURRET.WSA");      break;
1138             case Anim_Saboteur:         animation[Anim_Saboteur] = loadAnimationFromWsa("SABOTURE.WSA");         break;
1139             case Anim_Slab1:            animation[Anim_Slab1] = loadAnimationFromWsa("SLAB.WSA");                break;
1140             case Anim_SonicTank:        animation[Anim_SonicTank] = loadAnimationFromWsa("STANK.WSA");           break;
1141             case Anim_StarPort:         animation[Anim_StarPort] = loadAnimationFromWsa("STARPORT.WSA");         break;
1142             case Anim_Silo:             animation[Anim_Silo] = loadAnimationFromWsa("STORAGE.WSA");              break;
1143             case Anim_Trike:            animation[Anim_Trike] = loadAnimationFromWsa("TRIKE.WSA");               break;
1144             case Anim_GunTurret:        animation[Anim_GunTurret] = loadAnimationFromWsa("TURRET.WSA");          break;
1145             case Anim_Wall:             animation[Anim_Wall] = loadAnimationFromWsa("WALL.WSA");                 break;
1146             case Anim_WindTrap:         animation[Anim_WindTrap] = loadAnimationFromWsa("WINDTRAP.WSA");         break;
1147             case Anim_WOR:              animation[Anim_WOR] = loadAnimationFromWsa("WOR.WSA");                   break;
1148             case Anim_Sandworm:         animation[Anim_Sandworm] = loadAnimationFromWsa("WORM.WSA");             break;
1149             case Anim_Sardaukar:        animation[Anim_Sardaukar] = loadAnimationFromWsa("SARDUKAR.WSA");        break;
1150             case Anim_Frigate: {
1151                 if(pFileManager->exists("FRIGATE.WSA")) {
1152                     animation[Anim_Frigate] = loadAnimationFromWsa("FRIGATE.WSA");
1153                 } else {
1154                     // US-Version 1.07 does not contain FRIGATE.WSA
1155                     // We replace it with the starport
1156                     animation[Anim_Frigate] = loadAnimationFromWsa("STARPORT.WSA");
1157                 }
1158             } break;
1159             case Anim_Slab4:            animation[Anim_Slab4] = loadAnimationFromWsa("4SLAB.WSA");               break;
1160 
1161             default: {
1162                 THROW(std::runtime_error, "GFXManager::getAnimation(): Invalid animation ID %u", id);
1163             } break;
1164         }
1165 
1166         if(id >= Anim_Barracks && id <= Anim_Slab4) {
1167             animation[id]->setFrameRate(6);
1168         }
1169     }
1170 
1171     return animation[id];
1172 }
1173 
loadShpfile(const std::string & filename)1174 shared_ptr<Shpfile> GFXManager::loadShpfile(const std::string& filename) {
1175     try {
1176         return shared_ptr<Shpfile>(new Shpfile(pFileManager->openFile(filename), true));
1177     } catch (std::exception &e) {
1178         THROW(std::runtime_error, "Error in file \"" + filename + "\":" + e.what());
1179     }
1180 }
1181 
loadWsafile(const std::string & filename)1182 shared_ptr<Wsafile> GFXManager::loadWsafile(const std::string& filename) {
1183     SDL_RWops* file_wsa = nullptr;
1184     std::shared_ptr<Wsafile> wsafile;
1185     try {
1186         file_wsa = pFileManager->openFile(filename);
1187         wsafile = std::shared_ptr<Wsafile>(new Wsafile(file_wsa));
1188         SDL_RWclose(file_wsa);
1189         return wsafile;
1190     } catch (std::exception &e) {
1191         if(file_wsa != nullptr) {
1192             SDL_RWclose(file_wsa);
1193         }
1194         THROW(std::runtime_error, std::string("Error in file \"" + filename + "\":") + e.what());
1195     }
1196 }
1197 
extractSmallDetailPic(const std::string & filename)1198 SDL_Texture* GFXManager::extractSmallDetailPic(const std::string& filename) {
1199     SDL_RWops* myFile = pFileManager->openFile(filename);
1200 
1201     Wsafile* myWsafile = new Wsafile(myFile);
1202 
1203     SDL_Surface* tmp;
1204     if((tmp = myWsafile->getPicture(0)) == nullptr) {
1205         THROW(std::runtime_error, "Cannot decode first frame in file '%s'!", filename);
1206     }
1207 
1208     if((tmp->w != 184) || (tmp->h != 112)) {
1209         THROW(std::runtime_error, "Picture '%s' is not of size 184x112!", filename);
1210     }
1211 
1212     SDL_Surface* pSurface;
1213 
1214     // create new picture surface
1215     if((pSurface = SDL_CreateRGBSurface(0, 91, 55, 8, 0, 0, 0, 0)) == nullptr) {
1216         THROW(sdl_error, "Cannot create new surface: %s!", SDL_GetError());
1217     }
1218 
1219     palette.applyToSurface(pSurface);
1220     SDL_LockSurface(pSurface);
1221     SDL_LockSurface(tmp);
1222 
1223     //Now we can copy pixel by pixel
1224     for(int y = 0; y < 55;y++) {
1225         for(int x = 0; x < 91; x++) {
1226             *( ((char*) (pSurface->pixels)) + y*pSurface->pitch + x)
1227                 = *( ((char*) (tmp->pixels)) + ((y*2)+1)*tmp->pitch + (x*2)+1);
1228         }
1229     }
1230 
1231     SDL_UnlockSurface(tmp);
1232     SDL_UnlockSurface(pSurface);
1233 
1234     SDL_FreeSurface(tmp);
1235     delete myWsafile;
1236     SDL_RWclose(myFile);
1237 
1238     return convertSurfaceToTexture(pSurface, true);
1239 }
1240 
loadAnimationFromWsa(const std::string & filename)1241 Animation* GFXManager::loadAnimationFromWsa(const std::string& filename) {
1242     SDL_RWops* file = pFileManager->openFile(filename);
1243     Wsafile* wsafile = new Wsafile(file);
1244     Animation* ret = wsafile->getAnimation(0,wsafile->getNumFrames() - 1,true,false);
1245     delete wsafile;
1246     SDL_RWclose(file);
1247     return ret;
1248 }
1249 
generateWindtrapAnimationFrames(SDL_Surface * windtrapPic)1250 SDL_Surface* GFXManager::generateWindtrapAnimationFrames(SDL_Surface* windtrapPic) {
1251     int windtrapColorQuantizizer = 255/((NUM_WINDTRAP_ANIMATIONS/2)-2);
1252     int windtrapSize = windtrapPic->h;
1253     int sizeX = NUM_WINDTRAP_ANIMATIONS_PER_ROW*windtrapSize;
1254     int sizeY = ((2+NUM_WINDTRAP_ANIMATIONS+NUM_WINDTRAP_ANIMATIONS_PER_ROW-1)/NUM_WINDTRAP_ANIMATIONS_PER_ROW)*windtrapSize;
1255     SDL_Surface* returnPic = SDL_CreateRGBSurface(0, sizeX, sizeY, SCREEN_BPP, RMASK, GMASK, BMASK, AMASK);
1256     SDL_SetSurfaceBlendMode(returnPic, SDL_BLENDMODE_NONE);
1257 
1258     // copy building phase
1259     SDL_Rect src = { 0, 0, 2*windtrapSize, windtrapSize};
1260     SDL_Rect dest = src;
1261     SDL_BlitSurface(windtrapPic, &src, returnPic, &dest);
1262 
1263     src.w = windtrapSize;
1264     dest.x += dest.w;
1265     dest.w = windtrapSize;
1266 
1267     for(int i = 0; i < NUM_WINDTRAP_ANIMATIONS; i++) {
1268         src.x = ((i/3) % 2 == 0) ? 2*windtrapSize : 3*windtrapSize;
1269 
1270         SDL_Color windtrapColor;
1271         if(i < NUM_WINDTRAP_ANIMATIONS/2) {
1272             int val = i*windtrapColorQuantizizer;
1273             windtrapColor.r = static_cast<Uint8>(std::min(80, val));
1274             windtrapColor.g = static_cast<Uint8>(std::min(80, val));
1275             windtrapColor.b = static_cast<Uint8>(std::min(255, val));
1276             windtrapColor.a = 255;
1277         } else {
1278             int val = (i-NUM_WINDTRAP_ANIMATIONS/2)*windtrapColorQuantizizer;
1279             windtrapColor.r = static_cast<Uint8>(std::max(0, 80-val));
1280             windtrapColor.g = static_cast<Uint8>(std::max(0, 80-val));
1281             windtrapColor.b = static_cast<Uint8>(std::max(0, 255-val));
1282             windtrapColor.a = 255;
1283         }
1284         SDL_SetPaletteColors(windtrapPic->format->palette, &windtrapColor, PALCOLOR_WINDTRAP_COLORCYCLE, 1);
1285 
1286         SDL_BlitSurface(windtrapPic, &src, returnPic, &dest);
1287 
1288         dest.x += dest.w;
1289         dest.y = dest.y + dest.h * (dest.x / sizeX);
1290         dest.x = dest.x % sizeX;
1291     }
1292 
1293     if((returnPic->w > 2048) || (returnPic->h > 2048)) {
1294         SDL_Log("Warning: Size of sprite sheet for windtrap is %dx%d; may exceed hardware limits on older GPUs!", returnPic->w, returnPic->h);
1295     }
1296 
1297     return returnPic;
1298 }
1299 
1300 
generateMapChoiceArrowFrames(SDL_Surface * arrowPic,int house)1301 SDL_Surface* GFXManager::generateMapChoiceArrowFrames(SDL_Surface* arrowPic, int house) {
1302     SDL_Surface* returnPic = SDL_CreateRGBSurface(0, arrowPic->w*4, arrowPic->h, SCREEN_BPP, RMASK, GMASK, BMASK, AMASK);
1303 
1304     SDL_Rect dest = {0, 0, arrowPic->w, arrowPic->h};
1305 
1306     for(int i = 0; i < 4; i++) {
1307         for(int k = 0; k < 4; k++) {
1308             SDL_SetPaletteColors(arrowPic->format->palette, &palette[houseToPaletteIndex[house]+((i+k)%4)], 251+k, 1);
1309         }
1310 
1311         SDL_BlitSurface(arrowPic, nullptr, returnPic, &dest);
1312         dest.x += dest.w;
1313     }
1314 
1315     return returnPic;
1316 }
1317 
generateDoubledObjPic(unsigned int id,int h)1318 SDL_Surface* GFXManager::generateDoubledObjPic(unsigned int id, int h) {
1319     SDL_Surface* pSurface = nullptr;
1320     std::string filename = std::string("Mask_2x_") + ObjPicNames.at(id) + std::string(".png");
1321     if(settings.video.scaler == "ScaleHD") {
1322         if(pFileManager->exists(filename)) {
1323             pSurface = Scaler::doubleTiledSurfaceNN(objPic[id][h][0], objPicTiles[id].x, objPicTiles[id].y, false);
1324 
1325             SDL_Surface* pOverlay = LoadPNG_RW(pFileManager->openFile(filename), true);
1326             SDL_SetColorKey(pOverlay, SDL_TRUE, PALCOLOR_UI_COLORCYCLE);
1327 
1328             // SDL_BlitSurface will silently map PALCOLOR_BLACK to PALCOLOR_TRANSPARENT as both are RGB(0,0,0,255), so make them temporarily different
1329             pOverlay->format->palette->colors[PALCOLOR_BLACK].g = 1;
1330             pSurface->format->palette->colors[PALCOLOR_BLACK].g = 1;
1331             SDL_BlitSurface(pOverlay, NULL, pSurface, NULL);
1332             pOverlay->format->palette->colors[PALCOLOR_BLACK].g = 0;
1333             pSurface->format->palette->colors[PALCOLOR_BLACK].g = 0;
1334 
1335             SDL_FreeSurface(pOverlay);
1336         } else {
1337             SDL_Log("Warning: No HD sprite sheet for '%s' in zoom level 1!", ObjPicNames.at(id).c_str());
1338             pSurface = Scaler::defaultDoubleTiledSurface(objPic[id][h][0], objPicTiles[id].x, objPicTiles[id].y, false);
1339         }
1340     } else {
1341         pSurface = Scaler::defaultDoubleTiledSurface(objPic[id][h][0], objPicTiles[id].x, objPicTiles[id].y, false);
1342     }
1343 
1344     if((pSurface->w > 2048) || (pSurface->h > 2048)) {
1345         SDL_Log("Warning: Size of sprite sheet for '%s' in zoom level 1 is %dx%d; may exceed hardware limits on older GPUs!", ObjPicNames.at(id).c_str(), pSurface->w, pSurface->h);
1346     }
1347 
1348     return pSurface;
1349 }
1350 
generateTripledObjPic(unsigned int id,int h)1351 SDL_Surface* GFXManager::generateTripledObjPic(unsigned int id, int h) {
1352     SDL_Surface* pSurface = nullptr;
1353     std::string filename = std::string("Mask_3x_") + ObjPicNames.at(id) + std::string(".png");
1354     if(settings.video.scaler == "ScaleHD") {
1355         if(pFileManager->exists(filename)) {
1356             pSurface = Scaler::tripleTiledSurfaceNN(objPic[id][h][0], objPicTiles[id].x, objPicTiles[id].y, false);
1357 
1358             SDL_Surface* pOverlay = LoadPNG_RW(pFileManager->openFile(filename), true);
1359             SDL_SetColorKey(pOverlay, SDL_TRUE, PALCOLOR_UI_COLORCYCLE);
1360 
1361             // SDL_BlitSurface will silently map PALCOLOR_BLACK to PALCOLOR_TRANSPARENT as both are RGB(0,0,0,255), so make them temporarily different
1362             pOverlay->format->palette->colors[PALCOLOR_BLACK].g = 1;
1363             pSurface->format->palette->colors[PALCOLOR_BLACK].g = 1;
1364             SDL_BlitSurface(pOverlay, NULL, pSurface, NULL);
1365             pOverlay->format->palette->colors[PALCOLOR_BLACK].g = 0;
1366             pSurface->format->palette->colors[PALCOLOR_BLACK].g = 0;
1367 
1368             SDL_FreeSurface(pOverlay);
1369         } else {
1370             SDL_Log("Warning: No HD sprite sheet for '%s' in zoom level 2!", ObjPicNames.at(id).c_str());
1371             pSurface = Scaler::defaultTripleTiledSurface(objPic[id][h][0], objPicTiles[id].x, objPicTiles[id].y, false);
1372         }
1373     } else {
1374         pSurface = Scaler::defaultTripleTiledSurface(objPic[id][h][0], objPicTiles[id].x, objPicTiles[id].y, false);
1375     }
1376 
1377 
1378     if((pSurface->w > 2048) || (pSurface->h > 2048)) {
1379         SDL_Log("Warning: Size of sprite sheet for '%s' in zoom level 2 is %dx%d; may exceed hardware limits on older GPUs!", ObjPicNames.at(id).c_str(), pSurface->w, pSurface->h);
1380     }
1381 
1382     return pSurface;
1383 }
1384