# Home    # nevrax.com   
Nevrax
Nevrax.org
#News
#Mailing-list
#Documentation
#CVS
#Bugs
#License
Docs
 
Documentation  
Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages   Search  

tile_bank.cpp

Go to the documentation of this file.
00001 
00007 /* Copyright, 2000 Nevrax Ltd.
00008  *
00009  * This file is part of NEVRAX NEL.
00010  * NEVRAX NEL is free software; you can redistribute it and/or modify
00011  * it under the terms of the GNU General Public License as published by
00012  * the Free Software Foundation; either version 2, or (at your option)
00013  * any later version.
00014 
00015  * NEVRAX NEL is distributed in the hope that it will be useful, but
00016  * WITHOUT ANY WARRANTY; without even the implied warranty of
00017  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
00018  * General Public License for more details.
00019 
00020  * You should have received a copy of the GNU General Public License
00021  * along with NEVRAX NEL; see the file COPYING. If not, write to the
00022  * Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
00023  * MA 02111-1307, USA.
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 // TileBankLand.
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 // CTileBank.
00083 // ***************************************************************************
00084 // ***************************************************************************
00085 
00086 
00087 // ***************************************************************************
00088 const sint CTileBank::_Version=4;
00089 // ***************************************************************************
00090 CTileBank::CTileBank ()
00091 {
00092         // Default _DisplacementMap
00093         _DisplacementMap.resize (1);
00094 
00095         // Fill it with 0
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         // Version 1 not compatible
00106         if (f.isReading())
00107         {
00108                 if (streamver<2)
00109                         throw EOlderStream(f);
00110         }
00111 
00112         switch (streamver)
00113         {
00114         case 4:
00115                 // Displacement map array
00116                 f.serialCont (_DisplacementMap);
00117                 if (f.isReading())
00118                 {
00119                         // Checks
00120                         nlassert (_DisplacementMap.size()>0);
00121 
00122                         // Set first empty
00123                         _DisplacementMap[0].setEmpty ();
00124                 }
00125         case 3:
00126                 // Absolute path
00127                 f.serial (_AbsPath);
00128         case 2:
00129                 // Serial all containers
00130                 f.serialCont (_LandVector);
00131                 f.serialCont (_TileSetVector);
00132                 f.serialCont (_TileVector);
00133         }
00134 
00135         // Compute XRef in read mode
00136         if (f.isReading())
00137                 computeXRef ();
00138 
00139         // If Version<=2, remove diffuse and alpha tiles in transitions
00140         if (streamver<=2)
00141         {
00142                 // Must be reading
00143                 nlassert (f.isReading());
00144 
00145                 // Reset _AbsPath
00146                 _AbsPath="";
00147 
00148                 // Remove diffuse and additive in transition
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                         // Get xref
00157                         getTileXRef (i, tileSet, number, type);
00158 
00159                         // Transition ?
00160                         if (type==transition)
00161                         {
00162                                 // Remove diffuse bitmap
00163                                 getTileSet(tileSet)->clearTransition ((CTileSet::TTransition)number, CTile::diffuse, *this);
00164                                 
00165                                 // Remove alpha bitmap
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         // Check args
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         // Check args
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         // Look for a free tile
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         // Nothing free, add a tile at the end
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         // Check args
00248         nlassert (tileIndex>=0);
00249         nlassert (tileIndex<(sint)_TileVector.size());
00250 
00251         // Free
00252         _TileVector[tileIndex].free();
00253 
00254         // Resize tile table
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         // Resize
00288         _TileXRef.resize (_TileVector.size());
00289 
00290         // Erase number of the tileset in xref
00291         for (int tile=0; tile<(sint)_TileVector.size(); tile++)
00292                 _TileXRef[tile]._XRefTileSet=-1;
00293 
00294         // Erase number of the tileset in xref
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         // Some check
00326         nlassert ((firstTileSet>=0)&&(firstTileSet<(sint)_TileSetVector.size()));
00327         nlassert ((secondTileSet>=0)&&(secondTileSet<(sint)_TileSetVector.size()));
00328 
00329         // Xchange the sets
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 // Je parie que ce patch reste jusqu'à la fin du jeu. (Hulud)
00352 void CTileBank::makeAllPathRelative ()
00353 {
00354         // For all tiles
00355         for (sint nTile=0; nTile<(sint)_TileVector.size(); nTile++)
00356         {
00357                 // Tronc filename
00358                 char sTmpFileName[512];
00359 
00360                 // Diffuse
00361                 TroncFileName (sTmpFileName, _TileVector[nTile].getRelativeFileName (CTile::diffuse).c_str());
00362                 _TileVector[nTile].setFileName (CTile::diffuse, sTmpFileName);
00363 
00364                 // Additive
00365                 TroncFileName (sTmpFileName, _TileVector[nTile].getRelativeFileName (CTile::additive).c_str());
00366                 _TileVector[nTile].setFileName (CTile::additive, sTmpFileName);
00367 
00368                 // Alpha
00369                 TroncFileName (sTmpFileName, _TileVector[nTile].getRelativeFileName (CTile::alpha).c_str());
00370                 _TileVector[nTile].setFileName (CTile::alpha, sTmpFileName);
00371         }
00372 
00373         // For all displaces
00374         for (uint i=0; i<_DisplacementMap.size(); i++)
00375         {
00376                 // Tronc filename
00377                 char sTmpFileName[512];
00378 
00379                 TroncFileName (sTmpFileName, _DisplacementMap[i]._FileName.c_str());
00380                 _DisplacementMap[i]._FileName = sTmpFileName;
00381         }
00382 }
00383 
00384 
00385 // ***************************************************************************
00386 // Moi aussi je le parie (Yoyo).
00387 void CTileBank::makeAllExtensionDDS ()
00388 {
00389         // For all tiles
00390         for (sint nTile=0; nTile<(sint)_TileVector.size(); nTile++)
00391         {
00392                 string          tmp;
00393                 uint32          pos;
00394 
00395                 // Diffuse
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                 // Additive.
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                 // Alpha.
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         // Clean each tileset
00429         for (uint i=0; i<_TileSetVector.size(); i++)
00430         {
00431                 // Clean the tileset
00432                 _TileSetVector[i].cleanUnusedData ();
00433         }
00434 
00435         // Clear the land vector
00436         _LandVector.clear();
00437 }
00438 // ***************************************************************************
00439 CTileNoiseMap *CTileBank::getTileNoiseMap (uint tileNumber, uint tileSubNoise)
00440 {
00441         // Check tile number..
00442         if (tileNumber<_TileVector.size())
00443         {
00444                 // Get tileset number
00445                 uint tileSet=_TileXRef[tileNumber]._XRefTileSet;
00446 
00447                 // Checks
00448                 if (tileSet<_TileSetVector.size())
00449                 {
00450                         nlassert (tileSubNoise<CTileSet::CountDisplace);
00451                         nlassert (_TileSetVector[tileSet]._DisplacementBitmap[tileSubNoise]<_DisplacementMap.size());
00452 
00453                         // Return the tile noise map
00454                         CTileNoise &tileNoise=_DisplacementMap[_TileSetVector[tileSet]._DisplacementBitmap[tileSubNoise]];
00455 
00456                         // Not loaded ?
00457                         if (tileNoise._TileNoiseMap==NULL)
00458                         {
00459                                 // Load a bitmap
00460                                 CTextureFile texture (getAbsPath()+tileNoise._FileName);
00461                                 texture.loadGrayscaleAsAlpha (false);
00462                                 texture.generate ();
00463                                 texture.convertToType (CBitmap::Luminance);
00464 
00465                                 // Alloc
00466                                 tileNoise._TileNoiseMap=new CTileNoiseMap;
00467 
00468                                 // Good size ?
00469                                 if ((texture.getWidth ()==NL3D_TILE_NOISE_MAP_SIZE)&&(texture.getHeight()==NL3D_TILE_NOISE_MAP_SIZE))
00470                                 {
00471                                         // Copy
00472                                         memcpy (tileNoise._TileNoiseMap->Pixels, &texture.getPixels()[0], NL3D_TILE_NOISE_MAP_SIZE*NL3D_TILE_NOISE_MAP_SIZE);
00473 
00474                                         // Remap lumels
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                                         // This is not a normal behaviour.
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                                         // Not good size, copy a static map
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                                         // Copy
00529                                         memcpy (tileNoise._TileNoiseMap->Pixels, notGoodSizeForm, NL3D_TILE_NOISE_MAP_SIZE*NL3D_TILE_NOISE_MAP_SIZE);
00530                                 }
00531                         }
00532 
00533                         // Return the noise map
00534                         return tileNoise._TileNoiseMap;
00535                 }
00536         }
00537 
00538         // Checks
00539         nlassert (_DisplacementMap[0]._TileNoiseMap);
00540         return _DisplacementMap[0]._TileNoiseMap;
00541 }
00542 // ***************************************************************************
00543 void CTileBank::removeDisplacementMap (uint mapId)
00544 {
00545         // Checks
00546         nlassert (mapId<_DisplacementMap.size());
00547 
00548         if (mapId!=0)
00549         {
00550                 // Check if another tileSet uses it
00551                 uint tileSet;
00552                 for (tileSet=0; tileSet<_TileSetVector.size(); tileSet++)
00553                 {
00554                         // It uses it ?
00555                         uint tile;
00556                         for (tile=0; tile<CTileSet::CountDisplace; tile++)
00557                         {
00558                                 // The same ?
00559                                 if (_TileSetVector[tileSet]._DisplacementBitmap[tile]==mapId)
00560                                         // Stop
00561                                         break;
00562                         }
00563                         if (tile!=CTileSet::CountDisplace)
00564                                 break;
00565                 }
00566                 if (tileSet==_TileSetVector.size())
00567                 {
00568                         // Remove it
00569                         _DisplacementMap[mapId].reset();
00570                         
00571                         // Last element ?
00572                         if (mapId==_DisplacementMap.size()-1)
00573                         {
00574                                 // Resize the array ?
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         // Lower string
00585         string lower=fileName;
00586         lower=strlwr (lower);
00587 
00588         // Look for this texture filename
00589         uint noiseTile;
00590         for (noiseTile=0; noiseTile<_DisplacementMap.size(); noiseTile++)
00591         {
00592                 // Same name ?
00593                 if (lower==_DisplacementMap[noiseTile]._FileName)
00594                         return noiseTile;
00595         }
00596 
00597         // Look for a free space
00598         for (noiseTile=0; noiseTile<_DisplacementMap.size(); noiseTile++)
00599         {
00600                 // Same name ?
00601                 if (_DisplacementMap[noiseTile]._FileName=="")
00602                         break;
00603         }
00604         if (noiseTile==_DisplacementMap.size())
00605         {
00606                 // Add a tile
00607                 _DisplacementMap.resize (noiseTile+1);
00608         }
00609 
00610         // Set the file name
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         // Check tile number..
00636         if (tileNumber<_TileVector.size())
00637         {
00638                 // Get tileset number
00639                 uint tileSet=_TileXRef[tileNumber]._XRefTileSet;
00640 
00641                 // Checks
00642                 if (tileSet<_TileSetVector.size())
00643                 {
00644                         return _TileSetVector[tileSet].getTileVegetableDesc();
00645                 }
00646 
00647         }
00648 
00649         // if fails for any reason, return an empty tileVegetableDesc;
00650         static  CTileVegetableDesc      emptyTvd;
00651         return emptyTvd;
00652 }
00653 
00654 
00655 // ***************************************************************************
00656 void CTileBank::loadTileVegetableDescs()
00657 {
00658         // For all tileSets.
00659         uint tileSet;
00660         
00661         for(tileSet=0; tileSet<_TileSetVector.size(); tileSet++)
00662         {
00663                 // load their fileName
00664                 _TileSetVector[tileSet].loadTileVegetableDesc();
00665         }
00666 }
00667 
00668 
00669 // ***************************************************************************
00670 void    CTileBank::initTileVegetableDescs(CVegetableManager *vegetableManager)
00671 {
00672         // For all tileSets.
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 // CTile.
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         // Tmp value
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                 // Version 2, flags are not the same
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                 // Don't need invert many more
00720                 f.serial (tmp);
00721         case 0:
00722                 // Initialize flags
00723                 _Flags=0;
00724                 
00725                 // Initialize alpha name
00726                 _BitmapName[alpha]="";
00727                 
00728                 // Read free flag
00729                 f.serial (tmp);
00730 
00731                 // If free, set the flag
00732                 if (tmp)
00733                         _Flags|=NL3D_CTILE_FREE_FLAG;
00734 
00735                 // Read diffuse bitmap and additive
00736                 f.serial (_BitmapName[diffuse]);
00737                 f.serial (_BitmapName[additive]);
00738 
00739                 // Don't need bump name
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 // CTileSet.
00755 // ***************************************************************************
00756 // ***************************************************************************
00757 
00758 
00759 // ***************************************************************************
00760 const sint CTileSet::_Version=5;
00761 // ***************************************************************************
00762 const char* CTileSet::_ErrorMessage[CTileSet::errorCount]=
00763 {
00764         "No error.",                                                            // ok
00765         "Top interface is incompatible.",                       // topInterfaceProblem
00766         "Bottom interface is incompatible.",            // bottomInterfaceProblem
00767         "Left interface is incompatible.",                      // leftInterfaceProblem
00768         "Right interface is incompatible.",                     // rightInterfaceProblem
00769         "Add first a 128x128 tile.",                            // addFirstA128128
00770         "Top and bottom interface not the same.",       // topBottomNotTheSame, 
00771         "Right and left interface not the same.",       // rightLeftNotTheSame
00772         "Invalide bitmap size.",                                        // sizeInvalide
00773 };
00774 // ***************************************************************************
00775 const CTileSet::TFlagBorder CTileSet::_TransitionFlags[CTileSet::count][4]=
00776 {
00777         {_0000,_1111,_0111,_0111},      // tile 0
00778         {_0111,_1111,_0111,_1111},      // tile 1
00779         {_0000,_0111,_0000,_0111},      // tile 2
00780         {_1110,_1110,_1111,_0000},      // tile 3
00781         {_1110,_1111,_1111,_0111},      // tile 4
00782         {_0000,_1110,_0111,_0000},      // tile 5
00783 
00784         {_0000,_1111,_0001,_0001},      // tile 6
00785         {_0000,_1000,_0001,_0000},      // tile 7
00786         {_1111,_1000,_1111,_1000},      // tile 8
00787         {_1000,_1000,_1111,_0000},      // tile 9
00788         {_1000,_0000,_1000,_0000},      // tile 10
00789         {_1111,_0001,_1000,_1111},      // tile 11
00790 
00791         {_0000,_1111,_0111,_0001},      // tile 12
00792         {_0000,_1111,_0001,_0111},      // tile 13
00793         {_0111,_1111,_0001,_1111},      // tile 14
00794         {_1110,_1000,_1111,_0000},      // tile 15
00795         {_1000,_1110,_1111,_0000},      // tile 16
00796         {_1111,_0001,_1110,_1111},      // tile 17
00797 
00798         {_1000,_0000,_1110,_0000},      // tile 18
00799         {_0000,_0111,_0000,_0001},      // tile 19
00800         {_1111,_1000,_1111,_1110},      // tile 21
00801         {_0111,_0000,_0000,_1000},      // tile 21
00802         {_0000,_1000,_0111,_0000},      // tile 22
00803         {_1111,_0111,_1000,_1111},      // tile 23
00804 
00805         {_1111,_0000,_1110,_1110},      // tile 24
00806         {_1111,_1110,_1111,_1110},      // tile 25
00807         {_1110,_0000,_1110,_0000},      // tile 26
00808         {_0111,_0111,_0000,_1111},      // tile 27
00809         {_1111,_0111,_1110,_1111},      // tile 28
00810         {_0111,_0000,_0000,_1110},      // tile 29
00811 
00812         {_1111,_0000,_1000,_1000},      // tile 30
00813         {_0001,_0000,_0000,_1000},      // tile 31
00814         {_0001,_1111,_0001,_1111},      // tile 32
00815         {_0001,_0001,_0000,_1111},      // tile 33
00816         {_0000,_0001,_0000,_0001},      // tile 34
00817         {_1000,_1111,_1111,_0001},      // tile 35
00818 
00819         {_1111,_0000,_1000,_1110},      // tile 36
00820         {_1111,_0000,_1110,_1000},      // tile 37
00821         {_1000,_1111,_1111,_0111},      // tile 38
00822         {_0001,_0111,_0000,_1111},      // tile 39
00823         {_0111,_0001,_0000,_1111},      // tile 40
00824         {_1111,_1110,_1111,_1000},      // tile 41
00825 
00826         {_0000,_0001,_0000,_0111},      // tile 42
00827         {_1110,_0000,_1000,_0000},      // tile 43
00828         {_0001,_1111,_0111,_1111},      // tile 44
00829         {_0000,_1110,_0001,_0000},      // tile 45
00830         {_0001,_0000,_0000,_1110},      // tile 46
00831         {_1110,_1111,_1111,_0001}       // tile 47
00832 };
00833 // ***************************************************************************
00834 CTileSet::CTileSet ()
00835 {
00836         // Default, tileset 0
00837         _Oriented = false;
00838         uint displace;
00839         for (displace=FirstDisplace; displace<CountDisplace; displace++)
00840                 _DisplacementBitmap[displace]=0;
00841 
00842         // Default user surface data
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         // serial the user surface data
00863         if (streamver>=5)
00864         {
00865                 f.serial (SurfaceData);
00866         }
00867 
00868         // serial the oriented info which tell if the tile has a special orientation
00869         if (streamver>=4)
00870         {
00871                 f.serial (_Oriented);
00872         }
00873 
00874         // serial vegetable info.
00875         if (streamver>=3)
00876         {
00877                 // serialisze only the FileName, not the descrpitor
00878                 f.serial(_TileVegetableDescFileName);
00879         }
00880 
00881         // New version
00882         if (streamver>=2)
00883         {
00884                 uint displace;
00885                 for (displace=FirstDisplace; displace<CountDisplace; displace++)
00886                         f.serial (_DisplacementBitmap[displace]);
00887         }
00888 
00889         // Serial displacement map filename, obsolete
00890         if (streamver==1)
00891         {
00892                 // Remove obsolete data
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         // old field, border bump 128
00909         if (streamver==0)
00910                 f.serial (tmp);
00911 
00912         f.serial (_Border256[CTile::diffuse]);
00913         f.serial (_Border256[CTile::additive]);
00914 
00915         // old field, border bump 256
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                 // Reset the diffuse and alpha border if old version
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         // Create a tile
00937         sint index=bank.createTile ();
00938 
00939         // Index of the new tile
00940         indexInTileSet=_Tile128.size();
00941 
00942         // Add to the end of the list
00943         _Tile128.push_back (index);
00944 }
00945 // ***************************************************************************
00946 void CTileSet::setBorder (CTile::TBitmap type, const CTileBorder& border)
00947 {
00948         // This is our new border desc
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         // Edit a tile
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         // Self check
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         // Check
00973         if (_Border128[type].isSet())
00974         {
00975                 // Other check
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         // Create a tile
00996         sint index=bank.createTile ();
00997 
00998         // Index of the new tile
00999         indexInTileSet=_Tile256.size();
01000 
01001         // Add to the end of the list
01002         _Tile256.push_back (index);
01003 }
01004 // ***************************************************************************
01005 CTileSet::TError CTileSet::checkTile256 (CTile::TBitmap type, const CTileBorder& border, int& pixel, int& composante)
01006 {
01007         // Self check
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         // Check if prb
01016         if ((!_Border256[type].isSet())&&(_Border128[type].isSet()))
01017         {
01018                 _Border256[type]=_Border128[type];
01019                 _Border256[type].doubleSize ();
01020         }
01021 
01022         // Check
01023         if (_Border256[type].isSet())
01024         {
01025 
01026                 // Other check
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         // Edit a tile
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         // Check is not an alpha channel
01056         nlassert (type!=CTile::alpha);          // use setTileTransitionAlpha
01057 
01058         // Create a tile
01059         _BorderTransition[transition][type]=border;
01060 
01061         // Set the tile file name
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         // Check some args
01070         nlassert (rot<4);
01071 
01072         // Create a tile
01073         _BorderTransition[transition][CTile::alpha]=border;
01074 
01075         // Set the tile file name
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         // Check
01088         indexError=-1;
01089 
01090         // Top
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         // Bottom
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         // Left
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         // Right
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         // Check args
01175         nlassert (indexInTileSet>=0);
01176         nlassert (indexInTileSet<(sint)_Tile128.size());
01177 
01178         // Old index
01179         int index=_Tile128[indexInTileSet];
01180 
01181         // Erase
01182         _Tile128.erase (_Tile128.begin()+indexInTileSet);
01183         bank.freeTile (index);
01184 
01185         // Erase border if it is the last texture
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         // Check args
01194         nlassert (indexInTileSet>=0);
01195         nlassert (indexInTileSet<(sint)_Tile256.size());
01196 
01197         // Old index
01198         int index=_Tile256[indexInTileSet];
01199 
01200         // Erase
01201         _Tile256.erase (_Tile256.begin()+indexInTileSet);
01202         bank.freeTile (index);
01203 
01204         // Erase border if it is the last texture
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);   // no
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);   // no
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);   // no
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])),        // top
01329                 getOrientedBorder (bottom, getOrientedBorder (left, _TransitionFlags[transition][left])),       // bottom
01330                 getOrientedBorder (left, getOrientedBorder (top, _TransitionFlags[transition][top])),           // left
01331                 getOrientedBorder (right, getOrientedBorder (bottom, _TransitionFlags[transition][bottom])) // right
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         // Erase border if it is the last texture
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         // Erase border if it is the last texture
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         // Erase border if it is the last texture
01361         deleteBordersIfLast (bank, type);
01362 }
01363 // ***************************************************************************
01364 // Delete 128 and 256 borders if no more valid texture file name for each bitmap type.
01365 void CTileSet::deleteBordersIfLast (const CTileBank& bank, CTile::TBitmap type)
01366 {
01367         // delete is true
01368         bool bDelete=true;
01369 
01370         // iterator..
01371         std::vector<sint32>::iterator ite=_Tile128.begin();
01372 
01373         // Check all the 128x128 tiles
01374         while (ite!=_Tile128.end())
01375         {
01376                 // If the file name is valid
01377                 if (bank.getTile (*ite)->getRelativeFileName(type)!="")
01378                 {
01379                         // Don't delete, 
01380                         bDelete=false;
01381                         break;
01382                 }
01383                 ite++;
01384         }
01385         // If break, not empty, return
01386         if (ite!=_Tile128.end())
01387                 return;
01388 
01389         // Check all the 256x256 tiles
01390         ite=_Tile256.begin();
01391         while (ite!=_Tile256.end())
01392         {
01393                 // If the file name is valid
01394                 if (bank.getTile (*ite)->getRelativeFileName(type)!="")
01395                 {
01396                         // Don't delete, 
01397                         bDelete=false;
01398                         break;
01399                 }
01400                 ite++;
01401         }
01402         // If break, not empty, return
01403         if (ite!=_Tile256.end())
01404                 return;
01405 
01406 
01407         // Check all the transitions tiles
01408         sint trans;
01409         for (trans=0; trans<count; trans++)
01410         {
01411                 // Get the tile associed with the transition
01412                 int nTile=_TileTransition[trans]._Tile;
01413 
01414                 // If it is not NULL..
01415                 if (nTile!=-1)
01416                 {
01417                         // If the file name is valid
01418                         if (bank.getTile (nTile)->getRelativeFileName(type)!="")
01419                         {
01420                                 // Don't delete, 
01421                                 bDelete=false;
01422                                 break;
01423                         }
01424                 }
01425         }
01426         if (trans!=count)
01427                 return;
01428 
01429         // Ok, erase borders because no tile use it anymore
01430         _Border128[type].reset();
01431         _Border256[type].reset();
01432 }
01433 // ***************************************************************************
01434 void CTileSet::clearDisplacement (TDisplacement displacement, CTileBank& bank)
01435 {
01436         // checks
01437         nlassert (displacement>=FirstDisplace);
01438         nlassert (displacement<=LastDisplace);
01439 
01440         // Backup the id
01441         int id=_DisplacementBitmap[displacement];
01442 
01443         // Clear map id
01444         _DisplacementBitmap[displacement]=0;
01445 
01446         // Tell the bank we remove it
01447         bank.removeDisplacementMap (id);
01448 }
01449 // ***************************************************************************
01450 void CTileSet::setDisplacement (TDisplacement displacement, const std::string& fileName, CTileBank& bank)
01451 {
01452         // checks
01453         nlassert (displacement>=FirstDisplace);
01454         nlassert (displacement<=LastDisplace);
01455 
01456         // Clear it
01457         bank.removeDisplacementMap (_DisplacementBitmap[displacement]);
01458 
01459         // Get displacement map
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                         // load the TileVegetableDesc
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 // CTileBorder.
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         // Check array size
01551         nlassert (width>0);
01552         nlassert (height>0);
01553         nlassert ((sint)array.size()==width*height);
01554 
01555         // Copy size
01556         _Width=width;
01557         _Height=height;
01558 
01559         // Last line
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         // Copy top/bottom border
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         // Copy left/right border
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         // Set
01582         _Set=true;
01583 }
01584 // ***************************************************************************
01585 void CTileBorder::get (int &width, int &height, std::vector<CBGRA>& array) const
01586 {
01587         // Go
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                 // Fill
01600                 CBGRA black(0,0,0);
01601                 for (int p=0; p<_Width*_Height; p++)
01602                 {
01603                         array[p]=black;
01604                 }
01605 
01606                 // Last line
01607                 int lastLine=(_Height-1)*_Width;
01608                 int lastCol=(_Width-1);
01609 
01610                 // Copy top/bottom border
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                 // Copy left/right border
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         // Check border is initialized
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         // Check border is initialized
01670         nlassert (border.isSet());
01671 
01672         // always Alpha
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         // Copy the right
01723         std::vector<NLMISC::CBGRA> tmpLeft=_Borders[left];
01724 
01725         // Top inverted becomes left
01726         uint i, size;
01727         size=_Borders[top].size();
01728         _Borders[left].resize (size);
01729 
01730         // copy inverted
01731         for (i=0; i<size; i++)
01732                 _Borders[left][i]=_Borders[top][size-i-1];
01733 
01734         // Right become top
01735         _Borders[top]=_Borders[right];
01736 
01737         // bottom inverted becomes right
01738         size=_Borders[bottom].size();
01739         _Borders[right].resize (size);
01740 
01741         // copy inverted
01742         for (i=0; i<size; i++)
01743                 _Borders[right][i]=_Borders[bottom][size-i-1];
01744 
01745         // Left become bottom
01746         _Borders[bottom]=tmpLeft;
01747 
01748         // Invert size
01749         sint32 tmpSize=_Width;
01750         _Width=_Height;
01751         _Height=tmpSize;
01752 }
01753 
01754 // ***************************************************************************
01755 // ***************************************************************************
01756 // CTileSetTransition.
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);               // skip the old argu
01775                 }
01776                 break;
01777         case 1:
01778                 f.serial (_Tile);
01779                 break;
01780         }
01781 }
01782 // ***************************************************************************
01783 
01784 
01785 // ***************************************************************************
01786 // ***************************************************************************
01787 // CTileNoise.
01788 // ***************************************************************************
01789 // ***************************************************************************
01790 
01791 
01792 // ***************************************************************************
01793 CTileNoise::CTileNoise ()
01794 {
01795         // Not loaded
01796         _TileNoiseMap=NULL;
01797         _FileName="";
01798 }
01799 // ***************************************************************************
01800 CTileNoise::CTileNoise (const CTileNoise &src)
01801 {
01802         // Default ctor
01803         _TileNoiseMap=NULL;
01804         _FileName="";
01805 
01806         // Copy
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         // Copy the filename
01822         _FileName=src._FileName;
01823 
01824         // Tile noise map ?
01825         if (src._TileNoiseMap)
01826         {
01827                 if (_TileNoiseMap==NULL)
01828                 {
01829                         // Allocate it
01830                         _TileNoiseMap=new CTileNoiseMap;
01831                 }
01832 
01833                 // Copy the noise map
01834                 *_TileNoiseMap=*src._TileNoiseMap;
01835         }
01836         else
01837         {
01838                 // Erase the map
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         // Version
01851         f.serialVersion (0);
01852 
01853         // Serial the file name
01854         f.serial (_FileName);
01855 }
01856 // ***************************************************************************
01857 void CTileNoise::setEmpty ()
01858 {
01859         // Reset it
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         // Erase the map
01869         if (_TileNoiseMap)
01870         {
01871                 delete _TileNoiseMap;
01872                 _TileNoiseMap=NULL;
01873         }
01874 
01875         // Erase filename
01876         _FileName="";
01877 }
01878 // ***************************************************************************
01879 
01880 }       // NL3D