00001
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "std3d.h"
00027
00028 #include "3d/tile_bank.h"
00029 #include "3d/texture_file.h"
00030 #include "3d/tile_noise_map.h"
00031
00032 #include "nel/misc/stream.h"
00033 #include "nel/misc/common.h"
00034 #include "nel/misc/path.h"
00035 #include "nel/misc/file.h"
00036 #include <string>
00037
00038 using namespace NLMISC;
00039 using namespace std;
00040
00041 namespace NL3D
00042 {
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053 const sint CTileLand::_Version=0;
00054
00055 void CTileLand::serial(IStream &f) throw(EStream)
00056 {
00057 (void)f.serialVersion(_Version);
00058
00059 f.serial (_Name);
00060 f.serialCont (_TileSet);
00061 }
00062
00063 void CTileLand::addTileSet (const std::string& name)
00064 {
00065 _TileSet.insert (name);
00066 }
00067
00068 void CTileLand::removeTileSet (const std::string& name)
00069 {
00070 _TileSet.erase (name);
00071 }
00072
00073 void CTileLand::setName (const std::string& name)
00074 {
00075 _Name=name;
00076 };
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088 const sint CTileBank::_Version=4;
00089
00090 CTileBank::CTileBank ()
00091 {
00092
00093 _DisplacementMap.resize (1);
00094
00095
00096 _DisplacementMap[0].setEmpty ();
00097 }
00098
00099 void CTileBank::serial(IStream &f) throw(EStream)
00100 {
00101 f.serialCheck (std::string ("BANK"));
00102
00103 sint streamver = f.serialVersion(_Version);
00104
00105
00106 if (f.isReading())
00107 {
00108 if (streamver<2)
00109 throw EOlderStream(f);
00110 }
00111
00112 switch (streamver)
00113 {
00114 case 4:
00115
00116 f.serialCont (_DisplacementMap);
00117 if (f.isReading())
00118 {
00119
00120 nlassert (_DisplacementMap.size()>0);
00121
00122
00123 _DisplacementMap[0].setEmpty ();
00124 }
00125 case 3:
00126
00127 f.serial (_AbsPath);
00128 case 2:
00129
00130 f.serialCont (_LandVector);
00131 f.serialCont (_TileSetVector);
00132 f.serialCont (_TileVector);
00133 }
00134
00135
00136 if (f.isReading())
00137 computeXRef ();
00138
00139
00140 if (streamver<=2)
00141 {
00142
00143 nlassert (f.isReading());
00144
00145
00146 _AbsPath="";
00147
00148
00149 uint tileCount=(uint)getTileCount ();
00150 for (uint i=0; i<tileCount; i++)
00151 {
00152 int tileSet;
00153 int number;
00154 TTileType type;
00155
00156
00157 getTileXRef (i, tileSet, number, type);
00158
00159
00160 if (type==transition)
00161 {
00162
00163 getTileSet(tileSet)->clearTransition ((CTileSet::TTransition)number, CTile::diffuse, *this);
00164
00165
00166 getTileSet(tileSet)->clearTransition ((CTileSet::TTransition)number, CTile::alpha, *this);
00167 }
00168 }
00169 }
00170 }
00171
00172 sint CTileBank::addLand (const std::string& name)
00173 {
00174 sint last=_LandVector.size();
00175 _LandVector.push_back(CTileLand());
00176 _LandVector[last].setName (name);
00177 return last;
00178 }
00179
00180 void CTileBank::removeLand (sint landIndex)
00181 {
00182
00183 nlassert (landIndex>=0);
00184 nlassert (landIndex<(sint)_LandVector.size());
00185
00186 _LandVector.erase (_LandVector.begin ()+landIndex);
00187 }
00188
00189 sint CTileBank::addTileSet (const std::string& name)
00190 {
00191 sint last=_TileSetVector.size();
00192 _TileSetVector.push_back(CTileSet());
00193 _TileSetVector[last].setName (name);
00194 for (int i=0; i<CTileSet::count; i++)
00195 {
00196 _TileSetVector[last]._TileTransition[i]._Tile=createTile ();
00197 }
00198 return last;
00199 }
00200
00201 void CTileBank::removeTileSet (sint setIndex)
00202 {
00203
00204 nlassert (setIndex>=0);
00205 nlassert (setIndex<(sint)_TileSetVector.size());
00206
00207 for (int i=0; i<CTileSet::count; i++)
00208 {
00209 int index=_TileSetVector[setIndex]._TileTransition[i]._Tile;
00210 if (index!=-1)
00211 freeTile (index);
00212 }
00213 _TileSetVector.erase (_TileSetVector.begin ()+setIndex);
00214 }
00215
00216 void CTileBank::clear ()
00217 {
00218 _LandVector.clear ();
00219 _TileSetVector.clear ();
00220 _TileVector.clear ();
00221 }
00222
00223 sint CTileBank::createTile ()
00224 {
00225
00226 for (int i=0; i<(sint)_TileVector.size(); i++)
00227 {
00228 if (_TileVector[i].isFree())
00229 {
00230 _TileVector[i].setFileName (CTile::diffuse, "");
00231 _TileVector[i].setFileName (CTile::additive, "");
00232 _TileVector[i].setFileName (CTile::alpha, "");
00233 return i;
00234 }
00235 }
00236
00237
00238 _TileVector.push_back (CTile());
00239 _TileVector[_TileVector.size()-1].setFileName (CTile::diffuse, "");
00240 _TileVector[_TileVector.size()-1].setFileName (CTile::additive, "");
00241 _TileVector[_TileVector.size()-1].setFileName (CTile::alpha, "");
00242 return _TileVector.size()-1;
00243 }
00244
00245 void CTileBank::freeTile (int tileIndex)
00246 {
00247
00248 nlassert (tileIndex>=0);
00249 nlassert (tileIndex<(sint)_TileVector.size());
00250
00251
00252 _TileVector[tileIndex].free();
00253
00254
00255 int i;
00256 for (i=(sint)_TileVector.size()-1; i>=0; i--)
00257 {
00258 if (!_TileVector[i].isFree ())
00259 break;
00260 }
00261 if (i<(sint)_TileVector.size()-1)
00262 _TileVector.resize (i+1);
00263 }
00264
00265 sint CTileBank::getNumBitmap (CTile::TBitmap bitmap) const
00266 {
00267 std::set<std::string> setString;
00268 for (int i=0; i<(sint)_TileVector.size(); i++)
00269 {
00270 if (!_TileVector[i].isFree())
00271 {
00272 const std::string &str=_TileVector[i].getRelativeFileName (bitmap);
00273 if (str!="")
00274 {
00275 std::vector<char> vect (str.length()+1);
00276 memcpy (&*vect.begin(), str.c_str(), str.length()+1);
00277 NLMISC::strlwr (&*vect.begin());
00278 setString.insert (std::string (&*vect.begin()));
00279 }
00280 }
00281 }
00282 return setString.size();
00283 }
00284
00285 void CTileBank::computeXRef ()
00286 {
00287
00288 _TileXRef.resize (_TileVector.size());
00289
00290
00291 for (int tile=0; tile<(sint)_TileVector.size(); tile++)
00292 _TileXRef[tile]._XRefTileSet=-1;
00293
00294
00295 for (int s=0; s<(sint)_TileSetVector.size(); s++)
00296 {
00297 int t;
00298 CTileSet *tileSet=getTileSet (s);
00299 for (t=0; t<tileSet->getNumTile128(); t++)
00300 {
00301 int index=tileSet->getTile128 (t);
00302 _TileXRef[index]._XRefTileSet=s;
00303 _TileXRef[index]._XRefTileNumber=t;
00304 _TileXRef[index]._XRefTileType=_128x128;
00305 }
00306 for (t=0; t<tileSet->getNumTile256(); t++)
00307 {
00308 int index=tileSet->getTile256 (t);
00309 _TileXRef[index]._XRefTileSet=s;
00310 _TileXRef[index]._XRefTileNumber=t;
00311 _TileXRef[index]._XRefTileType=_256x256;
00312 }
00313 for (t=0; t<CTileSet::count; t++)
00314 {
00315 int index=tileSet->getTransition (t)->getTile();
00316 _TileXRef[index]._XRefTileSet=s;
00317 _TileXRef[index]._XRefTileNumber=t;
00318 _TileXRef[index]._XRefTileType=transition;
00319 }
00320 }
00321 }
00322
00323 void CTileBank::xchgTileset (sint firstTileSet, sint secondTileSet)
00324 {
00325
00326 nlassert ((firstTileSet>=0)&&(firstTileSet<(sint)_TileSetVector.size()));
00327 nlassert ((secondTileSet>=0)&&(secondTileSet<(sint)_TileSetVector.size()));
00328
00329
00330 CTileSet tmp=_TileSetVector[firstTileSet];
00331 _TileSetVector[firstTileSet]=_TileSetVector[secondTileSet];
00332 _TileSetVector[secondTileSet]=tmp;
00333 }
00334
00335 void TroncFileName (char* sDest, const char* sSrc)
00336 {
00337 char* ptr=strrchr (sSrc, '\\');
00338 if (ptr==NULL)
00339 ptr=strrchr (sSrc, '/');
00340 if (ptr)
00341 {
00342 ptr++;
00343 strcpy (sDest, ptr);
00344 }
00345 else
00346 {
00347 strcpy (sDest, sSrc);
00348 }
00349 }
00350
00351
00352 void CTileBank::makeAllPathRelative ()
00353 {
00354
00355 for (sint nTile=0; nTile<(sint)_TileVector.size(); nTile++)
00356 {
00357
00358 char sTmpFileName[512];
00359
00360
00361 TroncFileName (sTmpFileName, _TileVector[nTile].getRelativeFileName (CTile::diffuse).c_str());
00362 _TileVector[nTile].setFileName (CTile::diffuse, sTmpFileName);
00363
00364
00365 TroncFileName (sTmpFileName, _TileVector[nTile].getRelativeFileName (CTile::additive).c_str());
00366 _TileVector[nTile].setFileName (CTile::additive, sTmpFileName);
00367
00368
00369 TroncFileName (sTmpFileName, _TileVector[nTile].getRelativeFileName (CTile::alpha).c_str());
00370 _TileVector[nTile].setFileName (CTile::alpha, sTmpFileName);
00371 }
00372
00373
00374 for (uint i=0; i<_DisplacementMap.size(); i++)
00375 {
00376
00377 char sTmpFileName[512];
00378
00379 TroncFileName (sTmpFileName, _DisplacementMap[i]._FileName.c_str());
00380 _DisplacementMap[i]._FileName = sTmpFileName;
00381 }
00382 }
00383
00384
00385
00386
00387 void CTileBank::makeAllExtensionDDS ()
00388 {
00389
00390 for (sint nTile=0; nTile<(sint)_TileVector.size(); nTile++)
00391 {
00392 string tmp;
00393 uint32 pos;
00394
00395
00396 tmp= _TileVector[nTile].getRelativeFileName (CTile::diffuse);
00397 pos= tmp.rfind(".tga");
00398 if(pos!= string::npos)
00399 {
00400 tmp.replace(pos, 4, ".dds");
00401 _TileVector[nTile].setFileName (CTile::diffuse, tmp);
00402 }
00403
00404
00405 tmp= _TileVector[nTile].getRelativeFileName (CTile::additive);
00406 pos= tmp.rfind(".tga");
00407 if(pos!= string::npos)
00408 {
00409 tmp.replace(pos, 4, ".dds");
00410 _TileVector[nTile].setFileName (CTile::additive, tmp);
00411 }
00412
00413
00414 tmp= _TileVector[nTile].getRelativeFileName (CTile::alpha);
00415 pos= tmp.rfind(".tga");
00416 if(pos!= string::npos)
00417 {
00418 tmp.replace(pos, 4, ".dds");
00419 _TileVector[nTile].setFileName (CTile::alpha, tmp);
00420 }
00421
00422 }
00423
00424 }
00425
00426 void CTileBank::cleanUnusedData ()
00427 {
00428
00429 for (uint i=0; i<_TileSetVector.size(); i++)
00430 {
00431
00432 _TileSetVector[i].cleanUnusedData ();
00433 }
00434
00435
00436 _LandVector.clear();
00437 }
00438
00439 CTileNoiseMap *CTileBank::getTileNoiseMap (uint tileNumber, uint tileSubNoise)
00440 {
00441
00442 if (tileNumber<_TileVector.size())
00443 {
00444
00445 uint tileSet=_TileXRef[tileNumber]._XRefTileSet;
00446
00447
00448 if (tileSet<_TileSetVector.size())
00449 {
00450 nlassert (tileSubNoise<CTileSet::CountDisplace);
00451 nlassert (_TileSetVector[tileSet]._DisplacementBitmap[tileSubNoise]<_DisplacementMap.size());
00452
00453
00454 CTileNoise &tileNoise=_DisplacementMap[_TileSetVector[tileSet]._DisplacementBitmap[tileSubNoise]];
00455
00456
00457 if (tileNoise._TileNoiseMap==NULL)
00458 {
00459
00460 CTextureFile texture (getAbsPath()+tileNoise._FileName);
00461 texture.loadGrayscaleAsAlpha (false);
00462 texture.generate ();
00463 texture.convertToType (CBitmap::Luminance);
00464
00465
00466 tileNoise._TileNoiseMap=new CTileNoiseMap;
00467
00468
00469 if ((texture.getWidth ()==NL3D_TILE_NOISE_MAP_SIZE)&&(texture.getHeight()==NL3D_TILE_NOISE_MAP_SIZE))
00470 {
00471
00472 memcpy (tileNoise._TileNoiseMap->Pixels, &texture.getPixels()[0], NL3D_TILE_NOISE_MAP_SIZE*NL3D_TILE_NOISE_MAP_SIZE);
00473
00474
00475 for (uint i=0; i<NL3D_TILE_NOISE_MAP_SIZE*NL3D_TILE_NOISE_MAP_SIZE; i++)
00476 {
00477 tileNoise._TileNoiseMap->Pixels[i]=(sint8)((uint8)tileNoise._TileNoiseMap->Pixels[i]-128);
00478 if (tileNoise._TileNoiseMap->Pixels[i]==-128)
00479 tileNoise._TileNoiseMap->Pixels[i]=-127;
00480 }
00481 }
00482 else
00483 {
00484
00485 string pathname= getAbsPath()+tileNoise._FileName;
00486 if( texture.getWidth ()==0 || texture.getHeight ()==0 )
00487 nlwarning("TileNoiseMap not found: %s.", pathname.c_str());
00488 else
00489 nlwarning("Bad TileNoiseMap size: %s.", pathname.c_str());
00490
00491
00492 sint8 notGoodSizeForm[NL3D_TILE_NOISE_MAP_SIZE*NL3D_TILE_NOISE_MAP_SIZE]=
00493 {
00494 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
00495 00, 99, 99, 99, 99, 99, 99, 99, 99, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
00496 00, 99, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
00497 00, 99, 00, 99, 99, 99, 99, 99, 99, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
00498 00, 99, 00, 99, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
00499 00, 99, 00, 99, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
00500 00, 99, 00, 99, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
00501 00, 99, 00, 99, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
00502 00, 99, 00, 99, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
00503 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
00504 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
00505 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
00506 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
00507 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
00508 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
00509 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
00510 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
00511 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
00512 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
00513 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
00514 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
00515 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
00516 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
00517 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 99, 00, 99, 00,
00518 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 99, 00, 99, 00,
00519 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 99, 00, 99, 00,
00520 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 99, 00, 99, 00,
00521 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 99, 00, 99, 00,
00522 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 99, 99, 99, 99, 99, 99, 00, 99, 00,
00523 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 99, 00,
00524 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 99, 99, 99, 99, 99, 99, 99, 99, 00,
00525 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00
00526 };
00527
00528
00529 memcpy (tileNoise._TileNoiseMap->Pixels, notGoodSizeForm, NL3D_TILE_NOISE_MAP_SIZE*NL3D_TILE_NOISE_MAP_SIZE);
00530 }
00531 }
00532
00533
00534 return tileNoise._TileNoiseMap;
00535 }
00536 }
00537
00538
00539 nlassert (_DisplacementMap[0]._TileNoiseMap);
00540 return _DisplacementMap[0]._TileNoiseMap;
00541 }
00542
00543 void CTileBank::removeDisplacementMap (uint mapId)
00544 {
00545
00546 nlassert (mapId<_DisplacementMap.size());
00547
00548 if (mapId!=0)
00549 {
00550
00551 uint tileSet;
00552 for (tileSet=0; tileSet<_TileSetVector.size(); tileSet++)
00553 {
00554
00555 uint tile;
00556 for (tile=0; tile<CTileSet::CountDisplace; tile++)
00557 {
00558
00559 if (_TileSetVector[tileSet]._DisplacementBitmap[tile]==mapId)
00560
00561 break;
00562 }
00563 if (tile!=CTileSet::CountDisplace)
00564 break;
00565 }
00566 if (tileSet==_TileSetVector.size())
00567 {
00568
00569 _DisplacementMap[mapId].reset();
00570
00571
00572 if (mapId==_DisplacementMap.size()-1)
00573 {
00574
00575 while ((mapId>0)&&(_DisplacementMap[mapId]._FileName==""))
00576 _DisplacementMap.resize (mapId--);
00577 }
00578 }
00579 }
00580 }
00581
00582 uint CTileBank::getDisplacementMap (const string &fileName)
00583 {
00584
00585 string lower=fileName;
00586 lower=strlwr (lower);
00587
00588
00589 uint noiseTile;
00590 for (noiseTile=0; noiseTile<_DisplacementMap.size(); noiseTile++)
00591 {
00592
00593 if (lower==_DisplacementMap[noiseTile]._FileName)
00594 return noiseTile;
00595 }
00596
00597
00598 for (noiseTile=0; noiseTile<_DisplacementMap.size(); noiseTile++)
00599 {
00600
00601 if (_DisplacementMap[noiseTile]._FileName=="")
00602 break;
00603 }
00604 if (noiseTile==_DisplacementMap.size())
00605 {
00606
00607 _DisplacementMap.resize (noiseTile+1);
00608 }
00609
00610
00611 _DisplacementMap[noiseTile]._FileName=lower;
00612
00613 return noiseTile;
00614 }
00615
00616 const char* CTileBank::getDisplacementMap (uint noiseMap)
00617 {
00618 return _DisplacementMap[noiseMap]._FileName.c_str();
00619 }
00620
00621 void CTileBank::setDisplacementMap (uint noiseMap, const char *newName)
00622 {
00623 _DisplacementMap[noiseMap]._FileName=newName;
00624 }
00625
00626 uint CTileBank::getDisplacementMapCount () const
00627 {
00628 return _DisplacementMap.size();
00629 }
00630
00631
00632
00633 const CTileVegetableDesc &CTileBank::getTileVegetableDesc(uint tileNumber) const
00634 {
00635
00636 if (tileNumber<_TileVector.size())
00637 {
00638
00639 uint tileSet=_TileXRef[tileNumber]._XRefTileSet;
00640
00641
00642 if (tileSet<_TileSetVector.size())
00643 {
00644 return _TileSetVector[tileSet].getTileVegetableDesc();
00645 }
00646
00647 }
00648
00649
00650 static CTileVegetableDesc emptyTvd;
00651 return emptyTvd;
00652 }
00653
00654
00655
00656 void CTileBank::loadTileVegetableDescs()
00657 {
00658
00659 uint tileSet;
00660
00661 for(tileSet=0; tileSet<_TileSetVector.size(); tileSet++)
00662 {
00663
00664 _TileSetVector[tileSet].loadTileVegetableDesc();
00665 }
00666 }
00667
00668
00669
00670 void CTileBank::initTileVegetableDescs(CVegetableManager *vegetableManager)
00671 {
00672
00673 uint tileSet;
00674
00675 for(tileSet=0; tileSet<_TileSetVector.size(); tileSet++)
00676 {
00677 CTileVegetableDesc &tvd= _TileSetVector[tileSet].getTileVegetableDesc();
00678 tvd.registerToManager(vegetableManager);
00679 }
00680 }
00681
00682
00683
00684
00685
00686
00687
00688
00689
00690
00691 const sint CTile::_Version=4;
00692
00693 void CTile::serial(IStream &f) throw(EStream)
00694 {
00695 sint streamver = f.serialVersion(_Version);
00696
00697
00698 bool tmp;
00699 string tmpStr;
00700
00701 switch (streamver)
00702 {
00703 case 4:
00704 case 3:
00705 case 2:
00706 f.serial (_Flags);
00707
00708
00709 if (streamver==2)
00710 _Flags=(_Flags&NL3D_CTILE_ROT_MASK)|(_Flags&NL3D_CTILE_GROUP_MASK_V2)|(((_Flags&NL3D_CTILE_FREE_FLAG_V2)!=0)?NL3D_CTILE_FREE_FLAG:0);
00711 if (streamver==3)
00712 _Flags=(_Flags&NL3D_CTILE_ROT_MASK)|(_Flags&NL3D_CTILE_GROUP_MASK_V3)|(((_Flags&NL3D_CTILE_FREE_FLAG_V3)!=0)?NL3D_CTILE_FREE_FLAG:0);
00713
00714 f.serial (_BitmapName[diffuse]);
00715 f.serial (_BitmapName[additive]);
00716 f.serial (_BitmapName[alpha]);
00717 break;
00718 case 1:
00719
00720 f.serial (tmp);
00721 case 0:
00722
00723 _Flags=0;
00724
00725
00726 _BitmapName[alpha]="";
00727
00728
00729 f.serial (tmp);
00730
00731
00732 if (tmp)
00733 _Flags|=NL3D_CTILE_FREE_FLAG;
00734
00735
00736 f.serial (_BitmapName[diffuse]);
00737 f.serial (_BitmapName[additive]);
00738
00739
00740 f.serial (tmpStr);
00741
00742 break;
00743 }
00744 }
00745
00746 void CTile::clearTile (CTile::TBitmap type)
00747 {
00748 _BitmapName[type]="";
00749 }
00750
00751
00752
00753
00754
00755
00756
00757
00758
00759
00760 const sint CTileSet::_Version=5;
00761
00762 const char* CTileSet::_ErrorMessage[CTileSet::errorCount]=
00763 {
00764 "No error.",
00765 "Top interface is incompatible.",
00766 "Bottom interface is incompatible.",
00767 "Left interface is incompatible.",
00768 "Right interface is incompatible.",
00769 "Add first a 128x128 tile.",
00770 "Top and bottom interface not the same.",
00771 "Right and left interface not the same.",
00772 "Invalide bitmap size.",
00773 };
00774
00775 const CTileSet::TFlagBorder CTileSet::_TransitionFlags[CTileSet::count][4]=
00776 {
00777 {_0000,_1111,_0111,_0111},
00778 {_0111,_1111,_0111,_1111},
00779 {_0000,_0111,_0000,_0111},
00780 {_1110,_1110,_1111,_0000},
00781 {_1110,_1111,_1111,_0111},
00782 {_0000,_1110,_0111,_0000},
00783
00784 {_0000,_1111,_0001,_0001},
00785 {_0000,_1000,_0001,_0000},
00786 {_1111,_1000,_1111,_1000},
00787 {_1000,_1000,_1111,_0000},
00788 {_1000,_0000,_1000,_0000},
00789 {_1111,_0001,_1000,_1111},
00790
00791 {_0000,_1111,_0111,_0001},
00792 {_0000,_1111,_0001,_0111},
00793 {_0111,_1111,_0001,_1111},
00794 {_1110,_1000,_1111,_0000},
00795 {_1000,_1110,_1111,_0000},
00796 {_1111,_0001,_1110,_1111},
00797
00798 {_1000,_0000,_1110,_0000},
00799 {_0000,_0111,_0000,_0001},
00800 {_1111,_1000,_1111,_1110},
00801 {_0111,_0000,_0000,_1000},
00802 {_0000,_1000,_0111,_0000},
00803 {_1111,_0111,_1000,_1111},
00804
00805 {_1111,_0000,_1110,_1110},
00806 {_1111,_1110,_1111,_1110},
00807 {_1110,_0000,_1110,_0000},
00808 {_0111,_0111,_0000,_1111},
00809 {_1111,_0111,_1110,_1111},
00810 {_0111,_0000,_0000,_1110},
00811
00812 {_1111,_0000,_1000,_1000},
00813 {_0001,_0000,_0000,_1000},
00814 {_0001,_1111,_0001,_1111},
00815 {_0001,_0001,_0000,_1111},
00816 {_0000,_0001,_0000,_0001},
00817 {_1000,_1111,_1111,_0001},
00818
00819 {_1111,_0000,_1000,_1110},
00820 {_1111,_0000,_1110,_1000},
00821 {_1000,_1111,_1111,_0111},
00822 {_0001,_0111,_0000,_1111},
00823 {_0111,_0001,_0000,_1111},
00824 {_1111,_1110,_1111,_1000},
00825
00826 {_0000,_0001,_0000,_0111},
00827 {_1110,_0000,_1000,_0000},
00828 {_0001,_1111,_0111,_1111},
00829 {_0000,_1110,_0001,_0000},
00830 {_0001,_0000,_0000,_1110},
00831 {_1110,_1111,_1111,_0001}
00832 };
00833
00834 CTileSet::CTileSet ()
00835 {
00836
00837 _Oriented = false;
00838 uint displace;
00839 for (displace=FirstDisplace; displace<CountDisplace; displace++)
00840 _DisplacementBitmap[displace]=0;
00841
00842
00843 SurfaceData = 0;
00844 }
00845
00846 void CTileSet::setName (const std::string& name)
00847 {
00848 _Name=name;
00849 }
00850
00851 const std::string& CTileSet::getName () const
00852 {
00853 return _Name;
00854 }
00855
00856 void CTileSet::serial(IStream &f) throw(EStream)
00857 {
00858 sint streamver = f.serialVersion(_Version);
00859
00860 CTileBorder tmp;
00861
00862
00863 if (streamver>=5)
00864 {
00865 f.serial (SurfaceData);
00866 }
00867
00868
00869 if (streamver>=4)
00870 {
00871 f.serial (_Oriented);
00872 }
00873
00874
00875 if (streamver>=3)
00876 {
00877
00878 f.serial(_TileVegetableDescFileName);
00879 }
00880
00881
00882 if (streamver>=2)
00883 {
00884 uint displace;
00885 for (displace=FirstDisplace; displace<CountDisplace; displace++)
00886 f.serial (_DisplacementBitmap[displace]);
00887 }
00888
00889
00890 if (streamver==1)
00891 {
00892
00893 string tmp;
00894 for (uint displace=FirstDisplace; displace<CountDisplace; displace++)
00895 f.serial (tmp);
00896 }
00897
00898 int i;
00899 f.serial (_Name);
00900 f.serialCont (_Tile128);
00901 f.serialCont (_Tile256);
00902 for (i=0; i<count; i++)
00903 f.serial (_TileTransition[i]);
00904 f.serialCont (_ChildName);
00905 f.serial (_Border128[CTile::diffuse]);
00906 f.serial (_Border128[CTile::additive]);
00907
00908
00909 if (streamver==0)
00910 f.serial (tmp);
00911
00912 f.serial (_Border256[CTile::diffuse]);
00913 f.serial (_Border256[CTile::additive]);
00914
00915
00916 if (streamver==0)
00917 f.serial (tmp);
00918
00919 for (i=0; i<count; i++)
00920 {
00921 f.serial (_BorderTransition[i][CTile::diffuse]);
00922 f.serial (_BorderTransition[i][CTile::additive]);
00923 f.serial (_BorderTransition[i][CTile::alpha]);
00924
00925
00926 if (streamver==0)
00927 {
00928 _BorderTransition[i][CTile::diffuse].reset();
00929 _BorderTransition[i][CTile::alpha].reset();
00930 }
00931 }
00932 }
00933
00934 void CTileSet::addTile128 (int& indexInTileSet, CTileBank& bank)
00935 {
00936
00937 sint index=bank.createTile ();
00938
00939
00940 indexInTileSet=_Tile128.size();
00941
00942
00943 _Tile128.push_back (index);
00944 }
00945
00946 void CTileSet::setBorder (CTile::TBitmap type, const CTileBorder& border)
00947 {
00948
00949 _Border128[type]=border;
00950 _Border256[type]=border;
00951 _Border256[type].doubleSize ();
00952 }
00953
00954 void CTileSet::setTile128 (int indexInTileSet, const std::string& name, CTile::TBitmap type, CTileBank& bank)
00955 {
00956
00957 CTile *tile=bank.getTile (_Tile128[indexInTileSet]);
00958 tile->setFileName (type, name);
00959 tile->setRotAlpha (0);
00960 }
00961
00962 CTileSet::TError CTileSet::checkTile128 (CTile::TBitmap type, const CTileBorder& border, int& pixel, int& composante)
00963 {
00964
00965 if ((border.getWidth()!=128)||(border.getHeight()!=128))
00966 return sizeInvalide;
00967 if (!CTileBorder::compare (border, border, CTileBorder::top, CTileBorder::bottom, pixel, composante))
00968 return topBottomNotTheSame;
00969 if (!CTileBorder::compare (border, border, CTileBorder::left, CTileBorder::right, pixel, composante))
00970 return rightLeftNotTheSame;
00971
00972
00973 if (_Border128[type].isSet())
00974 {
00975
00976 if (!CTileBorder::compare (border, _Border128[type], CTileBorder::top, CTileBorder::top, pixel, composante))
00977 return topInterfaceProblem;
00978 if (!CTileBorder::compare (border, _Border128[type], CTileBorder::bottom, CTileBorder::bottom, pixel, composante))
00979 return bottomInterfaceProblem;
00980 if (!CTileBorder::compare (border, _Border128[type], CTileBorder::left, CTileBorder::left, pixel, composante))
00981 return leftInterfaceProblem;
00982 if (!CTileBorder::compare (border, _Border128[type], CTileBorder::right, CTileBorder::right, pixel, composante))
00983 return rightInterfaceProblem;
00984 }
00985 else
00986 {
00987 return addFirstA128128;
00988 }
00989
00990 return ok;
00991 }
00992
00993 void CTileSet::addTile256 (int& indexInTileSet, CTileBank& bank)
00994 {
00995
00996 sint index=bank.createTile ();
00997
00998
00999 indexInTileSet=_Tile256.size();
01000
01001
01002 _Tile256.push_back (index);
01003 }
01004
01005 CTileSet::TError CTileSet::checkTile256 (CTile::TBitmap type, const CTileBorder& border, int& pixel, int& composante)
01006 {
01007
01008 if ((border.getWidth()!=256)||(border.getHeight()!=256))
01009 return sizeInvalide;
01010 if (!CTileBorder::compare (border, border, CTileBorder::top, CTileBorder::bottom, pixel, composante))
01011 return topBottomNotTheSame;
01012 if (!CTileBorder::compare (border, border, CTileBorder::left, CTileBorder::right, pixel, composante))
01013 return rightLeftNotTheSame;
01014
01015
01016 if ((!_Border256[type].isSet())&&(_Border128[type].isSet()))
01017 {
01018 _Border256[type]=_Border128[type];
01019 _Border256[type].doubleSize ();
01020 }
01021
01022
01023 if (_Border256[type].isSet())
01024 {
01025
01026
01027 if (!CTileBorder::compare (border, _Border256[type], CTileBorder::top, CTileBorder::top, pixel, composante))
01028 return topInterfaceProblem;
01029 if (!CTileBorder::compare (border, _Border256[type], CTileBorder::bottom, CTileBorder::bottom, pixel, composante))
01030 return bottomInterfaceProblem;
01031 if (!CTileBorder::compare (border, _Border256[type], CTileBorder::left, CTileBorder::left, pixel, composante))
01032 return leftInterfaceProblem;
01033 if (!CTileBorder::compare (border, _Border256[type], CTileBorder::right, CTileBorder::right, pixel, composante))
01034 return rightInterfaceProblem;
01035 }
01036 else
01037 {
01038 return addFirstA128128;
01039 }
01040
01041 return ok;
01042 }
01043
01044 void CTileSet::setTile256 (int indexInTileSet, const std::string& name, CTile::TBitmap type, CTileBank& bank)
01045 {
01046
01047 CTile *tile=bank.getTile (_Tile256[indexInTileSet]);
01048 tile->setFileName (type, name);
01049 tile->setRotAlpha (0);
01050 }
01051
01052 void CTileSet::setTileTransition (TTransition transition, const std::string& name, CTile::TBitmap type, CTileBank& bank,
01053 const CTileBorder& border)
01054 {
01055
01056 nlassert (type!=CTile::alpha);
01057
01058
01059 _BorderTransition[transition][type]=border;
01060
01061
01062 CTile *tile=bank.getTile (_TileTransition[transition]._Tile);
01063 tile->setFileName (type, name);
01064 }
01065
01066 void CTileSet::setTileTransitionAlpha (TTransition transition, const std::string& name, CTileBank& bank,
01067 const CTileBorder& border, uint8 rot)
01068 {
01069
01070 nlassert (rot<4);
01071
01072
01073 _BorderTransition[transition][CTile::alpha]=border;
01074
01075
01076 CTile *tile=bank.getTile (_TileTransition[transition]._Tile);
01077 tile->setFileName (CTile::alpha, name);
01078 tile->setRotAlpha (rot);
01079 }
01080
01081 CTileSet::TError CTileSet::checkTileTransition (TTransition transition, CTile::TBitmap type, const CTileBorder& border, int& indexError,
01082 int& pixel, int& composante)
01083 {
01084 nlassert (transition>=0);
01085 nlassert (transition<count);
01086
01087
01088 indexError=-1;
01089
01090
01091 indexError=getExistingTransitionTile ((TFlagBorder)_TransitionFlags[transition][top], dontcare, dontcare, dontcare, transition, type);
01092 if (indexError!=-1)
01093 {
01094 if (!CTileBorder::compare (border, _BorderTransition[indexError][type], CTileBorder::top, CTileBorder::top, pixel, composante))
01095 return topInterfaceProblem;
01096 }
01097 indexError=getExistingTransitionTile (dontcare, (TFlagBorder)_TransitionFlags[transition][top], dontcare, dontcare, transition, type);
01098 if (indexError!=-1)
01099 {
01100 if (!CTileBorder::compare (border, _BorderTransition[indexError][type], CTileBorder::top, CTileBorder::bottom, pixel, composante))
01101 return topInterfaceProblem;
01102 }
01103 indexError=-1;
01104 if (_TransitionFlags[transition][top]==_1111)
01105 {
01106 if (!CTileBorder::allAlphaSet (border, CTileBorder::top, pixel, composante))
01107 return topInterfaceProblem;
01108 }
01109
01110
01111 indexError=getExistingTransitionTile (dontcare, (TFlagBorder)_TransitionFlags[transition][bottom], dontcare, dontcare, transition, type);
01112 if (indexError!=-1)
01113 {
01114 if (!CTileBorder::compare (border, _BorderTransition[indexError][type], CTileBorder::bottom, CTileBorder::bottom, pixel, composante))
01115 return bottomInterfaceProblem;
01116 }
01117 indexError=getExistingTransitionTile ((TFlagBorder)_TransitionFlags[transition][bottom], dontcare, dontcare, dontcare, transition, type);
01118 if (indexError!=-1)
01119 {
01120 if (!CTileBorder::compare (border, _BorderTransition[indexError][type], CTileBorder::bottom, CTileBorder::top, pixel, composante))
01121 return bottomInterfaceProblem;
01122 }
01123 indexError=-1;
01124 if (_TransitionFlags[transition][bottom]==_1111)
01125 {
01126 if (!CTileBorder::allAlphaSet (border, CTileBorder::bottom, pixel, composante))
01127 return bottomInterfaceProblem;
01128 }
01129
01130
01131 indexError=getExistingTransitionTile (dontcare, dontcare, (TFlagBorder)_TransitionFlags[transition][left], dontcare, transition, type);
01132 if (indexError!=-1)
01133 {
01134 if (!CTileBorder::compare (border, _BorderTransition[indexError][type], CTileBorder::left, CTileBorder::left, pixel, composante))
01135 return leftInterfaceProblem;
01136 }
01137 indexError=getExistingTransitionTile (dontcare, dontcare, dontcare, (TFlagBorder)_TransitionFlags[transition][left], transition, type);
01138 if (indexError!=-1)
01139 {
01140 if (!CTileBorder::compare (border, _BorderTransition[indexError][type], CTileBorder::left, CTileBorder::right, pixel, composante))
01141 return leftInterfaceProblem;
01142 }
01143 indexError=-1;
01144 if (_TransitionFlags[transition][left]==_1111)
01145 {
01146 if (!CTileBorder::allAlphaSet (border, CTileBorder::left, pixel, composante))
01147 return leftInterfaceProblem;
01148 }
01149
01150
01151 indexError=getExistingTransitionTile (dontcare, dontcare, dontcare, (TFlagBorder)_TransitionFlags[transition][right], transition, type);
01152 if (indexError!=-1)
01153 {
01154 if (!CTileBorder::compare (border, _BorderTransition[indexError][type], CTileBorder::right, CTileBorder::right, pixel, composante))
01155 return rightInterfaceProblem;
01156 }
01157 indexError=getExistingTransitionTile (dontcare, dontcare, (TFlagBorder)_TransitionFlags[transition][right], dontcare, transition, type);
01158 if (indexError!=-1)
01159 {
01160 if (!CTileBorder::compare (border, _BorderTransition[indexError][type], CTileBorder::right, CTileBorder::left, pixel, composante))
01161 return rightInterfaceProblem;
01162 }
01163 indexError=-1;
01164 if (_TransitionFlags[transition][right]==_1111)
01165 {
01166 if (!CTileBorder::allAlphaSet (border, CTileBorder::right, pixel, composante))
01167 return rightInterfaceProblem;
01168 }
01169 return ok;
01170 }
01171
01172 void CTileSet::removeTile128 (int indexInTileSet, CTileBank& bank)
01173 {
01174
01175 nlassert (indexInTileSet>=0);
01176 nlassert (indexInTileSet<(sint)_Tile128.size());
01177
01178
01179 int index=_Tile128[indexInTileSet];
01180
01181
01182 _Tile128.erase (_Tile128.begin()+indexInTileSet);
01183 bank.freeTile (index);
01184
01185
01186 deleteBordersIfLast (bank, CTile::diffuse);
01187 deleteBordersIfLast (bank, CTile::additive);
01188 deleteBordersIfLast (bank, CTile::alpha);
01189 }
01190
01191 void CTileSet::removeTile256 (int indexInTileSet, CTileBank& bank)
01192 {
01193
01194 nlassert (indexInTileSet>=0);
01195 nlassert (indexInTileSet<(sint)_Tile256.size());
01196
01197
01198 int index=_Tile256[indexInTileSet];
01199
01200
01201 _Tile256.erase (_Tile256.begin()+indexInTileSet);
01202 bank.freeTile (index);
01203
01204
01205 deleteBordersIfLast (bank, CTile::diffuse);
01206 deleteBordersIfLast (bank, CTile::additive);
01207 deleteBordersIfLast (bank, CTile::alpha);
01208 }
01209
01210 CTileSet::TTransition CTileSet::getTransitionTile (TFlagBorder _top, TFlagBorder _bottom, TFlagBorder _left, TFlagBorder _right)
01211 {
01212 for (int n=first; n<count; n++)
01213 {
01214 if (((_top==dontcare)||(_top==(TFlagBorder)_TransitionFlags[n][top]))&&
01215 ((_bottom==dontcare)||(_bottom==(TFlagBorder)_TransitionFlags[n][bottom]))&&
01216 ((_left==dontcare)||(_left==(TFlagBorder)_TransitionFlags[n][left]))&&
01217 ((_right==dontcare)||(_right==(TFlagBorder)_TransitionFlags[n][right])))
01218 {
01219 return (TTransition)n;
01220 }
01221 }
01222 return notfound;
01223 }
01224
01225 CTileSet::TTransition CTileSet::getExistingTransitionTile (TFlagBorder _top, TFlagBorder _bottom, TFlagBorder _left, TFlagBorder _right, int reject, CTile::TBitmap type)
01226 {
01227 for (int n=first; n<count; n++)
01228 {
01229 if ((n!=reject)&&
01230 (_BorderTransition[n][type].isSet ())&&
01231 ((_top==dontcare)||(_top==(TFlagBorder)_TransitionFlags[n][top]))&&
01232 ((_bottom==dontcare)||(_bottom==(TFlagBorder)_TransitionFlags[n][bottom]))&&
01233 ((_left==dontcare)||(_left==(TFlagBorder)_TransitionFlags[n][left]))&&
01234 ((_right==dontcare)||(_right==(TFlagBorder)_TransitionFlags[n][right])))
01235 {
01236 return (TTransition)n;
01237 }
01238 }
01239 return notfound;
01240 }
01241
01242 void CTileSet::addChild (const std::string& name)
01243 {
01244 _ChildName.insert (name);
01245 }
01246
01247 void CTileSet::removeChild (const std::string& name)
01248 {
01249 _ChildName.erase (name);
01250 }
01251
01252 CTileSet::TTransition CTileSet::getComplementaryTransition (TTransition transition)
01253 {
01254 nlassert ((transition>=first)&&(transition<=last));
01255 TTransition trans=getTransitionTile (getComplementaryBorder (_TransitionFlags[transition][top]),
01256 getComplementaryBorder (_TransitionFlags[transition][bottom]),
01257 getComplementaryBorder (_TransitionFlags[transition][left]),
01258 getComplementaryBorder (_TransitionFlags[transition][right]));
01259
01260 nlassert (trans!=notfound);
01261
01262 return trans;
01263 }
01264
01265 CTileSet::TFlagBorder CTileSet::getComplementaryBorder (TFlagBorder border)
01266 {
01267 switch (border)
01268 {
01269 case _0000:
01270 return _1111;
01271 case _0001:
01272 return _1110;
01273 case _0111:
01274 return _1000;
01275 case _1000:
01276 return _0111;
01277 case _1110:
01278 return _0001;
01279 case _1111:
01280 return _0000;
01281 default:
01282 nlassert (0);
01283 }
01284 return _0000;
01285 }
01286
01287 CTileSet::TFlagBorder CTileSet::getInvertBorder (TFlagBorder border)
01288 {
01289 switch (border)
01290 {
01291 case _0000:
01292 return _0000;
01293 case _0001:
01294 return _1000;
01295 case _0111:
01296 return _1110;
01297 case _1000:
01298 return _0001;
01299 case _1110:
01300 return _0111;
01301 case _1111:
01302 return _1111;
01303 default:
01304 nlassert (0);
01305 }
01306 return _0000;
01307 }
01308
01309 CTileSet::TFlagBorder CTileSet::getOrientedBorder (TBorder where, TFlagBorder border)
01310 {
01311 switch (where)
01312 {
01313 case left:
01314 case bottom:
01315 return border;
01316 case top:
01317 case right:
01318 return getInvertBorder (border);
01319 default:
01320 nlassert (0);
01321 }
01322 return _0000;
01323 }
01324
01325 CTileSet::TTransition CTileSet::rotateTransition (TTransition transition)
01326 {
01327 return getTransitionTile (
01328 getOrientedBorder (top, getOrientedBorder (right, _TransitionFlags[transition][right])),
01329 getOrientedBorder (bottom, getOrientedBorder (left, _TransitionFlags[transition][left])),
01330 getOrientedBorder (left, getOrientedBorder (top, _TransitionFlags[transition][top])),
01331 getOrientedBorder (right, getOrientedBorder (bottom, _TransitionFlags[transition][bottom]))
01332 );
01333 }
01334
01335 void CTileSet::clearTile128 (int indexInTileSet, CTile::TBitmap type, CTileBank& bank)
01336 {
01337 int nTile=_Tile128[indexInTileSet];
01338 bank.getTile (nTile)->clearTile(type);
01339
01340
01341 deleteBordersIfLast (bank, type);
01342 }
01343
01344 void CTileSet::clearTile256 (int indexInTileSet, CTile::TBitmap type, CTileBank& bank)
01345 {
01346 int nTile=_Tile256[indexInTileSet];
01347 bank.getTile (nTile)->clearTile(type);
01348
01349
01350 deleteBordersIfLast (bank, type);
01351 }
01352
01353 void CTileSet::clearTransition (TTransition transition, CTile::TBitmap type, CTileBank& bank)
01354 {
01355 int nTile=_TileTransition[transition]._Tile;
01356 if (nTile!=-1)
01357 bank.getTile (nTile)->clearTile(type);
01358 _BorderTransition[transition][type].reset();
01359
01360
01361 deleteBordersIfLast (bank, type);
01362 }
01363
01364
01365 void CTileSet::deleteBordersIfLast (const CTileBank& bank, CTile::TBitmap type)
01366 {
01367
01368 bool bDelete=true;
01369
01370
01371 std::vector<sint32>::iterator ite=_Tile128.begin();
01372
01373
01374 while (ite!=_Tile128.end())
01375 {
01376
01377 if (bank.getTile (*ite)->getRelativeFileName(type)!="")
01378 {
01379
01380 bDelete=false;
01381 break;
01382 }
01383 ite++;
01384 }
01385
01386 if (ite!=_Tile128.end())
01387 return;
01388
01389
01390 ite=_Tile256.begin();
01391 while (ite!=_Tile256.end())
01392 {
01393
01394 if (bank.getTile (*ite)->getRelativeFileName(type)!="")
01395 {
01396
01397 bDelete=false;
01398 break;
01399 }
01400 ite++;
01401 }
01402
01403 if (ite!=_Tile256.end())
01404 return;
01405
01406
01407
01408 sint trans;
01409 for (trans=0; trans<count; trans++)
01410 {
01411
01412 int nTile=_TileTransition[trans]._Tile;
01413
01414
01415 if (nTile!=-1)
01416 {
01417
01418 if (bank.getTile (nTile)->getRelativeFileName(type)!="")
01419 {
01420
01421 bDelete=false;
01422 break;
01423 }
01424 }
01425 }
01426 if (trans!=count)
01427 return;
01428
01429
01430 _Border128[type].reset();
01431 _Border256[type].reset();
01432 }
01433
01434 void CTileSet::clearDisplacement (TDisplacement displacement, CTileBank& bank)
01435 {
01436
01437 nlassert (displacement>=FirstDisplace);
01438 nlassert (displacement<=LastDisplace);
01439
01440
01441 int id=_DisplacementBitmap[displacement];
01442
01443
01444 _DisplacementBitmap[displacement]=0;
01445
01446
01447 bank.removeDisplacementMap (id);
01448 }
01449
01450 void CTileSet::setDisplacement (TDisplacement displacement, const std::string& fileName, CTileBank& bank)
01451 {
01452
01453 nlassert (displacement>=FirstDisplace);
01454 nlassert (displacement<=LastDisplace);
01455
01456
01457 bank.removeDisplacementMap (_DisplacementBitmap[displacement]);
01458
01459
01460 _DisplacementBitmap[displacement]=bank.getDisplacementMap (fileName);
01461 }
01462
01463 void CTileSet::cleanUnusedData ()
01464 {
01465 _Name="";
01466 _ChildName.clear();
01467 _Border128[0].reset ();
01468 _Border128[1].reset ();
01469 _Border256[0].reset ();
01470 _Border256[1].reset ();
01471 for (uint i=0; i<count; i++)
01472 for (uint j=0; j<CTile::bitmapCount; j++)
01473 _BorderTransition[i][j].reset();
01474 }
01475
01476
01477
01478 void CTileSet::setTileVegetableDescFileName (const std::string &fileName)
01479 {
01480 _TileVegetableDescFileName= fileName;
01481 }
01482
01483 const std::string& CTileSet::getTileVegetableDescFileName () const
01484 {
01485 return _TileVegetableDescFileName;
01486 }
01487
01488 void CTileSet::setTileVegetableDesc (const CTileVegetableDesc &tvd)
01489 {
01490 _TileVegetableDesc= tvd;
01491 }
01492
01493
01494 CTileVegetableDesc &CTileSet::getTileVegetableDesc()
01495 {
01496 return _TileVegetableDesc;
01497 }
01498
01499
01500 const CTileVegetableDesc &CTileSet::getTileVegetableDesc() const
01501 {
01502 return _TileVegetableDesc;
01503 }
01504
01505
01506 void CTileSet::loadTileVegetableDesc()
01507 {
01508 if(_TileVegetableDescFileName!="")
01509 {
01510 try
01511 {
01512 string fname= CPath::lookup(_TileVegetableDescFileName);
01513 CIFile f(fname);
01514
01515 f.serial(_TileVegetableDesc);
01516 }
01517 catch(Exception &e)
01518 {
01519 nlinfo("Error loading TileVegetableDesc: %s", e.what());
01520 }
01521 }
01522 }
01523
01524
01525
01526
01527
01528
01529
01530
01531
01532
01533 const sint CTileBorder::_Version=0;
01534
01535 void CTileBorder::serial(IStream &f) throw(EStream)
01536 {
01537 (void)f.serialVersion(_Version);
01538
01539 f.serial (_Set);
01540 f.serial (_Width);
01541 f.serial (_Height);
01542 f.serialCont (_Borders[top]);
01543 f.serialCont (_Borders[bottom]);
01544 f.serialCont (_Borders[left]);
01545 f.serialCont (_Borders[right]);
01546 }
01547
01548 void CTileBorder::set (int width, int height, const std::vector<CBGRA>& array)
01549 {
01550
01551 nlassert (width>0);
01552 nlassert (height>0);
01553 nlassert ((sint)array.size()==width*height);
01554
01555
01556 _Width=width;
01557 _Height=height;
01558
01559
01560 int lastLine=(_Height-1)*width;
01561 int lastCol=(_Width-1);
01562 _Borders[top].resize (_Width);
01563 _Borders[bottom].resize (_Width);
01564 _Borders[left].resize (_Height);
01565 _Borders[right].resize (_Height);
01566
01567
01568 for (int w=0; w<_Width; w++)
01569 {
01570 _Borders[top][w]=array[w];
01571 _Borders[bottom][w]=array[w+lastLine];
01572 }
01573
01574
01575 for (int h=0; h<_Height; h++)
01576 {
01577 _Borders[left][h]=array[h*_Width];
01578 _Borders[right][h]=array[h*_Width+lastCol];
01579 }
01580
01581
01582 _Set=true;
01583 }
01584
01585 void CTileBorder::get (int &width, int &height, std::vector<CBGRA>& array) const
01586 {
01587
01588 if (_Set)
01589 {
01590 width=_Width;
01591 height=_Height;
01592 array.resize (0);
01593 array.resize (_Width*_Height);
01594 nlassert (_Borders[bottom].size()==(uint)_Width);
01595 nlassert (_Borders[top].size()==(uint)_Width);
01596 nlassert (_Borders[left].size()==(uint)_Height);
01597 nlassert (_Borders[right].size()==(uint)_Height);
01598
01599
01600 CBGRA black(0,0,0);
01601 for (int p=0; p<_Width*_Height; p++)
01602 {
01603 array[p]=black;
01604 }
01605
01606
01607 int lastLine=(_Height-1)*_Width;
01608 int lastCol=(_Width-1);
01609
01610
01611 for (int w=0; w<_Width; w++)
01612 {
01613 array[w]=_Borders[top][w];
01614 array[w+lastLine]=_Borders[bottom][w];
01615 }
01616
01617
01618 for (int h=0; h<_Height; h++)
01619 {
01620 array[h*_Width]=_Borders[left][h];
01621 array[h*_Width+lastCol]=_Borders[right][h];
01622 }
01623 }
01624 else
01625 {
01626 width=0;
01627 height=0;
01628 array.resize (0);
01629 }
01630 }
01631
01632 bool CTileBorder::compare (const CTileBorder& border1, const CTileBorder& border2, TBorder where1, TBorder where2, int& pixel, int& composante)
01633 {
01634
01635 nlassert (border1.isSet());
01636 nlassert (border2.isSet());
01637
01638 if (border1._Borders[where1].size()!=border2._Borders[where2].size())
01639 return false;
01640 for (pixel=0; pixel<(int)border1._Borders[where1].size(); pixel++)
01641 {
01642 if (border1._Borders[where1][pixel].R!=border2._Borders[where2][pixel].R)
01643 {
01644 composante=0;
01645 return false;
01646 }
01647 else if (border1._Borders[where1][pixel].G!=border2._Borders[where2][pixel].G)
01648 {
01649 composante=1;
01650 return false;
01651 }
01652 else if (border1._Borders[where1][pixel].B!=border2._Borders[where2][pixel].B)
01653 {
01654 composante=2;
01655 return false;
01656 }
01657 else if (border1._Borders[where1][pixel].A!=border2._Borders[where2][pixel].A)
01658 {
01659 composante=3;
01660 return false;
01661 }
01662 }
01663
01664 return true;
01665 }
01666
01667 bool CTileBorder::allAlphaSet (const CTileBorder& border, TBorder where, int& pixel, int& composante)
01668 {
01669
01670 nlassert (border.isSet());
01671
01672
01673 composante=3;
01674
01675 for (pixel=0; pixel<(int)border._Borders[where].size(); pixel++)
01676 {
01677 if (border._Borders[where][pixel].A!=0xff)
01678 return false;
01679 }
01680
01681 return true;
01682 }
01683
01684 bool CTileBorder::operator== (const CTileBorder& border) const
01685 {
01686 return (_Width==border._Width) && (_Height==border._Height) && (_Borders==border._Borders);
01687 }
01688
01689 void CTileBorder::operator= (const CTileBorder& border)
01690 {
01691 _Set=border._Set;
01692 _Width=border._Width;
01693 _Height=border._Width;
01694 _Borders[top]=border._Borders[top];
01695 _Borders[bottom]=border._Borders[bottom];
01696 _Borders[left]=border._Borders[left];
01697 _Borders[right]=border._Borders[right];
01698 }
01699
01700
01701 void CTileBorder::doubleSize ()
01702 {
01703 _Borders[top].resize (_Width*2);
01704 _Borders[bottom].resize (_Width*2);
01705 _Borders[left].resize (_Height*2);
01706 _Borders[right].resize (_Height*2);
01707
01708 for (int w=0; w<_Width; w++)
01709 {
01710 _Borders[top][w+_Width]=_Borders[top][w];
01711 _Borders[bottom][w+_Width]=_Borders[bottom][w];
01712 }
01713 for (int h=0; h<_Height; h++)
01714 {
01715 _Borders[left][h+_Height]=_Borders[left][h];
01716 _Borders[right][h+_Height]=_Borders[right][h];
01717 }
01718 }
01719
01720 void CTileBorder::rotate()
01721 {
01722
01723 std::vector<NLMISC::CBGRA> tmpLeft=_Borders[left];
01724
01725
01726 uint i, size;
01727 size=_Borders[top].size();
01728 _Borders[left].resize (size);
01729
01730
01731 for (i=0; i<size; i++)
01732 _Borders[left][i]=_Borders[top][size-i-1];
01733
01734
01735 _Borders[top]=_Borders[right];
01736
01737
01738 size=_Borders[bottom].size();
01739 _Borders[right].resize (size);
01740
01741
01742 for (i=0; i<size; i++)
01743 _Borders[right][i]=_Borders[bottom][size-i-1];
01744
01745
01746 _Borders[bottom]=tmpLeft;
01747
01748
01749 sint32 tmpSize=_Width;
01750 _Width=_Height;
01751 _Height=tmpSize;
01752 }
01753
01754
01755
01756
01757
01758
01759
01760
01761
01762 const sint CTileSetTransition::_Version=1;
01763
01764 void CTileSetTransition::serial(class NLMISC::IStream &f) throw(EStream)
01765 {
01766 sint streamver = f.serialVersion(_Version);
01767
01768 switch (streamver)
01769 {
01770 case 0:
01771 {
01772 bool doomy;
01773 f.serial (_Tile);
01774 f.serial (doomy);
01775 }
01776 break;
01777 case 1:
01778 f.serial (_Tile);
01779 break;
01780 }
01781 }
01782
01783
01784
01785
01786
01787
01788
01789
01790
01791
01792
01793 CTileNoise::CTileNoise ()
01794 {
01795
01796 _TileNoiseMap=NULL;
01797 _FileName="";
01798 }
01799
01800 CTileNoise::CTileNoise (const CTileNoise &src)
01801 {
01802
01803 _TileNoiseMap=NULL;
01804 _FileName="";
01805
01806
01807 *this=src;
01808 }
01809
01810 CTileNoise::~CTileNoise ()
01811 {
01812 if (_TileNoiseMap)
01813 {
01814 delete _TileNoiseMap;
01815 _TileNoiseMap=NULL;
01816 }
01817 }
01818
01819 CTileNoise& CTileNoise::operator= (const CTileNoise &src)
01820 {
01821
01822 _FileName=src._FileName;
01823
01824
01825 if (src._TileNoiseMap)
01826 {
01827 if (_TileNoiseMap==NULL)
01828 {
01829
01830 _TileNoiseMap=new CTileNoiseMap;
01831 }
01832
01833
01834 *_TileNoiseMap=*src._TileNoiseMap;
01835 }
01836 else
01837 {
01838
01839 if (_TileNoiseMap)
01840 {
01841 delete _TileNoiseMap;
01842 _TileNoiseMap=NULL;
01843 }
01844 }
01845 return *this;
01846 }
01847
01848 void CTileNoise::serial (IStream& f)
01849 {
01850
01851 f.serialVersion (0);
01852
01853
01854 f.serial (_FileName);
01855 }
01856
01857 void CTileNoise::setEmpty ()
01858 {
01859
01860 reset();
01861 _FileName="EmptyDisplacementMap";
01862 _TileNoiseMap=new CTileNoiseMap();
01863 memset (_TileNoiseMap->Pixels, 0, NL3D_TILE_NOISE_MAP_SIZE*NL3D_TILE_NOISE_MAP_SIZE);
01864 }
01865
01866 void CTileNoise::reset()
01867 {
01868
01869 if (_TileNoiseMap)
01870 {
01871 delete _TileNoiseMap;
01872 _TileNoiseMap=NULL;
01873 }
01874
01875
01876 _FileName="";
01877 }
01878
01879
01880 }