1 // ==============================================================
2 // This file is part of Glest (www.glest.org)
3 //
4 // Copyright (C) 2001-2008 Martiño Figueroa
5 //
6 // You can redistribute this code and/or modify it under
7 // the terms of the GNU General Public License as published
8 // by the Free Software Foundation; either version 2 of the
9 // License, or (at your option) any later version
10 // ==============================================================
11
12 #include "tileset.h"
13
14 #include <cassert>
15 #include <ctime>
16
17 #include "logger.h"
18 #include "util.h"
19 #include "renderer.h"
20 #include "game_util.h"
21 #include "leak_dumper.h"
22 #include "properties.h"
23 #include "lang.h"
24 #include "platform_util.h"
25
26 using namespace Shared::Util;
27 using namespace Shared::Xml;
28 using namespace Shared::Graphics;
29
30 namespace Glest{ namespace Game{
31
32 const float Tileset::standardAirHeight= 5.0f;
33 const float Tileset::standardShadowIntensity= 0.2f;
34 // =====================================================
35 // class AmbientSounds
36 // =====================================================
37
load(const string & dir,const XmlNode * xmlNode,std::map<string,vector<pair<string,string>>> & loadedFileList,string parentLoader)38 void AmbientSounds::load(const string &dir, const XmlNode *xmlNode,
39 std::map<string,vector<pair<string, string> > > &loadedFileList, string parentLoader) {
40 string path="";
41
42 //day
43 const XmlNode *dayNode= xmlNode->getChild("day-sound");
44 enabledDay= dayNode->getAttribute("enabled")->getBoolValue();
45 if(enabledDay) {
46 string currentPath = dir;
47 endPathWithSlash(currentPath);
48
49 path= dayNode->getAttribute("path")->getRestrictedValue(currentPath);
50 day.open(path);
51 loadedFileList[path].push_back(make_pair(parentLoader,dayNode->getAttribute("path")->getRestrictedValue()));
52
53 alwaysPlayDay= dayNode->getAttribute("play-always")->getBoolValue();
54 }
55
56 //night
57 const XmlNode *nightNode= xmlNode->getChild("night-sound");
58 enabledNight= nightNode->getAttribute("enabled")->getBoolValue();
59 if(enabledNight) {
60 string currentPath = dir;
61 endPathWithSlash(currentPath);
62
63 path= nightNode->getAttribute("path")->getRestrictedValue(currentPath);
64 night.open(path);
65 loadedFileList[path].push_back(make_pair(parentLoader,nightNode->getAttribute("path")->getRestrictedValue()));
66
67 alwaysPlayNight= nightNode->getAttribute("play-always")->getBoolValue();
68 }
69
70 //rain
71 const XmlNode *rainNode= xmlNode->getChild("rain-sound");
72 enabledRain= rainNode->getAttribute("enabled")->getBoolValue();
73 if(enabledRain) {
74 string currentPath = dir;
75 endPathWithSlash(currentPath);
76
77 path= rainNode->getAttribute("path")->getRestrictedValue(currentPath);
78 rain.open(path);
79 loadedFileList[path].push_back(make_pair(parentLoader,rainNode->getAttribute("path")->getRestrictedValue()));
80 }
81
82 //snow
83 const XmlNode *snowNode= xmlNode->getChild("snow-sound");
84 enabledSnow= snowNode->getAttribute("enabled")->getBoolValue();
85 if(enabledSnow) {
86 string currentPath = dir;
87 endPathWithSlash(currentPath);
88
89 path= snowNode->getAttribute("path")->getRestrictedValue(currentPath);
90 snow.open(path);
91 loadedFileList[path].push_back(make_pair(parentLoader,snowNode->getAttribute("path")->getRestrictedValue()));
92 }
93
94 //dayStart
95 const XmlNode *dayStartNode= xmlNode->getChild("day-start-sound");
96 enabledDayStart= dayStartNode->getAttribute("enabled")->getBoolValue();
97 if(enabledDayStart) {
98 string currentPath = dir;
99 endPathWithSlash(currentPath);
100
101 path= dayStartNode->getAttribute("path")->getRestrictedValue(currentPath);
102 dayStart.load(path);
103 loadedFileList[path].push_back(make_pair(parentLoader,dayStartNode->getAttribute("path")->getRestrictedValue()));
104 }
105
106 //nightStart
107 const XmlNode *nightStartNode= xmlNode->getChild("night-start-sound");
108 enabledNightStart= nightStartNode->getAttribute("enabled")->getBoolValue();
109 if(enabledNightStart) {
110 string currentPath = dir;
111 endPathWithSlash(currentPath);
112
113 path= nightStartNode->getAttribute("path")->getRestrictedValue(currentPath);
114 nightStart.load(path);
115 loadedFileList[path].push_back(make_pair(parentLoader,nightStartNode->getAttribute("path")->getRestrictedValue()));
116 }
117 }
118
119 // =====================================================
120 // class Tileset
121 // =====================================================
122
loadTileset(const vector<string> pathList,const string & tilesetName,Checksum * checksum,std::map<string,vector<pair<string,string>>> & loadedFileList)123 Checksum Tileset::loadTileset(const vector<string> pathList, const string &tilesetName,
124 Checksum* checksum, std::map<string,vector<pair<string, string> > > &loadedFileList) {
125 Checksum tilesetChecksum;
126
127 bool found = false;
128 for(int idx = 0; idx < (int)pathList.size(); idx++) {
129 string currentPath = pathList[idx];
130 endPathWithSlash(currentPath);
131 string path = currentPath + tilesetName;
132 if(isdir(path.c_str()) == true) {
133 load(path, checksum, &tilesetChecksum, loadedFileList);
134 found = true;
135 break;
136 }
137 }
138 if(found == false) {
139 throw megaglest_runtime_error("Error could not find tileset [" + tilesetName + "]\n",true);
140
141 }
142 return tilesetChecksum;
143 }
144
145
load(const string & dir,Checksum * checksum,Checksum * tilesetChecksum,std::map<string,vector<pair<string,string>>> & loadedFileList)146 void Tileset::load(const string &dir, Checksum *checksum, Checksum *tilesetChecksum,
147 std::map<string,vector<pair<string, string> > > &loadedFileList) {
148 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
149
150 random.init(time(NULL));
151
152 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
153
154 string name= lastDir(dir);
155 tileset_name = name;
156 string currentPath = dir;
157 endPathWithSlash(currentPath);
158 string path= currentPath + name + ".xml";
159 string sourceXMLFile = path;
160
161 checksum->addFile(path);
162 tilesetChecksum->addFile(path);
163 checksumValue.addFile(path);
164
165 try {
166 char szBuf[8096]="";
167 snprintf(szBuf,8096,Lang::getInstance().getString("LogScreenGameLoadingTileset","",true).c_str(),formatString(name).c_str());
168 Logger::getInstance().add(szBuf, true);
169
170 Renderer &renderer= Renderer::getInstance();
171
172 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
173
174 //printf("About to load tileset [%s]\n",path.c_str());
175 //parse xml
176 XmlTree xmlTree;
177 xmlTree.load(path,Properties::getTagReplacementValues());
178 loadedFileList[path].push_back(make_pair(currentPath,currentPath));
179
180 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
181
182 const XmlNode *tilesetNode= xmlTree.getRootNode();
183
184 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
185
186 //surfaces
187 const XmlNode *surfacesNode= tilesetNode->getChild("surfaces");
188 int partsize= 0;
189 for(int i=0; i < surfCount; ++i) {
190
191 const XmlNode *surfaceNode;
192 if(surfacesNode->hasChildAtIndex("surface",i)){
193 surfaceNode= surfacesNode->getChild("surface", i);
194 }
195 else {
196 // cliff texture does not exist, use texture 2 instead
197 surfaceNode= surfacesNode->getChild("surface", 2);
198 }
199
200 if(surfaceNode->hasAttribute("partsize")){
201 partsize=surfaceNode->getAttribute("partsize",true)->getIntValue();
202 }
203 else{
204 partsize=0;
205 }
206
207 if(partsize==0){
208 int childCount= (int)surfaceNode->getChildCount();
209 surfPixmaps[i].resize(childCount);
210 surfProbs[i].resize(childCount);
211
212 for(int j = 0; j < childCount; ++j) {
213 surfPixmaps[i][j] = NULL;
214 }
215
216 for(int j = 0; j < childCount; ++j) {
217 const XmlNode *textureNode= surfaceNode->getChild("texture", j);
218 if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == false) {
219 surfPixmaps[i][j] = new Pixmap2D();
220 surfPixmaps[i][j]->init(3);
221 surfPixmaps[i][j]->load(textureNode->getAttribute("path")->getRestrictedValue(currentPath));
222 }
223 loadedFileList[textureNode->getAttribute("path")->getRestrictedValue(currentPath)].push_back(make_pair(sourceXMLFile,textureNode->getAttribute("path")->getRestrictedValue()));
224
225 surfProbs[i][j]= textureNode->getAttribute("prob")->getFloatValue();
226 }
227 }
228 else {
229 // read single big texture and cut it into pieces
230 const XmlNode *textureNode= surfaceNode->getChild("texture", 0);
231
232 // There is no way to figure out parts without loading the texture
233 // unfortunately we must load it even for headless server
234 // to get width and height
235 bool switchOffNonGraphicalModeEnabled = GlobalStaticFlags::getIsNonGraphicalModeEnabled();
236 if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) {
237 GlobalStaticFlags::setIsNonGraphicalModeEnabled(false);
238 }
239
240 string exceptionError = "";
241 Pixmap2D *pixmap = NULL;
242 int width = 0;
243 int height = 0;
244
245 try {
246 pixmap=new Pixmap2D();
247 pixmap->init(3);
248 pixmap->load(textureNode->getAttribute("path")->getRestrictedValue(currentPath));
249 loadedFileList[textureNode->getAttribute("path")->getRestrictedValue(currentPath)].push_back(make_pair(sourceXMLFile,textureNode->getAttribute("path")->getRestrictedValue()));
250
251 width = pixmap->getW();
252 height = pixmap->getW();
253 }
254 catch(megaglest_runtime_error& ex) {
255 SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] Error [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,ex.what());
256 throw megaglest_runtime_error("Error loading tileset: "+ path + "\nMessage: " + ex.what(),!ex.wantStackTrace() );
257 }
258 catch(const exception &ex) {
259 SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] Error [%s]\n",__FILE__,__FUNCTION__,__LINE__,ex.what());
260
261 exceptionError = "Error: " + path + "\n" + ex.what();
262 }
263
264 if(switchOffNonGraphicalModeEnabled == true) {
265 GlobalStaticFlags::setIsNonGraphicalModeEnabled(true);
266
267 delete pixmap;
268 pixmap = NULL;
269 }
270
271 if(exceptionError != "") {
272 throw megaglest_runtime_error(exceptionError.c_str());
273 }
274
275 if(width != height) {
276 throw megaglest_runtime_error("width != height");
277 }
278 if(width % 64 != 0) {
279 throw megaglest_runtime_error("width % 64 != 0");
280 }
281 if(width % partsize != 0) {
282 throw megaglest_runtime_error("width % partsize != 0");
283 }
284
285 int parts=width/partsize;
286 int numberOfPieces=parts*parts;
287 partsArray[i]=parts;
288 surfPixmaps[i].resize(numberOfPieces);
289 surfProbs[i].resize(numberOfPieces);
290 int j=0;
291 for(int x = 0; x < parts; ++x) {
292 for(int y = 0; y < parts; ++y) {
293 if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == false) {
294 surfPixmaps[i][j] = new Pixmap2D();
295 surfPixmaps[i][j]->init(partsize,partsize,3);
296 surfPixmaps[i][j]->copyImagePart(x*partsize,y*partsize,pixmap);
297 }
298 surfProbs[i][j]=-1;
299 j++;
300 }
301 }
302 }
303 }
304
305 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
306
307 //object models
308 const XmlNode *objectsNode= tilesetNode->getChild("objects");
309 for(int i=0; i<objCount; ++i){
310 const XmlNode *objectNode= objectsNode->getChild("object", i);
311 int childCount= (int)objectNode->getChildCount();
312
313 int objectHeight = 0;
314 bool walkable = objectNode->getAttribute("walkable")->getBoolValue();
315 if(walkable == false) {
316 const XmlAttribute *heightAttribute = objectNode->getAttribute("height",false);
317 if(heightAttribute != NULL) {
318 objectHeight = heightAttribute->getIntValue();
319 }
320 }
321
322 objectTypes[i].init(childCount, i, walkable,objectHeight);
323 for(int j=0; j<childCount; ++j) {
324 const XmlNode *modelNode= objectNode->getChild("model", j);
325 const XmlAttribute *pathAttribute= modelNode->getAttribute("path");
326 TilesetModelType* tmt=objectTypes[i].loadModel(pathAttribute->getRestrictedValue(currentPath),&loadedFileList, sourceXMLFile);
327 loadedFileList[pathAttribute->getRestrictedValue(currentPath)].push_back(make_pair(sourceXMLFile,pathAttribute->getRestrictedValue()));
328
329 if(modelNode->hasAttribute("anim-speed") == true) {
330 int animSpeed= modelNode->getAttribute("anim-speed")->getIntValue();
331 tmt->setAnimSpeed(animSpeed);
332 }
333
334 if(modelNode->hasChild("particles")){
335 const XmlNode *particleNode= modelNode->getChild("particles");
336 bool particleEnabled= particleNode->getAttribute("value")->getBoolValue();
337 if(particleEnabled){
338 for(int k=0; k < (int)particleNode->getChildCount(); ++k){
339 const XmlNode *particleFileNode= particleNode->getChild("particle-file", k);
340 string path= particleFileNode->getAttribute("path")->getRestrictedValue();
341 ObjectParticleSystemType *objectParticleSystemType= new ObjectParticleSystemType();
342 objectParticleSystemType->load(particleFileNode, dir, currentPath + path,
343 &Renderer::getInstance(), loadedFileList, sourceXMLFile,"");
344 loadedFileList[currentPath + path].push_back(make_pair(sourceXMLFile,particleFileNode->getAttribute("path")->getRestrictedValue()));
345
346 tmt->addParticleSystem(objectParticleSystemType);
347 }
348 }
349 }
350
351 //rotationAllowed
352 if(modelNode->hasAttribute("rotationAllowed") == true) {
353 tmt->setRotationAllowed(modelNode->getAttribute("rotationAllowed")->getBoolValue());
354 }
355 else if(modelNode->hasChild("rotationAllowed")){
356 const XmlNode *rotationAllowedNode= modelNode->getChild("rotationAllowed");
357 tmt->setRotationAllowed(rotationAllowedNode->getAttribute("value")->getBoolValue());
358 }
359 else{
360 tmt->setRotationAllowed(true);
361 }
362 //randomPositionEnabled
363 if(modelNode->hasAttribute("randomPositionEnabled") == true) {
364 tmt->setRandomPositionEnabled(modelNode->getAttribute("randomPositionEnabled")->getBoolValue());
365 }
366 else{
367 tmt->setRandomPositionEnabled(true);
368 }
369
370 //smoothTwoFrameAnim
371 if(modelNode->hasAttribute("smoothTwoFrameAnim") == true) {
372 tmt->setSmoothTwoFrameAnim(modelNode->getAttribute("smoothTwoFrameAnim")->getBoolValue());
373 }
374 else{
375 tmt->setSmoothTwoFrameAnim(false);
376 }
377 }
378 }
379
380 // Now free up the pixmap memory
381 for(int i=0; i<objCount; ++i){
382 objectTypes[i].deletePixels();
383 }
384
385 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
386
387 //ambient sounds
388 ambientSounds.load(dir, tilesetNode->getChild("ambient-sounds"), loadedFileList, sourceXMLFile);
389
390 //parameters
391 const XmlNode *parametersNode= tilesetNode->getChild("parameters");
392
393 //water
394 const XmlNode *waterNode= parametersNode->getChild("water");
395 waterTex= renderer.newTexture3D(rsGame);
396 if(waterTex) {
397 waterTex->setMipmap(false);
398 waterTex->setWrapMode(Texture::wmRepeat);
399 }
400 waterEffects= waterNode->getAttribute("effects")->getBoolValue();
401
402 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
403
404 int waterFrameCount= (int)waterNode->getChildCount();
405 if(waterTex) {
406 waterTex->getPixmap()->init(waterFrameCount, 4);
407 }
408 for(int i=0; i<waterFrameCount; ++i){
409 const XmlNode *waterFrameNode= waterNode->getChild("texture", i);
410 if(waterTex) {
411 waterTex->getPixmap()->loadSlice(waterFrameNode->getAttribute("path")->getRestrictedValue(currentPath), i);
412 }
413 loadedFileList[waterFrameNode->getAttribute("path")->getRestrictedValue(currentPath)].push_back(make_pair(sourceXMLFile,waterFrameNode->getAttribute("path")->getRestrictedValue()));
414 }
415
416 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
417
418 //fog
419 const XmlNode *fogNode= parametersNode->getChild("fog");
420 fog= fogNode->getAttribute("enabled")->getBoolValue();
421 if(fog){
422 fogMode= fogNode->getAttribute("mode")->getIntValue(1, 2);
423 fogDensity= fogNode->getAttribute("density")->getFloatValue();
424 fogColor.x= fogNode->getAttribute("color-red")->getFloatValue(0.f, 1.f);
425 fogColor.y= fogNode->getAttribute("color-green")->getFloatValue(0.f, 1.f);
426 fogColor.z= fogNode->getAttribute("color-blue")->getFloatValue(0.f, 1.f);
427 }
428
429 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
430
431 //sun and moon light colors
432 const XmlNode *sunLightColorNode= parametersNode->getChild("sun-light");
433 sunLightColor.x= sunLightColorNode->getAttribute("red")->getFloatValue();
434 sunLightColor.y= sunLightColorNode->getAttribute("green")->getFloatValue();
435 sunLightColor.z= sunLightColorNode->getAttribute("blue")->getFloatValue();
436
437 const XmlNode *moonLightColorNode= parametersNode->getChild("moon-light");
438 moonLightColor.x= moonLightColorNode->getAttribute("red")->getFloatValue();
439 moonLightColor.y= moonLightColorNode->getAttribute("green")->getFloatValue();
440 moonLightColor.z= moonLightColorNode->getAttribute("blue")->getFloatValue();
441
442 if(parametersNode->hasChild("shadow-intensity")) {
443 const XmlNode *shadowIntenseNode= parametersNode->getChild("shadow-intensity");
444 shadowIntensity= shadowIntenseNode->getAttribute("value")->getFloatValue();
445 } else {
446 shadowIntensity=standardShadowIntensity;
447 }
448
449 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
450
451 //weather
452 const XmlNode *weatherNode= parametersNode->getChild("weather");
453 float sunnyProb= weatherNode->getAttribute("sun")->getFloatValue(0.f, 1.f);
454 float rainyProb= weatherNode->getAttribute("rain")->getFloatValue(0.f, 1.f) + sunnyProb;
455
456 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
457
458 #ifdef USE_STREFLOP
459 float rnd= streflop::fabs(static_cast<streflop::Simple>(random.randRange(-1.f, 1.f)));
460 #else
461 float rnd= fabs(random.randRange(-1.f, 1.f));
462 #endif
463
464 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
465
466 if(rnd < sunnyProb) {
467 weather= wSunny;
468 }
469 else if(rnd < rainyProb) {
470 weather= wRainy;
471 }
472 else {
473 weather= wSnowy;
474 }
475
476 //printf("==> Weather is: %d rnd = %f [sun: %f rainyProb: %f]",weather,rnd,sunnyProb,rainyProb);
477
478 //airHeight
479 if(parametersNode->hasChild("air-height")) {
480 const XmlNode *node= parametersNode->getChild("air-height");
481 airHeight= node->getAttribute("value")->getFloatValue();
482 // airHeight should not be lower than default
483 if( airHeight<Tileset::standardAirHeight){
484 airHeight=standardAirHeight;
485 }
486 // airHeight should not be bigger than 3 x default
487 if( airHeight>3*Tileset::standardAirHeight){
488 airHeight=3*Tileset::standardAirHeight;
489 }
490 }
491
492
493
494 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
495
496 }
497 //Exception handling (conversions and so on);
498 catch(megaglest_runtime_error& ex) {
499 SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] Error [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,ex.what());
500 throw megaglest_runtime_error("Error loading tileset: "+ path + "\nMessage: " + ex.what(),!ex.wantStackTrace() );
501 }
502 catch(const exception &e) {
503 SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] Error [%s]\n",__FILE__,__FUNCTION__,__LINE__,e.what());
504 throw megaglest_runtime_error("Error: " + path + "\n" + e.what());
505 }
506
507 Lang &lang = Lang::getInstance();
508 lang.loadTilesetStrings(name);
509 }
510
~Tileset()511 Tileset::~Tileset() {
512 for(int i = 0; i < surfCount; ++i) {
513 deleteValues(surfPixmaps[i].begin(),surfPixmaps[i].end());
514 surfPixmaps[i].clear();
515 }
516
517 Logger::getInstance().add(Lang::getInstance().getString("LogScreenGameUnLoadingTileset","",true), true);
518 }
519
getSurfPixmap(int type,int var) const520 const Pixmap2D *Tileset::getSurfPixmap(int type, int var) const{
521 int vars= (int)surfPixmaps[type].size();
522 return surfPixmaps[type][var % vars];
523 }
524
addSurfTex(int leftUp,int rightUp,int leftDown,int rightDown,Vec2f & coord,const Texture2D * & texture,int mapX,int mapY)525 void Tileset::addSurfTex(int leftUp, int rightUp, int leftDown, int rightDown, Vec2f &coord, const Texture2D *&texture, int mapX, int mapY) {
526 //center textures
527 if(leftUp == rightUp && leftUp == leftDown && leftUp == rightDown) {
528 //texture variation according to probability
529 float r= random.randRange(0.f, 1.f);
530 const Pixmap2D *pixmap = NULL;
531
532 if(surfProbs[leftUp][0] < 0) {
533 // big textures use coordinates
534 int parts = partsArray[leftUp];
535 pixmap = getSurfPixmap(leftUp, (mapY % parts) * parts + (mapX % parts));
536 }
537 else {
538 float max= 0.f;
539 int var= 0;
540 for(int i=0; i < (int)surfProbs[leftUp].size(); ++i) {
541 max += surfProbs[leftUp][i];
542 if(r <= max) {
543 var= i;
544 break;
545 }
546 }
547 pixmap=getSurfPixmap(leftUp, var);
548 }
549 SurfaceInfo si(pixmap);
550 surfaceAtlas.addSurface(&si);
551 coord= si.getCoord();
552 // only for 512px printf("coord.x=%f coord.y=%f mapX=%d mapY=%d result=%d\n",coord.x,coord.y,mapX,mapY,(mapY%8)*8+(mapX%8));
553 texture= si.getTexture();
554 }
555 //spatted textures
556 else {
557 int var= random.randRange(0, transitionVars);
558
559 SurfaceInfo si( getSurfPixmap(leftUp, var),
560 getSurfPixmap(rightUp, var),
561 getSurfPixmap(leftDown, var),
562 getSurfPixmap(rightDown, var));
563 surfaceAtlas.addSurface(&si);
564 coord= si.getCoord();
565 texture= si.getTexture();
566 }
567 }
568
569 }}// end namespace
570