mirror of
https://port.numenaute.org/aleajactaest/khanat-opennel-code.git
synced 2024-11-15 12:09:06 +00:00
1934 lines
60 KiB
C++
1934 lines
60 KiB
C++
// NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
|
||
// Copyright (C) 2010 Winch Gate Property Limited
|
||
//
|
||
// This program is free software: you can redistribute it and/or modify
|
||
// it under the terms of the GNU Affero General Public License as
|
||
// published by the Free Software Foundation, either version 3 of the
|
||
// License, or (at your option) any later version.
|
||
//
|
||
// This program is distributed in the hope that it will be useful,
|
||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
// GNU Affero General Public License for more details.
|
||
//
|
||
// You should have received a copy of the GNU Affero General Public License
|
||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||
|
||
#include "std3d.h"
|
||
|
||
#include "nel/3d/tile_bank.h"
|
||
#include "nel/3d/texture_file.h"
|
||
#include "nel/3d/tile_noise_map.h"
|
||
|
||
#include "nel/misc/stream.h"
|
||
#include "nel/misc/common.h"
|
||
#include "nel/misc/path.h"
|
||
#include "nel/misc/file.h"
|
||
#include <string>
|
||
|
||
using namespace NLMISC;
|
||
using namespace std;
|
||
|
||
namespace NL3D
|
||
{
|
||
|
||
|
||
// ***************************************************************************
|
||
// ***************************************************************************
|
||
// TileBankLand.
|
||
// ***************************************************************************
|
||
// ***************************************************************************
|
||
|
||
|
||
// ***************************************************************************
|
||
const sint CTileLand::_Version=0;
|
||
// ***************************************************************************
|
||
void CTileLand::serial(NLMISC::IStream &f) throw(NLMISC::EStream)
|
||
{
|
||
(void)f.serialVersion(_Version);
|
||
|
||
f.serial (_Name);
|
||
f.serialCont (_TileSet);
|
||
}
|
||
// ***************************************************************************
|
||
void CTileLand::addTileSet (const std::string& name)
|
||
{
|
||
_TileSet.insert (name);
|
||
}
|
||
// ***************************************************************************
|
||
void CTileLand::removeTileSet (const std::string& name)
|
||
{
|
||
_TileSet.erase (name);
|
||
}
|
||
// ***************************************************************************
|
||
void CTileLand::setName (const std::string& name)
|
||
{
|
||
_Name=name;
|
||
};
|
||
// ***************************************************************************
|
||
|
||
|
||
// ***************************************************************************
|
||
// ***************************************************************************
|
||
// CTileBank.
|
||
// ***************************************************************************
|
||
// ***************************************************************************
|
||
|
||
|
||
// ***************************************************************************
|
||
const sint CTileBank::_Version=4;
|
||
// ***************************************************************************
|
||
CTileBank::CTileBank ()
|
||
{
|
||
// Default _DisplacementMap
|
||
_DisplacementMap.resize (1);
|
||
|
||
// Fill it with 0
|
||
_DisplacementMap[0].setEmpty ();
|
||
}
|
||
// ***************************************************************************
|
||
void CTileBank::serial(NLMISC::IStream &f) throw(NLMISC::EStream)
|
||
{
|
||
f.serialCheck (std::string ("BANK"));
|
||
|
||
sint streamver = f.serialVersion(_Version);
|
||
|
||
// Version 1 not compatible
|
||
if (f.isReading())
|
||
{
|
||
if (streamver<2)
|
||
throw EOlderStream(f);
|
||
}
|
||
|
||
switch (streamver)
|
||
{
|
||
case 4:
|
||
// Displacement map array
|
||
f.serialCont (_DisplacementMap);
|
||
if (f.isReading())
|
||
{
|
||
// Checks
|
||
nlassert (_DisplacementMap.size()>0);
|
||
|
||
// Set first empty
|
||
_DisplacementMap[0].setEmpty ();
|
||
}
|
||
case 3:
|
||
// Absolute path
|
||
f.serial (_AbsPath);
|
||
case 2:
|
||
// Serial all containers
|
||
f.serialCont (_LandVector);
|
||
f.serialCont (_TileSetVector);
|
||
f.serialCont (_TileVector);
|
||
}
|
||
|
||
// Compute XRef in read mode
|
||
if (f.isReading())
|
||
computeXRef ();
|
||
|
||
// If Version<=2, remove diffuse and alpha tiles in transitions
|
||
if (streamver<=2)
|
||
{
|
||
// Must be reading
|
||
nlassert (f.isReading());
|
||
|
||
// Reset _AbsPath
|
||
_AbsPath="";
|
||
|
||
// Remove diffuse and additive in transition
|
||
uint tileCount=(uint)getTileCount ();
|
||
for (uint i=0; i<tileCount; i++)
|
||
{
|
||
int tileSet;
|
||
int number;
|
||
TTileType type;
|
||
|
||
// Get xref
|
||
getTileXRef (i, tileSet, number, type);
|
||
|
||
// Transition ?
|
||
if (type==transition)
|
||
{
|
||
// Remove diffuse bitmap
|
||
getTileSet(tileSet)->clearTransition ((CTileSet::TTransition)number, CTile::diffuse, *this);
|
||
|
||
// Remove alpha bitmap
|
||
getTileSet(tileSet)->clearTransition ((CTileSet::TTransition)number, CTile::alpha, *this);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
// ***************************************************************************
|
||
sint CTileBank::addLand (const std::string& name)
|
||
{
|
||
sint last=_LandVector.size();
|
||
_LandVector.push_back(CTileLand());
|
||
_LandVector[last].setName (name);
|
||
return last;
|
||
}
|
||
// ***************************************************************************
|
||
void CTileBank::removeLand (sint landIndex)
|
||
{
|
||
// Check args
|
||
nlassert (landIndex>=0);
|
||
nlassert (landIndex<(sint)_LandVector.size());
|
||
|
||
_LandVector.erase (_LandVector.begin ()+landIndex);
|
||
}
|
||
// ***************************************************************************
|
||
sint CTileBank::addTileSet (const std::string& name)
|
||
{
|
||
sint last=_TileSetVector.size();
|
||
_TileSetVector.push_back(CTileSet());
|
||
_TileSetVector[last].setName (name);
|
||
for (int i=0; i<CTileSet::count; i++)
|
||
{
|
||
_TileSetVector[last]._TileTransition[i]._Tile=createTile ();
|
||
}
|
||
return last;
|
||
}
|
||
// ***************************************************************************
|
||
void CTileBank::removeTileSet (sint setIndex)
|
||
{
|
||
// Check args
|
||
nlassert (setIndex>=0);
|
||
nlassert (setIndex<(sint)_TileSetVector.size());
|
||
|
||
for (int i=0; i<CTileSet::count; i++)
|
||
{
|
||
int index=_TileSetVector[setIndex]._TileTransition[i]._Tile;
|
||
if (index!=-1)
|
||
freeTile (index);
|
||
}
|
||
_TileSetVector.erase (_TileSetVector.begin ()+setIndex);
|
||
}
|
||
// ***************************************************************************
|
||
void CTileBank::clear ()
|
||
{
|
||
_LandVector.clear ();
|
||
_TileSetVector.clear ();
|
||
_TileVector.clear ();
|
||
_TileXRef.clear ();
|
||
_DisplacementMap.clear ();
|
||
_AbsPath.clear ();
|
||
}
|
||
// ***************************************************************************
|
||
sint CTileBank::createTile ()
|
||
{
|
||
// Look for a free tile
|
||
for (int i=0; i<(sint)_TileVector.size(); i++)
|
||
{
|
||
if (_TileVector[i].isFree())
|
||
{
|
||
_TileVector[i].setFileName (CTile::diffuse, "");
|
||
_TileVector[i].setFileName (CTile::additive, "");
|
||
_TileVector[i].setFileName (CTile::alpha, "");
|
||
return i;
|
||
}
|
||
}
|
||
|
||
// Nothing free, add a tile at the end
|
||
_TileVector.push_back (CTile());
|
||
_TileVector[_TileVector.size()-1].setFileName (CTile::diffuse, "");
|
||
_TileVector[_TileVector.size()-1].setFileName (CTile::additive, "");
|
||
_TileVector[_TileVector.size()-1].setFileName (CTile::alpha, "");
|
||
return _TileVector.size()-1;
|
||
}
|
||
// ***************************************************************************
|
||
void CTileBank::freeTile (int tileIndex)
|
||
{
|
||
// Check args
|
||
nlassert (tileIndex>=0);
|
||
nlassert (tileIndex<(sint)_TileVector.size());
|
||
|
||
// Free
|
||
_TileVector[tileIndex].free();
|
||
|
||
// Resize tile table
|
||
int i;
|
||
for (i=(sint)_TileVector.size()-1; i>=0; i--)
|
||
{
|
||
if (!_TileVector[i].isFree ())
|
||
break;
|
||
}
|
||
if (i<(sint)_TileVector.size()-1)
|
||
_TileVector.resize (i+1);
|
||
}
|
||
// ***************************************************************************
|
||
sint CTileBank::getNumBitmap (CTile::TBitmap bitmap) const
|
||
{
|
||
std::set<std::string> setString;
|
||
for (int i=0; i<(sint)_TileVector.size(); i++)
|
||
{
|
||
if (!_TileVector[i].isFree())
|
||
{
|
||
const std::string &str=_TileVector[i].getRelativeFileName (bitmap);
|
||
if (str!="")
|
||
{
|
||
std::vector<char> vect (str.length()+1);
|
||
memcpy (&*vect.begin(), str.c_str(), str.length()+1);
|
||
toLower(&*vect.begin());
|
||
setString.insert (std::string (&*vect.begin()));
|
||
}
|
||
}
|
||
}
|
||
return setString.size();
|
||
}
|
||
// ***************************************************************************
|
||
void CTileBank::computeXRef ()
|
||
{
|
||
// Resize
|
||
_TileXRef.resize (_TileVector.size());
|
||
|
||
// Erase number of the tileset in xref
|
||
for (int tile=0; tile<(sint)_TileVector.size(); tile++)
|
||
_TileXRef[tile]._XRefTileSet=-1;
|
||
|
||
// Erase number of the tileset in xref
|
||
for (int s=0; s<(sint)_TileSetVector.size(); s++)
|
||
{
|
||
int t;
|
||
CTileSet *tileSet=getTileSet (s);
|
||
for (t=0; t<tileSet->getNumTile128(); t++)
|
||
{
|
||
int index=tileSet->getTile128 (t);
|
||
_TileXRef[index]._XRefTileSet=s;
|
||
_TileXRef[index]._XRefTileNumber=t;
|
||
_TileXRef[index]._XRefTileType=_128x128;
|
||
}
|
||
for (t=0; t<tileSet->getNumTile256(); t++)
|
||
{
|
||
int index=tileSet->getTile256 (t);
|
||
_TileXRef[index]._XRefTileSet=s;
|
||
_TileXRef[index]._XRefTileNumber=t;
|
||
_TileXRef[index]._XRefTileType=_256x256;
|
||
}
|
||
for (t=0; t<CTileSet::count; t++)
|
||
{
|
||
int index=tileSet->getTransition (t)->getTile();
|
||
_TileXRef[index]._XRefTileSet=s;
|
||
_TileXRef[index]._XRefTileNumber=t;
|
||
_TileXRef[index]._XRefTileType=transition;
|
||
}
|
||
}
|
||
}
|
||
// ***************************************************************************
|
||
void CTileBank::xchgTileset (sint firstTileSet, sint secondTileSet)
|
||
{
|
||
// Some check
|
||
nlassert ((firstTileSet>=0)&&(firstTileSet<(sint)_TileSetVector.size()));
|
||
nlassert ((secondTileSet>=0)&&(secondTileSet<(sint)_TileSetVector.size()));
|
||
|
||
// Xchange the sets
|
||
CTileSet tmp=_TileSetVector[firstTileSet];
|
||
_TileSetVector[firstTileSet]=_TileSetVector[secondTileSet];
|
||
_TileSetVector[secondTileSet]=tmp;
|
||
}
|
||
// ***************************************************************************
|
||
void TroncFileName (char* sDest, const char* sSrc)
|
||
{
|
||
const char* ptr=strrchr (sSrc, '\\');
|
||
if (ptr==NULL)
|
||
ptr=strrchr (sSrc, '/');
|
||
if (ptr)
|
||
{
|
||
ptr++;
|
||
strcpy (sDest, ptr);
|
||
}
|
||
else
|
||
{
|
||
strcpy (sDest, sSrc);
|
||
}
|
||
}
|
||
// ***************************************************************************
|
||
// Je parie que ce patch reste jusqu'<27> la fin du jeu. (Hulud)
|
||
void CTileBank::makeAllPathRelative ()
|
||
{
|
||
// For all tiles
|
||
for (sint nTile=0; nTile<(sint)_TileVector.size(); nTile++)
|
||
{
|
||
// Tronc filename
|
||
char sTmpFileName[512];
|
||
|
||
// Diffuse
|
||
TroncFileName (sTmpFileName, _TileVector[nTile].getRelativeFileName (CTile::diffuse).c_str());
|
||
_TileVector[nTile].setFileName (CTile::diffuse, sTmpFileName);
|
||
|
||
// Additive
|
||
TroncFileName (sTmpFileName, _TileVector[nTile].getRelativeFileName (CTile::additive).c_str());
|
||
_TileVector[nTile].setFileName (CTile::additive, sTmpFileName);
|
||
|
||
// Alpha
|
||
TroncFileName (sTmpFileName, _TileVector[nTile].getRelativeFileName (CTile::alpha).c_str());
|
||
_TileVector[nTile].setFileName (CTile::alpha, sTmpFileName);
|
||
}
|
||
|
||
// For all displaces
|
||
for (uint i=0; i<_DisplacementMap.size(); i++)
|
||
{
|
||
// Tronc filename
|
||
char sTmpFileName[512];
|
||
|
||
TroncFileName (sTmpFileName, _DisplacementMap[i]._FileName.c_str());
|
||
_DisplacementMap[i]._FileName = sTmpFileName;
|
||
}
|
||
}
|
||
|
||
|
||
// ***************************************************************************
|
||
// Moi aussi je le parie (Yoyo).
|
||
void CTileBank::makeAllExtensionDDS ()
|
||
{
|
||
// For all tiles
|
||
for (sint nTile=0; nTile<(sint)_TileVector.size(); nTile++)
|
||
{
|
||
string tmp;
|
||
string::size_type pos;
|
||
|
||
// Diffuse
|
||
tmp= _TileVector[nTile].getRelativeFileName (CTile::diffuse);
|
||
pos= tmp.rfind(".tga");
|
||
if(pos!= string::npos)
|
||
{
|
||
tmp.replace(pos, 4, ".dds");
|
||
_TileVector[nTile].setFileName (CTile::diffuse, tmp);
|
||
}
|
||
|
||
// Additive.
|
||
tmp= _TileVector[nTile].getRelativeFileName (CTile::additive);
|
||
pos= tmp.rfind(".tga");
|
||
if(pos!= string::npos)
|
||
{
|
||
tmp.replace(pos, 4, ".dds");
|
||
_TileVector[nTile].setFileName (CTile::additive, tmp);
|
||
}
|
||
|
||
// Alpha.
|
||
tmp= _TileVector[nTile].getRelativeFileName (CTile::alpha);
|
||
pos= tmp.rfind(".tga");
|
||
if(pos!= string::npos)
|
||
{
|
||
tmp.replace(pos, 4, ".dds");
|
||
_TileVector[nTile].setFileName (CTile::alpha, tmp);
|
||
}
|
||
|
||
}
|
||
|
||
}
|
||
// ***************************************************************************
|
||
void CTileBank::cleanUnusedData ()
|
||
{
|
||
// Clean each tileset
|
||
for (uint i=0; i<_TileSetVector.size(); i++)
|
||
{
|
||
// Clean the tileset
|
||
_TileSetVector[i].cleanUnusedData ();
|
||
}
|
||
|
||
// Clear the land vector
|
||
_LandVector.clear();
|
||
}
|
||
// ***************************************************************************
|
||
CTileNoiseMap *CTileBank::getTileNoiseMap (uint tileNumber, uint tileSubNoise)
|
||
{
|
||
if (_DisplacementMap.size() == 0)
|
||
{
|
||
// it happens when serial a tile bank with version < 4
|
||
return NULL;
|
||
}
|
||
|
||
// Check tile number..
|
||
if (tileNumber<_TileVector.size())
|
||
{
|
||
// Get tileset number
|
||
uint tileSet=_TileXRef[tileNumber]._XRefTileSet;
|
||
|
||
// Checks
|
||
if (tileSet<_TileSetVector.size())
|
||
{
|
||
nlassert (tileSubNoise<CTileSet::CountDisplace);
|
||
//nlassert (_TileSetVector[tileSet]._DisplacementBitmap[tileSubNoise]<_DisplacementMap.size());
|
||
|
||
if (_TileSetVector[tileSet]._DisplacementBitmap[tileSubNoise]>=_DisplacementMap.size())
|
||
return NULL;
|
||
|
||
// Return the tile noise map
|
||
CTileNoise &tileNoise=_DisplacementMap[_TileSetVector[tileSet]._DisplacementBitmap[tileSubNoise]];
|
||
|
||
// Not loaded ?
|
||
if (tileNoise._TileNoiseMap==NULL)
|
||
{
|
||
// Load a bitmap
|
||
CTextureFile texture (getAbsPath()+tileNoise._FileName);
|
||
texture.loadGrayscaleAsAlpha (false);
|
||
texture.generate ();
|
||
texture.convertToType (CBitmap::Luminance);
|
||
|
||
// Alloc
|
||
tileNoise._TileNoiseMap=new CTileNoiseMap;
|
||
|
||
// Good size ?
|
||
if ((texture.getWidth ()==NL3D_TILE_NOISE_MAP_SIZE)&&(texture.getHeight()==NL3D_TILE_NOISE_MAP_SIZE))
|
||
{
|
||
// Copy
|
||
memcpy (tileNoise._TileNoiseMap->Pixels, &texture.getPixels()[0], NL3D_TILE_NOISE_MAP_SIZE*NL3D_TILE_NOISE_MAP_SIZE);
|
||
|
||
// Remap lumels
|
||
for (uint i=0; i<NL3D_TILE_NOISE_MAP_SIZE*NL3D_TILE_NOISE_MAP_SIZE; i++)
|
||
{
|
||
tileNoise._TileNoiseMap->Pixels[i]=(sint8)((uint8)tileNoise._TileNoiseMap->Pixels[i]-128);
|
||
if (tileNoise._TileNoiseMap->Pixels[i]==-128)
|
||
tileNoise._TileNoiseMap->Pixels[i]=-127;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
// This is not a normal behaviour.
|
||
string pathname= getAbsPath()+tileNoise._FileName;
|
||
if( texture.getWidth ()==0 || texture.getHeight ()==0 )
|
||
nlwarning("TileNoiseMap not found: %s.", pathname.c_str());
|
||
else
|
||
nlwarning("Bad TileNoiseMap size: %s.", pathname.c_str());
|
||
|
||
// Not good size, copy a static map
|
||
sint8 notGoodSizeForm[NL3D_TILE_NOISE_MAP_SIZE*NL3D_TILE_NOISE_MAP_SIZE]=
|
||
{
|
||
00, 00, 00, 00, 00, 00, 00, 00, 00, 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, 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,
|
||
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,
|
||
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,
|
||
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,
|
||
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,
|
||
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,
|
||
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,
|
||
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,
|
||
00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
|
||
00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
|
||
00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
|
||
00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
|
||
00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
|
||
00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
|
||
00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
|
||
00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
|
||
00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
|
||
00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
|
||
00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
|
||
00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
|
||
00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
|
||
00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
|
||
00, 00, 00, 00, 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,
|
||
00, 00, 00, 00, 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,
|
||
00, 00, 00, 00, 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,
|
||
00, 00, 00, 00, 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,
|
||
00, 00, 00, 00, 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,
|
||
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,
|
||
00, 00, 00, 00, 00, 00, 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,
|
||
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,
|
||
00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00
|
||
};
|
||
|
||
// Copy
|
||
memcpy (tileNoise._TileNoiseMap->Pixels, notGoodSizeForm, NL3D_TILE_NOISE_MAP_SIZE*NL3D_TILE_NOISE_MAP_SIZE);
|
||
}
|
||
}
|
||
|
||
// Return the noise map
|
||
return tileNoise._TileNoiseMap;
|
||
}
|
||
}
|
||
|
||
if (_DisplacementMap.size()==0 || _DisplacementMap[0]._TileNoiseMap)
|
||
return NULL;
|
||
|
||
// Checks
|
||
nlassert (_DisplacementMap[0]._TileNoiseMap);
|
||
return _DisplacementMap[0]._TileNoiseMap;
|
||
}
|
||
// ***************************************************************************
|
||
void CTileBank::removeDisplacementMap (uint mapId)
|
||
{
|
||
// Checks
|
||
nlassert (mapId<_DisplacementMap.size());
|
||
|
||
if (mapId!=0)
|
||
{
|
||
// Check if another tileSet uses it
|
||
uint tileSet;
|
||
for (tileSet=0; tileSet<_TileSetVector.size(); tileSet++)
|
||
{
|
||
// It uses it ?
|
||
uint tile;
|
||
for (tile=0; tile<CTileSet::CountDisplace; tile++)
|
||
{
|
||
// The same ?
|
||
if (_TileSetVector[tileSet]._DisplacementBitmap[tile]==mapId)
|
||
// Stop
|
||
break;
|
||
}
|
||
if (tile!=CTileSet::CountDisplace)
|
||
break;
|
||
}
|
||
if (tileSet==_TileSetVector.size())
|
||
{
|
||
// Remove it
|
||
_DisplacementMap[mapId].reset();
|
||
|
||
// Last element ?
|
||
if (mapId==_DisplacementMap.size()-1)
|
||
{
|
||
// Resize the array ?
|
||
while ((mapId>0)&&(_DisplacementMap[mapId]._FileName==""))
|
||
_DisplacementMap.resize (mapId--);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
// ***************************************************************************
|
||
uint CTileBank::getDisplacementMap (const string &fileName)
|
||
{
|
||
// Lower string
|
||
string lower=toLower(fileName);
|
||
|
||
// Look for this texture filename
|
||
uint noiseTile;
|
||
for (noiseTile=0; noiseTile<_DisplacementMap.size(); noiseTile++)
|
||
{
|
||
// Same name ?
|
||
if (lower==_DisplacementMap[noiseTile]._FileName)
|
||
return noiseTile;
|
||
}
|
||
|
||
// Look for a free space
|
||
for (noiseTile=0; noiseTile<_DisplacementMap.size(); noiseTile++)
|
||
{
|
||
// Same name ?
|
||
if (_DisplacementMap[noiseTile]._FileName=="")
|
||
break;
|
||
}
|
||
if (noiseTile==_DisplacementMap.size())
|
||
{
|
||
// Add a tile
|
||
_DisplacementMap.resize (noiseTile+1);
|
||
}
|
||
|
||
// Set the file name
|
||
_DisplacementMap[noiseTile]._FileName=lower;
|
||
|
||
return noiseTile;
|
||
}
|
||
// ***************************************************************************
|
||
const char* CTileBank::getDisplacementMap (uint noiseMap)
|
||
{
|
||
return _DisplacementMap[noiseMap]._FileName.c_str();
|
||
}
|
||
// ***************************************************************************
|
||
void CTileBank::setDisplacementMap (uint noiseMap, const char *newName)
|
||
{
|
||
_DisplacementMap[noiseMap]._FileName=newName;
|
||
}
|
||
// ***************************************************************************
|
||
uint CTileBank::getDisplacementMapCount () const
|
||
{
|
||
return _DisplacementMap.size();
|
||
}
|
||
|
||
|
||
// ***************************************************************************
|
||
const CTileVegetableDesc &CTileBank::getTileVegetableDesc(uint tileNumber) const
|
||
{
|
||
// Check tile number..
|
||
if (tileNumber<_TileVector.size())
|
||
{
|
||
// Get tileset number
|
||
uint tileSet=_TileXRef[tileNumber]._XRefTileSet;
|
||
|
||
// Checks
|
||
if (tileSet<_TileSetVector.size())
|
||
{
|
||
return _TileSetVector[tileSet].getTileVegetableDesc();
|
||
}
|
||
|
||
}
|
||
|
||
// if fails for any reason, return an empty tileVegetableDesc;
|
||
static CTileVegetableDesc emptyTvd;
|
||
return emptyTvd;
|
||
}
|
||
|
||
|
||
// ***************************************************************************
|
||
void CTileBank::loadTileVegetableDescs()
|
||
{
|
||
// For all tileSets.
|
||
uint tileSet;
|
||
|
||
for(tileSet=0; tileSet<_TileSetVector.size(); tileSet++)
|
||
{
|
||
// load their fileName
|
||
_TileSetVector[tileSet].loadTileVegetableDesc();
|
||
}
|
||
}
|
||
|
||
|
||
// ***************************************************************************
|
||
void CTileBank::initTileVegetableDescs(CVegetableManager *vegetableManager)
|
||
{
|
||
// For all tileSets.
|
||
uint tileSet;
|
||
|
||
for(tileSet=0; tileSet<_TileSetVector.size(); tileSet++)
|
||
{
|
||
CTileVegetableDesc &tvd= _TileSetVector[tileSet].getTileVegetableDesc();
|
||
tvd.registerToManager(vegetableManager);
|
||
}
|
||
}
|
||
|
||
|
||
// ***************************************************************************
|
||
void CTileBank::postfixTileFilename (const char *postfix)
|
||
{
|
||
// For each tiles
|
||
uint tile;
|
||
for (tile=0; tile<_TileVector.size (); tile++)
|
||
{
|
||
// For each bitmap
|
||
uint bitmap;
|
||
for (bitmap=0; bitmap<CTile::bitmapCount; bitmap++)
|
||
{
|
||
string &filename = _TileVector[tile]._BitmapName[bitmap];
|
||
if (!filename.empty())
|
||
{
|
||
string ext = CFile::getExtension(filename);
|
||
string name = CFile::getFilenameWithoutExtension(filename);
|
||
filename = CFile::getPath (filename);
|
||
filename += name;
|
||
filename += postfix;
|
||
filename += ".";
|
||
filename += ext;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
// ***************************************************************************
|
||
void CTileBank::postfixTileVegetableDesc (const char *postfix)
|
||
{
|
||
// For each tiles
|
||
uint tileSet;
|
||
for (tileSet=0; tileSet<_TileSetVector.size (); tileSet++)
|
||
{
|
||
string &filename = _TileSetVector[tileSet]._TileVegetableDescFileName;
|
||
if (!filename.empty())
|
||
{
|
||
string ext = CFile::getExtension(filename);
|
||
string name = CFile::getFilenameWithoutExtension(filename);
|
||
filename = CFile::getPath (filename);
|
||
filename += name;
|
||
filename += postfix;
|
||
filename += ".";
|
||
filename += ext;
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
// ***************************************************************************
|
||
// ***************************************************************************
|
||
// CTile.
|
||
// ***************************************************************************
|
||
// ***************************************************************************
|
||
|
||
|
||
// ***************************************************************************
|
||
const sint CTile::_Version=4;
|
||
// ***************************************************************************
|
||
void CTile::serial(NLMISC::IStream &f) throw(NLMISC::EStream)
|
||
{
|
||
sint streamver = f.serialVersion(_Version);
|
||
|
||
// Tmp value
|
||
bool tmp;
|
||
string tmpStr;
|
||
|
||
switch (streamver)
|
||
{
|
||
case 4:
|
||
case 3:
|
||
case 2:
|
||
f.serial (_Flags);
|
||
|
||
// Version 2, flags are not the same
|
||
if (streamver==2)
|
||
_Flags=(_Flags&NL3D_CTILE_ROT_MASK)|(_Flags&NL3D_CTILE_GROUP_MASK_V2)|(((_Flags&NL3D_CTILE_FREE_FLAG_V2)!=0)?NL3D_CTILE_FREE_FLAG:0);
|
||
if (streamver==3)
|
||
_Flags=(_Flags&NL3D_CTILE_ROT_MASK)|(_Flags&NL3D_CTILE_GROUP_MASK_V3)|(((_Flags&NL3D_CTILE_FREE_FLAG_V3)!=0)?NL3D_CTILE_FREE_FLAG:0);
|
||
|
||
f.serial (_BitmapName[diffuse]);
|
||
f.serial (_BitmapName[additive]);
|
||
f.serial (_BitmapName[alpha]);
|
||
break;
|
||
case 1:
|
||
// Don't need invert many more
|
||
f.serial (tmp);
|
||
case 0:
|
||
// Initialize flags
|
||
_Flags=0;
|
||
|
||
// Initialize alpha name
|
||
_BitmapName[alpha]="";
|
||
|
||
// Read free flag
|
||
f.serial (tmp);
|
||
|
||
// If free, set the flag
|
||
if (tmp)
|
||
_Flags|=NL3D_CTILE_FREE_FLAG;
|
||
|
||
// Read diffuse bitmap and additive
|
||
f.serial (_BitmapName[diffuse]);
|
||
f.serial (_BitmapName[additive]);
|
||
|
||
// Don't need bump name
|
||
f.serial (tmpStr);
|
||
|
||
break;
|
||
}
|
||
}
|
||
// ***************************************************************************
|
||
void CTile::clearTile (CTile::TBitmap type)
|
||
{
|
||
_BitmapName[type]="";
|
||
}
|
||
|
||
|
||
// ***************************************************************************
|
||
// ***************************************************************************
|
||
// CTileSet.
|
||
// ***************************************************************************
|
||
// ***************************************************************************
|
||
|
||
|
||
// ***************************************************************************
|
||
const sint CTileSet::_Version=5;
|
||
// ***************************************************************************
|
||
const char* CTileSet::_ErrorMessage[CTileSet::errorCount]=
|
||
{
|
||
"No error.", // ok
|
||
"Top interface is incompatible.", // topInterfaceProblem
|
||
"Bottom interface is incompatible.", // bottomInterfaceProblem
|
||
"Left interface is incompatible.", // leftInterfaceProblem
|
||
"Right interface is incompatible.", // rightInterfaceProblem
|
||
"Add first a 128x128 tile.", // addFirstA128128
|
||
"Top and bottom interface not the same.", // topBottomNotTheSame,
|
||
"Right and left interface not the same.", // rightLeftNotTheSame
|
||
"Invalide bitmap size.", // sizeInvalide
|
||
};
|
||
// ***************************************************************************
|
||
const CTileSet::TFlagBorder CTileSet::_TransitionFlags[CTileSet::count][4]=
|
||
{
|
||
{_0000,_1111,_0111,_0111}, // tile 0
|
||
{_0111,_1111,_0111,_1111}, // tile 1
|
||
{_0000,_0111,_0000,_0111}, // tile 2
|
||
{_1110,_1110,_1111,_0000}, // tile 3
|
||
{_1110,_1111,_1111,_0111}, // tile 4
|
||
{_0000,_1110,_0111,_0000}, // tile 5
|
||
|
||
{_0000,_1111,_0001,_0001}, // tile 6
|
||
{_0000,_1000,_0001,_0000}, // tile 7
|
||
{_1111,_1000,_1111,_1000}, // tile 8
|
||
{_1000,_1000,_1111,_0000}, // tile 9
|
||
{_1000,_0000,_1000,_0000}, // tile 10
|
||
{_1111,_0001,_1000,_1111}, // tile 11
|
||
|
||
{_0000,_1111,_0111,_0001}, // tile 12
|
||
{_0000,_1111,_0001,_0111}, // tile 13
|
||
{_0111,_1111,_0001,_1111}, // tile 14
|
||
{_1110,_1000,_1111,_0000}, // tile 15
|
||
{_1000,_1110,_1111,_0000}, // tile 16
|
||
{_1111,_0001,_1110,_1111}, // tile 17
|
||
|
||
{_1000,_0000,_1110,_0000}, // tile 18
|
||
{_0000,_0111,_0000,_0001}, // tile 19
|
||
{_1111,_1000,_1111,_1110}, // tile 21
|
||
{_0111,_0000,_0000,_1000}, // tile 21
|
||
{_0000,_1000,_0111,_0000}, // tile 22
|
||
{_1111,_0111,_1000,_1111}, // tile 23
|
||
|
||
{_1111,_0000,_1110,_1110}, // tile 24
|
||
{_1111,_1110,_1111,_1110}, // tile 25
|
||
{_1110,_0000,_1110,_0000}, // tile 26
|
||
{_0111,_0111,_0000,_1111}, // tile 27
|
||
{_1111,_0111,_1110,_1111}, // tile 28
|
||
{_0111,_0000,_0000,_1110}, // tile 29
|
||
|
||
{_1111,_0000,_1000,_1000}, // tile 30
|
||
{_0001,_0000,_0000,_1000}, // tile 31
|
||
{_0001,_1111,_0001,_1111}, // tile 32
|
||
{_0001,_0001,_0000,_1111}, // tile 33
|
||
{_0000,_0001,_0000,_0001}, // tile 34
|
||
{_1000,_1111,_1111,_0001}, // tile 35
|
||
|
||
{_1111,_0000,_1000,_1110}, // tile 36
|
||
{_1111,_0000,_1110,_1000}, // tile 37
|
||
{_1000,_1111,_1111,_0111}, // tile 38
|
||
{_0001,_0111,_0000,_1111}, // tile 39
|
||
{_0111,_0001,_0000,_1111}, // tile 40
|
||
{_1111,_1110,_1111,_1000}, // tile 41
|
||
|
||
{_0000,_0001,_0000,_0111}, // tile 42
|
||
{_1110,_0000,_1000,_0000}, // tile 43
|
||
{_0001,_1111,_0111,_1111}, // tile 44
|
||
{_0000,_1110,_0001,_0000}, // tile 45
|
||
{_0001,_0000,_0000,_1110}, // tile 46
|
||
{_1110,_1111,_1111,_0001} // tile 47
|
||
};
|
||
// ***************************************************************************
|
||
CTileSet::CTileSet ()
|
||
{
|
||
// Default, tileset 0
|
||
_Oriented = false;
|
||
uint displace;
|
||
for (displace=FirstDisplace; displace<CountDisplace; displace++)
|
||
_DisplacementBitmap[displace]=0;
|
||
|
||
// Default user surface data
|
||
SurfaceData = 0;
|
||
}
|
||
// ***************************************************************************
|
||
void CTileSet::setName (const std::string& name)
|
||
{
|
||
_Name=name;
|
||
}
|
||
// ***************************************************************************
|
||
const std::string& CTileSet::getName () const
|
||
{
|
||
return _Name;
|
||
}
|
||
// ***************************************************************************
|
||
void CTileSet::serial(NLMISC::IStream &f) throw(NLMISC::EStream)
|
||
{
|
||
sint streamver = f.serialVersion(_Version);
|
||
|
||
CTileBorder tmp;
|
||
|
||
// serial the user surface data
|
||
if (streamver>=5)
|
||
{
|
||
f.serial (SurfaceData);
|
||
}
|
||
|
||
// serial the oriented info which tell if the tile has a special orientation
|
||
if (streamver>=4)
|
||
{
|
||
f.serial (_Oriented);
|
||
}
|
||
|
||
// serial vegetable info.
|
||
if (streamver>=3)
|
||
{
|
||
// serialisze only the FileName, not the descrpitor
|
||
f.serial(_TileVegetableDescFileName);
|
||
}
|
||
|
||
// New version
|
||
if (streamver>=2)
|
||
{
|
||
uint displace;
|
||
for (displace=FirstDisplace; displace<CountDisplace; displace++)
|
||
f.serial (_DisplacementBitmap[displace]);
|
||
}
|
||
|
||
// Serial displacement map filename, obsolete
|
||
if (streamver==1)
|
||
{
|
||
// Remove obsolete data
|
||
string tmp;
|
||
for (uint displace=FirstDisplace; displace<CountDisplace; displace++)
|
||
f.serial (tmp);
|
||
}
|
||
|
||
int i;
|
||
f.serial (_Name);
|
||
f.serialCont (_Tile128);
|
||
f.serialCont (_Tile256);
|
||
for (i=0; i<count; i++)
|
||
f.serial (_TileTransition[i]);
|
||
f.serialCont (_ChildName);
|
||
f.serial (_Border128[CTile::diffuse]);
|
||
f.serial (_Border128[CTile::additive]);
|
||
|
||
// old field, border bump 128
|
||
if (streamver==0)
|
||
f.serial (tmp);
|
||
|
||
f.serial (_Border256[CTile::diffuse]);
|
||
f.serial (_Border256[CTile::additive]);
|
||
|
||
// old field, border bump 256
|
||
if (streamver==0)
|
||
f.serial (tmp);
|
||
|
||
for (i=0; i<count; i++)
|
||
{
|
||
f.serial (_BorderTransition[i][CTile::diffuse]);
|
||
f.serial (_BorderTransition[i][CTile::additive]);
|
||
f.serial (_BorderTransition[i][CTile::alpha]);
|
||
|
||
// Reset the diffuse and alpha border if old version
|
||
if (streamver==0)
|
||
{
|
||
_BorderTransition[i][CTile::diffuse].reset();
|
||
_BorderTransition[i][CTile::alpha].reset();
|
||
}
|
||
}
|
||
}
|
||
// ***************************************************************************
|
||
void CTileSet::addTile128 (int& indexInTileSet, CTileBank& bank)
|
||
{
|
||
// Create a tile
|
||
sint index=bank.createTile ();
|
||
|
||
// Index of the new tile
|
||
indexInTileSet=_Tile128.size();
|
||
|
||
// Add to the end of the list
|
||
_Tile128.push_back (index);
|
||
}
|
||
// ***************************************************************************
|
||
void CTileSet::setBorder (CTile::TBitmap type, const CTileBorder& border)
|
||
{
|
||
// This is our new border desc
|
||
_Border128[type]=border;
|
||
_Border256[type]=border;
|
||
_Border256[type].doubleSize ();
|
||
}
|
||
// ***************************************************************************
|
||
void CTileSet::setTile128 (int indexInTileSet, const std::string& name, CTile::TBitmap type, CTileBank& bank)
|
||
{
|
||
// Edit a tile
|
||
CTile *tile=bank.getTile (_Tile128[indexInTileSet]);
|
||
tile->setFileName (type, name);
|
||
tile->setRotAlpha (0);
|
||
}
|
||
// ***************************************************************************
|
||
CTileSet::TError CTileSet::checkTile128 (CTile::TBitmap type, const CTileBorder& border, int& pixel, int& composante)
|
||
{
|
||
// Self check
|
||
if ((border.getWidth()!=128)||(border.getHeight()!=128))
|
||
return sizeInvalide;
|
||
if (!CTileBorder::compare (border, border, CTileBorder::top, CTileBorder::bottom, pixel, composante))
|
||
return topBottomNotTheSame;
|
||
if (!CTileBorder::compare (border, border, CTileBorder::left, CTileBorder::right, pixel, composante))
|
||
return rightLeftNotTheSame;
|
||
|
||
// Check
|
||
if (_Border128[type].isSet())
|
||
{
|
||
// Other check
|
||
if (!CTileBorder::compare (border, _Border128[type], CTileBorder::top, CTileBorder::top, pixel, composante))
|
||
return topInterfaceProblem;
|
||
if (!CTileBorder::compare (border, _Border128[type], CTileBorder::bottom, CTileBorder::bottom, pixel, composante))
|
||
return bottomInterfaceProblem;
|
||
if (!CTileBorder::compare (border, _Border128[type], CTileBorder::left, CTileBorder::left, pixel, composante))
|
||
return leftInterfaceProblem;
|
||
if (!CTileBorder::compare (border, _Border128[type], CTileBorder::right, CTileBorder::right, pixel, composante))
|
||
return rightInterfaceProblem;
|
||
}
|
||
else
|
||
{
|
||
return addFirstA128128;
|
||
}
|
||
|
||
return ok;
|
||
}
|
||
// ***************************************************************************
|
||
void CTileSet::addTile256 (int& indexInTileSet, CTileBank& bank)
|
||
{
|
||
// Create a tile
|
||
sint index=bank.createTile ();
|
||
|
||
// Index of the new tile
|
||
indexInTileSet=_Tile256.size();
|
||
|
||
// Add to the end of the list
|
||
_Tile256.push_back (index);
|
||
}
|
||
// ***************************************************************************
|
||
CTileSet::TError CTileSet::checkTile256 (CTile::TBitmap type, const CTileBorder& border, int& pixel, int& composante)
|
||
{
|
||
// Self check
|
||
if ((border.getWidth()!=256)||(border.getHeight()!=256))
|
||
return sizeInvalide;
|
||
if (!CTileBorder::compare (border, border, CTileBorder::top, CTileBorder::bottom, pixel, composante))
|
||
return topBottomNotTheSame;
|
||
if (!CTileBorder::compare (border, border, CTileBorder::left, CTileBorder::right, pixel, composante))
|
||
return rightLeftNotTheSame;
|
||
|
||
// Check if prb
|
||
if ((!_Border256[type].isSet())&&(_Border128[type].isSet()))
|
||
{
|
||
_Border256[type]=_Border128[type];
|
||
_Border256[type].doubleSize ();
|
||
}
|
||
|
||
// Check
|
||
if (_Border256[type].isSet())
|
||
{
|
||
|
||
// Other check
|
||
if (!CTileBorder::compare (border, _Border256[type], CTileBorder::top, CTileBorder::top, pixel, composante))
|
||
return topInterfaceProblem;
|
||
if (!CTileBorder::compare (border, _Border256[type], CTileBorder::bottom, CTileBorder::bottom, pixel, composante))
|
||
return bottomInterfaceProblem;
|
||
if (!CTileBorder::compare (border, _Border256[type], CTileBorder::left, CTileBorder::left, pixel, composante))
|
||
return leftInterfaceProblem;
|
||
if (!CTileBorder::compare (border, _Border256[type], CTileBorder::right, CTileBorder::right, pixel, composante))
|
||
return rightInterfaceProblem;
|
||
}
|
||
else
|
||
{
|
||
return addFirstA128128;
|
||
}
|
||
|
||
return ok;
|
||
}
|
||
// ***************************************************************************
|
||
void CTileSet::setTile256 (int indexInTileSet, const std::string& name, CTile::TBitmap type, CTileBank& bank)
|
||
{
|
||
// Edit a tile
|
||
CTile *tile=bank.getTile (_Tile256[indexInTileSet]);
|
||
tile->setFileName (type, name);
|
||
tile->setRotAlpha (0);
|
||
}
|
||
// ***************************************************************************
|
||
void CTileSet::setTileTransition (TTransition transition, const std::string& name, CTile::TBitmap type, CTileBank& bank,
|
||
const CTileBorder& border)
|
||
{
|
||
// Check is not an alpha channel
|
||
nlassert (type!=CTile::alpha); // use setTileTransitionAlpha
|
||
|
||
// Create a tile
|
||
_BorderTransition[transition][type]=border;
|
||
|
||
// Set the tile file name
|
||
CTile *tile=bank.getTile (_TileTransition[transition]._Tile);
|
||
tile->setFileName (type, name);
|
||
}
|
||
// ***************************************************************************
|
||
void CTileSet::setTileTransitionAlpha (TTransition transition, const std::string& name, CTileBank& bank,
|
||
const CTileBorder& border, uint8 rot)
|
||
{
|
||
// Check some args
|
||
nlassert (rot<4);
|
||
|
||
// Create a tile
|
||
_BorderTransition[transition][CTile::alpha]=border;
|
||
|
||
// Set the tile file name
|
||
CTile *tile=bank.getTile (_TileTransition[transition]._Tile);
|
||
tile->setFileName (CTile::alpha, name);
|
||
tile->setRotAlpha (rot);
|
||
}
|
||
// ***************************************************************************
|
||
CTileSet::TError CTileSet::checkTileTransition (TTransition transition, CTile::TBitmap type, const CTileBorder& border, int& indexError,
|
||
int& pixel, int& composante)
|
||
{
|
||
nlassert (transition>=0);
|
||
nlassert (transition<count);
|
||
|
||
// Check
|
||
indexError=-1;
|
||
|
||
// Top
|
||
indexError=getExistingTransitionTile ((TFlagBorder)_TransitionFlags[transition][top], dontcare, dontcare, dontcare, transition, type);
|
||
if (indexError!=-1)
|
||
{
|
||
if (!CTileBorder::compare (border, _BorderTransition[indexError][type], CTileBorder::top, CTileBorder::top, pixel, composante))
|
||
return topInterfaceProblem;
|
||
}
|
||
indexError=getExistingTransitionTile (dontcare, (TFlagBorder)_TransitionFlags[transition][top], dontcare, dontcare, transition, type);
|
||
if (indexError!=-1)
|
||
{
|
||
if (!CTileBorder::compare (border, _BorderTransition[indexError][type], CTileBorder::top, CTileBorder::bottom, pixel, composante))
|
||
return topInterfaceProblem;
|
||
}
|
||
indexError=-1;
|
||
if (_TransitionFlags[transition][top]==_1111)
|
||
{
|
||
if (!CTileBorder::allAlphaSet (border, CTileBorder::top, pixel, composante))
|
||
return topInterfaceProblem;
|
||
}
|
||
|
||
// Bottom
|
||
indexError=getExistingTransitionTile (dontcare, (TFlagBorder)_TransitionFlags[transition][bottom], dontcare, dontcare, transition, type);
|
||
if (indexError!=-1)
|
||
{
|
||
if (!CTileBorder::compare (border, _BorderTransition[indexError][type], CTileBorder::bottom, CTileBorder::bottom, pixel, composante))
|
||
return bottomInterfaceProblem;
|
||
}
|
||
indexError=getExistingTransitionTile ((TFlagBorder)_TransitionFlags[transition][bottom], dontcare, dontcare, dontcare, transition, type);
|
||
if (indexError!=-1)
|
||
{
|
||
if (!CTileBorder::compare (border, _BorderTransition[indexError][type], CTileBorder::bottom, CTileBorder::top, pixel, composante))
|
||
return bottomInterfaceProblem;
|
||
}
|
||
indexError=-1;
|
||
if (_TransitionFlags[transition][bottom]==_1111)
|
||
{
|
||
if (!CTileBorder::allAlphaSet (border, CTileBorder::bottom, pixel, composante))
|
||
return bottomInterfaceProblem;
|
||
}
|
||
|
||
// Left
|
||
indexError=getExistingTransitionTile (dontcare, dontcare, (TFlagBorder)_TransitionFlags[transition][left], dontcare, transition, type);
|
||
if (indexError!=-1)
|
||
{
|
||
if (!CTileBorder::compare (border, _BorderTransition[indexError][type], CTileBorder::left, CTileBorder::left, pixel, composante))
|
||
return leftInterfaceProblem;
|
||
}
|
||
indexError=getExistingTransitionTile (dontcare, dontcare, dontcare, (TFlagBorder)_TransitionFlags[transition][left], transition, type);
|
||
if (indexError!=-1)
|
||
{
|
||
if (!CTileBorder::compare (border, _BorderTransition[indexError][type], CTileBorder::left, CTileBorder::right, pixel, composante))
|
||
return leftInterfaceProblem;
|
||
}
|
||
indexError=-1;
|
||
if (_TransitionFlags[transition][left]==_1111)
|
||
{
|
||
if (!CTileBorder::allAlphaSet (border, CTileBorder::left, pixel, composante))
|
||
return leftInterfaceProblem;
|
||
}
|
||
|
||
// Right
|
||
indexError=getExistingTransitionTile (dontcare, dontcare, dontcare, (TFlagBorder)_TransitionFlags[transition][right], transition, type);
|
||
if (indexError!=-1)
|
||
{
|
||
if (!CTileBorder::compare (border, _BorderTransition[indexError][type], CTileBorder::right, CTileBorder::right, pixel, composante))
|
||
return rightInterfaceProblem;
|
||
}
|
||
indexError=getExistingTransitionTile (dontcare, dontcare, (TFlagBorder)_TransitionFlags[transition][right], dontcare, transition, type);
|
||
if (indexError!=-1)
|
||
{
|
||
if (!CTileBorder::compare (border, _BorderTransition[indexError][type], CTileBorder::right, CTileBorder::left, pixel, composante))
|
||
return rightInterfaceProblem;
|
||
}
|
||
indexError=-1;
|
||
if (_TransitionFlags[transition][right]==_1111)
|
||
{
|
||
if (!CTileBorder::allAlphaSet (border, CTileBorder::right, pixel, composante))
|
||
return rightInterfaceProblem;
|
||
}
|
||
return ok;
|
||
}
|
||
// ***************************************************************************
|
||
void CTileSet::removeTile128 (int indexInTileSet, CTileBank& bank)
|
||
{
|
||
// Check args
|
||
nlassert (indexInTileSet>=0);
|
||
nlassert (indexInTileSet<(sint)_Tile128.size());
|
||
|
||
// Old index
|
||
int index=_Tile128[indexInTileSet];
|
||
|
||
// Erase
|
||
_Tile128.erase (_Tile128.begin()+indexInTileSet);
|
||
bank.freeTile (index);
|
||
|
||
// Erase border if it is the last texture
|
||
deleteBordersIfLast (bank, CTile::diffuse);
|
||
deleteBordersIfLast (bank, CTile::additive);
|
||
deleteBordersIfLast (bank, CTile::alpha);
|
||
}
|
||
// ***************************************************************************
|
||
void CTileSet::removeTile256 (int indexInTileSet, CTileBank& bank)
|
||
{
|
||
// Check args
|
||
nlassert (indexInTileSet>=0);
|
||
nlassert (indexInTileSet<(sint)_Tile256.size());
|
||
|
||
// Old index
|
||
int index=_Tile256[indexInTileSet];
|
||
|
||
// Erase
|
||
_Tile256.erase (_Tile256.begin()+indexInTileSet);
|
||
bank.freeTile (index);
|
||
|
||
// Erase border if it is the last texture
|
||
deleteBordersIfLast (bank, CTile::diffuse);
|
||
deleteBordersIfLast (bank, CTile::additive);
|
||
deleteBordersIfLast (bank, CTile::alpha);
|
||
}
|
||
// ***************************************************************************
|
||
CTileSet::TTransition CTileSet::getTransitionTile (TFlagBorder _top, TFlagBorder _bottom, TFlagBorder _left, TFlagBorder _right)
|
||
{
|
||
for (int n=first; n<count; n++)
|
||
{
|
||
if (((_top==dontcare)||(_top==(TFlagBorder)_TransitionFlags[n][top]))&&
|
||
((_bottom==dontcare)||(_bottom==(TFlagBorder)_TransitionFlags[n][bottom]))&&
|
||
((_left==dontcare)||(_left==(TFlagBorder)_TransitionFlags[n][left]))&&
|
||
((_right==dontcare)||(_right==(TFlagBorder)_TransitionFlags[n][right])))
|
||
{
|
||
return (TTransition)n;
|
||
}
|
||
}
|
||
return notfound;
|
||
}
|
||
// ***************************************************************************
|
||
CTileSet::TTransition CTileSet::getExistingTransitionTile (TFlagBorder _top, TFlagBorder _bottom, TFlagBorder _left, TFlagBorder _right, int reject, CTile::TBitmap type)
|
||
{
|
||
for (int n=first; n<count; n++)
|
||
{
|
||
if ((n!=reject)&&
|
||
(_BorderTransition[n][type].isSet ())&&
|
||
((_top==dontcare)||(_top==(TFlagBorder)_TransitionFlags[n][top]))&&
|
||
((_bottom==dontcare)||(_bottom==(TFlagBorder)_TransitionFlags[n][bottom]))&&
|
||
((_left==dontcare)||(_left==(TFlagBorder)_TransitionFlags[n][left]))&&
|
||
((_right==dontcare)||(_right==(TFlagBorder)_TransitionFlags[n][right])))
|
||
{
|
||
return (TTransition)n;
|
||
}
|
||
}
|
||
return notfound;
|
||
}
|
||
// ***************************************************************************
|
||
void CTileSet::addChild (const std::string& name)
|
||
{
|
||
_ChildName.insert (name);
|
||
}
|
||
// ***************************************************************************
|
||
void CTileSet::removeChild (const std::string& name)
|
||
{
|
||
_ChildName.erase (name);
|
||
}
|
||
// ***************************************************************************
|
||
CTileSet::TTransition CTileSet::getComplementaryTransition (TTransition transition)
|
||
{
|
||
nlassert ((transition>=first)&&(transition<=last));
|
||
TTransition trans=getTransitionTile (getComplementaryBorder (_TransitionFlags[transition][top]),
|
||
getComplementaryBorder (_TransitionFlags[transition][bottom]),
|
||
getComplementaryBorder (_TransitionFlags[transition][left]),
|
||
getComplementaryBorder (_TransitionFlags[transition][right]));
|
||
|
||
nlassert (trans!=notfound);
|
||
|
||
return trans;
|
||
}
|
||
// ***************************************************************************
|
||
CTileSet::TFlagBorder CTileSet::getComplementaryBorder (TFlagBorder border)
|
||
{
|
||
switch (border)
|
||
{
|
||
case _0000:
|
||
return _1111;
|
||
case _0001:
|
||
return _1110;
|
||
case _0111:
|
||
return _1000;
|
||
case _1000:
|
||
return _0111;
|
||
case _1110:
|
||
return _0001;
|
||
case _1111:
|
||
return _0000;
|
||
default:
|
||
nlassert (0); // no
|
||
}
|
||
return _0000;
|
||
}
|
||
// ***************************************************************************
|
||
CTileSet::TFlagBorder CTileSet::getInvertBorder (TFlagBorder border)
|
||
{
|
||
switch (border)
|
||
{
|
||
case _0000:
|
||
return _0000;
|
||
case _0001:
|
||
return _1000;
|
||
case _0111:
|
||
return _1110;
|
||
case _1000:
|
||
return _0001;
|
||
case _1110:
|
||
return _0111;
|
||
case _1111:
|
||
return _1111;
|
||
default:
|
||
nlassert (0); // no
|
||
}
|
||
return _0000;
|
||
}
|
||
// ***************************************************************************
|
||
CTileSet::TFlagBorder CTileSet::getOrientedBorder (TBorder where, TFlagBorder border)
|
||
{
|
||
switch (where)
|
||
{
|
||
case left:
|
||
case bottom:
|
||
return border;
|
||
case top:
|
||
case right:
|
||
return getInvertBorder (border);
|
||
default:
|
||
nlassert (0); // no
|
||
}
|
||
return _0000;
|
||
}
|
||
// ***************************************************************************
|
||
CTileSet::TTransition CTileSet::rotateTransition (TTransition transition)
|
||
{
|
||
return getTransitionTile (
|
||
getOrientedBorder (top, getOrientedBorder (right, _TransitionFlags[transition][right])), // top
|
||
getOrientedBorder (bottom, getOrientedBorder (left, _TransitionFlags[transition][left])), // bottom
|
||
getOrientedBorder (left, getOrientedBorder (top, _TransitionFlags[transition][top])), // left
|
||
getOrientedBorder (right, getOrientedBorder (bottom, _TransitionFlags[transition][bottom])) // right
|
||
);
|
||
}
|
||
// ***************************************************************************
|
||
void CTileSet::clearTile128 (int indexInTileSet, CTile::TBitmap type, CTileBank& bank)
|
||
{
|
||
int nTile=_Tile128[indexInTileSet];
|
||
bank.getTile (nTile)->clearTile(type);
|
||
|
||
// Erase border if it is the last texture
|
||
deleteBordersIfLast (bank, type);
|
||
}
|
||
// ***************************************************************************
|
||
void CTileSet::clearTile256 (int indexInTileSet, CTile::TBitmap type, CTileBank& bank)
|
||
{
|
||
int nTile=_Tile256[indexInTileSet];
|
||
bank.getTile (nTile)->clearTile(type);
|
||
|
||
// Erase border if it is the last texture
|
||
deleteBordersIfLast (bank, type);
|
||
}
|
||
// ***************************************************************************
|
||
void CTileSet::clearTransition (TTransition transition, CTile::TBitmap type, CTileBank& bank)
|
||
{
|
||
int nTile=_TileTransition[transition]._Tile;
|
||
if (nTile!=-1)
|
||
bank.getTile (nTile)->clearTile(type);
|
||
_BorderTransition[transition][type].reset();
|
||
|
||
// Erase border if it is the last texture
|
||
deleteBordersIfLast (bank, type);
|
||
}
|
||
// ***************************************************************************
|
||
// Delete 128 and 256 borders if no more valid texture file name for each bitmap type.
|
||
void CTileSet::deleteBordersIfLast (const CTileBank& bank, CTile::TBitmap type)
|
||
{
|
||
// delete is true
|
||
bool bDelete=true;
|
||
|
||
// iterator..
|
||
std::vector<sint32>::iterator ite=_Tile128.begin();
|
||
|
||
// Check all the 128x128 tiles
|
||
while (ite!=_Tile128.end())
|
||
{
|
||
// If the file name is valid
|
||
if (bank.getTile (*ite)->getRelativeFileName(type)!="")
|
||
{
|
||
// Don't delete,
|
||
bDelete=false;
|
||
break;
|
||
}
|
||
ite++;
|
||
}
|
||
// If break, not empty, return
|
||
if (ite!=_Tile128.end())
|
||
return;
|
||
|
||
// Check all the 256x256 tiles
|
||
ite=_Tile256.begin();
|
||
while (ite!=_Tile256.end())
|
||
{
|
||
// If the file name is valid
|
||
if (bank.getTile (*ite)->getRelativeFileName(type)!="")
|
||
{
|
||
// Don't delete,
|
||
bDelete=false;
|
||
break;
|
||
}
|
||
ite++;
|
||
}
|
||
// If break, not empty, return
|
||
if (ite!=_Tile256.end())
|
||
return;
|
||
|
||
|
||
// Check all the transitions tiles
|
||
sint trans;
|
||
for (trans=0; trans<count; trans++)
|
||
{
|
||
// Get the tile associed with the transition
|
||
int nTile=_TileTransition[trans]._Tile;
|
||
|
||
// If it is not NULL..
|
||
if (nTile!=-1)
|
||
{
|
||
// If the file name is valid
|
||
if (bank.getTile (nTile)->getRelativeFileName(type)!="")
|
||
{
|
||
// Don't delete,
|
||
bDelete=false;
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
if (trans!=count)
|
||
return;
|
||
|
||
// Ok, erase borders because no tile use it anymore
|
||
_Border128[type].reset();
|
||
_Border256[type].reset();
|
||
}
|
||
// ***************************************************************************
|
||
void CTileSet::clearDisplacement (TDisplacement displacement, CTileBank& bank)
|
||
{
|
||
// checks
|
||
nlassert (displacement>=FirstDisplace);
|
||
nlassert (displacement<=LastDisplace);
|
||
|
||
// Backup the id
|
||
int id=_DisplacementBitmap[displacement];
|
||
|
||
// Clear map id
|
||
_DisplacementBitmap[displacement]=0;
|
||
|
||
// Tell the bank we remove it
|
||
bank.removeDisplacementMap (id);
|
||
}
|
||
// ***************************************************************************
|
||
void CTileSet::setDisplacement (TDisplacement displacement, const std::string& fileName, CTileBank& bank)
|
||
{
|
||
// checks
|
||
nlassert (displacement>=FirstDisplace);
|
||
nlassert (displacement<=LastDisplace);
|
||
|
||
// Clear it
|
||
bank.removeDisplacementMap (_DisplacementBitmap[displacement]);
|
||
|
||
// Get displacement map
|
||
_DisplacementBitmap[displacement]=bank.getDisplacementMap (fileName);
|
||
}
|
||
// ***************************************************************************
|
||
void CTileSet::cleanUnusedData ()
|
||
{
|
||
_Name="";
|
||
_ChildName.clear();
|
||
_Border128[0].reset ();
|
||
_Border128[1].reset ();
|
||
_Border256[0].reset ();
|
||
_Border256[1].reset ();
|
||
for (uint i=0; i<count; i++)
|
||
for (uint j=0; j<CTile::bitmapCount; j++)
|
||
_BorderTransition[i][j].reset();
|
||
}
|
||
|
||
|
||
// ***************************************************************************
|
||
void CTileSet::setTileVegetableDescFileName (const std::string &fileName)
|
||
{
|
||
_TileVegetableDescFileName= fileName;
|
||
}
|
||
// ***************************************************************************
|
||
const std::string& CTileSet::getTileVegetableDescFileName () const
|
||
{
|
||
return _TileVegetableDescFileName;
|
||
}
|
||
// ***************************************************************************
|
||
void CTileSet::setTileVegetableDesc (const CTileVegetableDesc &tvd)
|
||
{
|
||
_TileVegetableDesc= tvd;
|
||
}
|
||
|
||
// ***************************************************************************
|
||
CTileVegetableDesc &CTileSet::getTileVegetableDesc()
|
||
{
|
||
return _TileVegetableDesc;
|
||
}
|
||
|
||
// ***************************************************************************
|
||
const CTileVegetableDesc &CTileSet::getTileVegetableDesc() const
|
||
{
|
||
return _TileVegetableDesc;
|
||
}
|
||
|
||
// ***************************************************************************
|
||
void CTileSet::loadTileVegetableDesc()
|
||
{
|
||
if(_TileVegetableDescFileName!="")
|
||
{
|
||
try
|
||
{
|
||
string fname= CPath::lookup(_TileVegetableDescFileName);
|
||
CIFile f(fname);
|
||
// load the TileVegetableDesc
|
||
f.serial(_TileVegetableDesc);
|
||
}
|
||
catch(Exception &e)
|
||
{
|
||
nlinfo("Error loading TileVegetableDesc: %s", e.what());
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
// ***************************************************************************
|
||
// ***************************************************************************
|
||
// CTileBorder.
|
||
// ***************************************************************************
|
||
// ***************************************************************************
|
||
|
||
|
||
// ***************************************************************************
|
||
const sint CTileBorder::_Version=0;
|
||
// ***************************************************************************
|
||
void CTileBorder::serial(NLMISC::IStream &f) throw(NLMISC::EStream)
|
||
{
|
||
(void)f.serialVersion(_Version);
|
||
|
||
f.serial (_Set);
|
||
f.serial (_Width);
|
||
f.serial (_Height);
|
||
f.serialCont (_Borders[top]);
|
||
f.serialCont (_Borders[bottom]);
|
||
f.serialCont (_Borders[left]);
|
||
f.serialCont (_Borders[right]);
|
||
}
|
||
// ***************************************************************************
|
||
void CTileBorder::set (int width, int height, const std::vector<CBGRA>& array)
|
||
{
|
||
// Check array size
|
||
nlassert (width>0);
|
||
nlassert (height>0);
|
||
nlassert ((sint)array.size()==width*height);
|
||
|
||
// Copy size
|
||
_Width=width;
|
||
_Height=height;
|
||
|
||
// Last line
|
||
int lastLine=(_Height-1)*width;
|
||
int lastCol=(_Width-1);
|
||
_Borders[top].resize (_Width);
|
||
_Borders[bottom].resize (_Width);
|
||
_Borders[left].resize (_Height);
|
||
_Borders[right].resize (_Height);
|
||
|
||
// Copy top/bottom border
|
||
for (int w=0; w<_Width; w++)
|
||
{
|
||
_Borders[top][w]=array[w];
|
||
_Borders[bottom][w]=array[w+lastLine];
|
||
}
|
||
|
||
// Copy left/right border
|
||
for (int h=0; h<_Height; h++)
|
||
{
|
||
_Borders[left][h]=array[h*_Width];
|
||
_Borders[right][h]=array[h*_Width+lastCol];
|
||
}
|
||
|
||
// Set
|
||
_Set=true;
|
||
}
|
||
// ***************************************************************************
|
||
void CTileBorder::get (int &width, int &height, std::vector<CBGRA>& array) const
|
||
{
|
||
// Go
|
||
if (_Set)
|
||
{
|
||
width=_Width;
|
||
height=_Height;
|
||
array.resize (0);
|
||
array.resize (_Width*_Height);
|
||
nlassert (_Borders[bottom].size()==(uint)_Width);
|
||
nlassert (_Borders[top].size()==(uint)_Width);
|
||
nlassert (_Borders[left].size()==(uint)_Height);
|
||
nlassert (_Borders[right].size()==(uint)_Height);
|
||
|
||
// Fill
|
||
CBGRA black(0,0,0);
|
||
for (int p=0; p<_Width*_Height; p++)
|
||
{
|
||
array[p]=black;
|
||
}
|
||
|
||
// Last line
|
||
int lastLine=(_Height-1)*_Width;
|
||
int lastCol=(_Width-1);
|
||
|
||
// Copy top/bottom border
|
||
for (int w=0; w<_Width; w++)
|
||
{
|
||
array[w]=_Borders[top][w];
|
||
array[w+lastLine]=_Borders[bottom][w];
|
||
}
|
||
|
||
// Copy left/right border
|
||
for (int h=0; h<_Height; h++)
|
||
{
|
||
array[h*_Width]=_Borders[left][h];
|
||
array[h*_Width+lastCol]=_Borders[right][h];
|
||
}
|
||
}
|
||
else
|
||
{
|
||
width=0;
|
||
height=0;
|
||
array.resize (0);
|
||
}
|
||
}
|
||
// ***************************************************************************
|
||
bool CTileBorder::compare (const CTileBorder& border1, const CTileBorder& border2, TBorder where1, TBorder where2, int& pixel, int& composante)
|
||
{
|
||
// Check border is initialized
|
||
nlassert (border1.isSet());
|
||
nlassert (border2.isSet());
|
||
|
||
if (border1._Borders[where1].size()!=border2._Borders[where2].size())
|
||
return false;
|
||
for (pixel=0; pixel<(int)border1._Borders[where1].size(); pixel++)
|
||
{
|
||
if (border1._Borders[where1][pixel].R!=border2._Borders[where2][pixel].R)
|
||
{
|
||
composante=0;
|
||
return false;
|
||
}
|
||
else if (border1._Borders[where1][pixel].G!=border2._Borders[where2][pixel].G)
|
||
{
|
||
composante=1;
|
||
return false;
|
||
}
|
||
else if (border1._Borders[where1][pixel].B!=border2._Borders[where2][pixel].B)
|
||
{
|
||
composante=2;
|
||
return false;
|
||
}
|
||
else if (border1._Borders[where1][pixel].A!=border2._Borders[where2][pixel].A)
|
||
{
|
||
composante=3;
|
||
return false;
|
||
}
|
||
}
|
||
|
||
return true;
|
||
}
|
||
// ***************************************************************************
|
||
bool CTileBorder::allAlphaSet (const CTileBorder& border, TBorder where, int& pixel, int& composante)
|
||
{
|
||
// Check border is initialized
|
||
nlassert (border.isSet());
|
||
|
||
// always Alpha
|
||
composante=3;
|
||
|
||
for (pixel=0; pixel<(int)border._Borders[where].size(); pixel++)
|
||
{
|
||
if (border._Borders[where][pixel].A!=0xff)
|
||
return false;
|
||
}
|
||
|
||
return true;
|
||
}
|
||
// ***************************************************************************
|
||
bool CTileBorder::operator== (const CTileBorder& border) const
|
||
{
|
||
return (_Width==border._Width) && (_Height==border._Height) && (_Borders==border._Borders);
|
||
}
|
||
// ***************************************************************************
|
||
void CTileBorder::operator= (const CTileBorder& border)
|
||
{
|
||
_Set=border._Set;
|
||
_Width=border._Width;
|
||
_Height=border._Width;
|
||
_Borders[top]=border._Borders[top];
|
||
_Borders[bottom]=border._Borders[bottom];
|
||
_Borders[left]=border._Borders[left];
|
||
_Borders[right]=border._Borders[right];
|
||
}
|
||
|
||
// ***************************************************************************
|
||
void CTileBorder::doubleSize ()
|
||
{
|
||
_Borders[top].resize (_Width*2);
|
||
_Borders[bottom].resize (_Width*2);
|
||
_Borders[left].resize (_Height*2);
|
||
_Borders[right].resize (_Height*2);
|
||
|
||
for (int w=0; w<_Width; w++)
|
||
{
|
||
_Borders[top][w+_Width]=_Borders[top][w];
|
||
_Borders[bottom][w+_Width]=_Borders[bottom][w];
|
||
}
|
||
for (int h=0; h<_Height; h++)
|
||
{
|
||
_Borders[left][h+_Height]=_Borders[left][h];
|
||
_Borders[right][h+_Height]=_Borders[right][h];
|
||
}
|
||
}
|
||
// ***************************************************************************
|
||
void CTileBorder::rotate()
|
||
{
|
||
// Copy the right
|
||
std::vector<NLMISC::CBGRA> tmpLeft=_Borders[left];
|
||
|
||
// Top inverted becomes left
|
||
uint i, size;
|
||
size=_Borders[top].size();
|
||
_Borders[left].resize (size);
|
||
|
||
// copy inverted
|
||
for (i=0; i<size; i++)
|
||
_Borders[left][i]=_Borders[top][size-i-1];
|
||
|
||
// Right become top
|
||
_Borders[top]=_Borders[right];
|
||
|
||
// bottom inverted becomes right
|
||
size=_Borders[bottom].size();
|
||
_Borders[right].resize (size);
|
||
|
||
// copy inverted
|
||
for (i=0; i<size; i++)
|
||
_Borders[right][i]=_Borders[bottom][size-i-1];
|
||
|
||
// Left become bottom
|
||
_Borders[bottom]=tmpLeft;
|
||
|
||
// Invert size
|
||
sint32 tmpSize=_Width;
|
||
_Width=_Height;
|
||
_Height=tmpSize;
|
||
}
|
||
|
||
// ***************************************************************************
|
||
// ***************************************************************************
|
||
// CTileSetTransition.
|
||
// ***************************************************************************
|
||
// ***************************************************************************
|
||
|
||
|
||
// ***************************************************************************
|
||
const sint CTileSetTransition::_Version=1;
|
||
// ***************************************************************************
|
||
void CTileSetTransition::serial(class NLMISC::IStream &f) throw(EStream)
|
||
{
|
||
sint streamver = f.serialVersion(_Version);
|
||
|
||
switch (streamver)
|
||
{
|
||
case 0:
|
||
{
|
||
bool doomy;
|
||
f.serial (_Tile);
|
||
f.serial (doomy); // skip the old argu
|
||
}
|
||
break;
|
||
case 1:
|
||
f.serial (_Tile);
|
||
break;
|
||
}
|
||
}
|
||
// ***************************************************************************
|
||
|
||
|
||
// ***************************************************************************
|
||
// ***************************************************************************
|
||
// CTileNoise.
|
||
// ***************************************************************************
|
||
// ***************************************************************************
|
||
|
||
|
||
// ***************************************************************************
|
||
CTileNoise::CTileNoise ()
|
||
{
|
||
// Not loaded
|
||
_TileNoiseMap=NULL;
|
||
_FileName="";
|
||
}
|
||
// ***************************************************************************
|
||
CTileNoise::CTileNoise (const CTileNoise &src)
|
||
{
|
||
// Default ctor
|
||
_TileNoiseMap=NULL;
|
||
_FileName="";
|
||
|
||
// Copy
|
||
*this=src;
|
||
}
|
||
// ***************************************************************************
|
||
CTileNoise::~CTileNoise ()
|
||
{
|
||
if (_TileNoiseMap)
|
||
{
|
||
delete _TileNoiseMap;
|
||
_TileNoiseMap=NULL;
|
||
}
|
||
}
|
||
// ***************************************************************************
|
||
CTileNoise& CTileNoise::operator= (const CTileNoise &src)
|
||
{
|
||
// Copy the filename
|
||
_FileName=src._FileName;
|
||
|
||
// Tile noise map ?
|
||
if (src._TileNoiseMap)
|
||
{
|
||
if (_TileNoiseMap==NULL)
|
||
{
|
||
// Allocate it
|
||
_TileNoiseMap=new CTileNoiseMap;
|
||
}
|
||
|
||
// Copy the noise map
|
||
*_TileNoiseMap=*src._TileNoiseMap;
|
||
}
|
||
else
|
||
{
|
||
// Erase the map
|
||
if (_TileNoiseMap)
|
||
{
|
||
delete _TileNoiseMap;
|
||
_TileNoiseMap=NULL;
|
||
}
|
||
}
|
||
return *this;
|
||
}
|
||
// ***************************************************************************
|
||
void CTileNoise::serial (NLMISC::IStream& f)
|
||
{
|
||
// Version
|
||
f.serialVersion (0);
|
||
|
||
// Serial the file name
|
||
f.serial (_FileName);
|
||
}
|
||
// ***************************************************************************
|
||
void CTileNoise::setEmpty ()
|
||
{
|
||
// Reset it
|
||
reset();
|
||
_FileName="EmptyDisplacementMap";
|
||
_TileNoiseMap=new CTileNoiseMap();
|
||
memset (_TileNoiseMap->Pixels, 0, NL3D_TILE_NOISE_MAP_SIZE*NL3D_TILE_NOISE_MAP_SIZE);
|
||
}
|
||
// ***************************************************************************
|
||
void CTileNoise::reset()
|
||
{
|
||
// Erase the map
|
||
if (_TileNoiseMap)
|
||
{
|
||
delete _TileNoiseMap;
|
||
_TileNoiseMap=NULL;
|
||
}
|
||
|
||
// Erase filename
|
||
_FileName="";
|
||
}
|
||
// ***************************************************************************
|
||
|
||
} // NL3D
|