From 0ea5fc66924303d1bf73ba283a383e2aadee02f2 Mon Sep 17 00:00:00 2001 From: neodarz Date: Sat, 11 Aug 2018 20:21:34 +0200 Subject: Initial commit --- docs/doxygen/nel/texture__far_8cpp-source.html | 1989 ++++++++++++++++++++++++ 1 file changed, 1989 insertions(+) create mode 100644 docs/doxygen/nel/texture__far_8cpp-source.html (limited to 'docs/doxygen/nel/texture__far_8cpp-source.html') diff --git a/docs/doxygen/nel/texture__far_8cpp-source.html b/docs/doxygen/nel/texture__far_8cpp-source.html new file mode 100644 index 00000000..bd8e9fbd --- /dev/null +++ b/docs/doxygen/nel/texture__far_8cpp-source.html @@ -0,0 +1,1989 @@ + + + + nevrax.org : docs + + + + + + + + + + + + + + +
# 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  
+

texture_far.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/texture_far.h"
+00029 #include "3d/tile_far_bank.h"
+00030 #include "3d/patch.h"
+00031 #include "3d/tile_color.h"
+00032 #include "3d/zone.h"
+00033 #include "3d/landscape.h"
+00034 #include "nel/misc/system_info.h"
+00035 
+00036 
+00037 using namespace NLMISC;
+00038 using namespace NL3D;
+00039 
+00040 namespace NL3D {
+00041 
+00042 CRGBA CTextureFar::_LightmapExpanded[NL_NUM_PIXELS_ON_FAR_TILE_EDGE*NL_MAX_TILES_BY_PATCH_EDGE*NL_NUM_PIXELS_ON_FAR_TILE_EDGE*NL_MAX_TILES_BY_PATCH_EDGE];
+00043 uint8 CTextureFar::_LumelExpanded[(NL_MAX_TILES_BY_PATCH_EDGE*NL_LUMEL_BY_TILE+1)*(NL_MAX_TILES_BY_PATCH_EDGE*NL_LUMEL_BY_TILE+1)];
+00044 CRGBA CTextureFar::_TileTLIColors[(NL_MAX_TILES_BY_PATCH_EDGE+1)*(NL_MAX_TILES_BY_PATCH_EDGE+1)];
+00045 
+00046 CTextureFar::CTextureFar()
+00047 {
+00048         // This texture is releasable. It doesn't stays in standard memory after been uploaded into video memory.
+00049         setReleasable (true);
+00050 
+00051         _ULPrec= this;
+00052         _ULNext= this;
+00053 }
+00054 
+00055 CTextureFar::~CTextureFar()
+00056 {
+00057         // verify the textureFar is correctly unlinked from any ciruclar list.
+00058         nlassert(_ULPrec==this && _ULNext==this);
+00059 }
+00060 
+00061 
+00062 void CTextureFar::linkBeforeUL(CTextureFar *textNext)
+00063 {
+00064         nlassert(textNext);
+00065 
+00066         // first, unlink others from me. NB: works even if _ULPrec==_ULNext==this.
+00067         _ULNext->_ULPrec= _ULPrec;
+00068         _ULPrec->_ULNext= _ULNext;
+00069         // link to igNext.
+00070         _ULNext= textNext;
+00071         _ULPrec= textNext->_ULPrec;
+00072         // link others to me.
+00073         _ULNext->_ULPrec= this;
+00074         _ULPrec->_ULNext= this;
+00075 }
+00076 
+00077 void CTextureFar::unlinkUL()
+00078 {
+00079         // first, unlink others from me. NB: works even if _ULPrec==_ULNext==this.
+00080         _ULNext->_ULPrec= _ULPrec;
+00081         _ULPrec->_ULNext= _ULNext;
+00082         // reset
+00083         _ULPrec= this;
+00084         _ULNext= this;
+00085 }
+00086 
+00087 
+00088 void CTextureFar::setSizeOfFarPatch (sint width, sint height)
+00089 {
+00090         // Resizing the bitmap
+00091         _OriginalWidth=width*NL_NUM_FAR_PATCHES_BY_EDGE;
+00092         _OriginalHeight=height*NL_NUM_FAR_PATCHES_BY_EDGE;
+00093 
+00094         // Resize patch array
+00095         contReset (_Patches);
+00096         _Patches.resize (NL_NUM_FAR_PATCHES_BY_TEXTURE);
+00097 
+00098         // Init count of patch
+00099         _PatchCount=0;
+00100 
+00101         // Init upload format 16 bits
+00102         setUploadFormat(RGB565);
+00103 
+00104         // Set filter mode. No mipmap!
+00105         setFilterMode (Linear, LinearMipMapOff);
+00106 
+00107         // Wrap
+00108         setWrapS (Clamp);
+00109         setWrapT (Clamp);
+00110 
+00111         // Init patch array
+00112         for (sint p=0; p<NL_NUM_FAR_PATCHES_BY_TEXTURE; p++)
+00113         {
+00114                 // Set patch pointer to NULL
+00115                 _Patches[p].Patch=NULL;
+00116         }
+00117 }
+00118 
+00119 // Add a patch in the CTexture Patch. Must not be full! Return true if the texture is full after adding this patch else false.
+00120 bool CTextureFar::addPatch (CPatch *pPatch, float& farUScale, float& farVScale, float& farUBias, float& farVBias, bool& bRot)
+00121 {
+00122         // Check that at least a cell is free
+00123         nlassert (_PatchCount<NL_NUM_FAR_PATCHES_BY_TEXTURE);
+00124 
+00125         // Look for a free cell
+00126         sint p;
+00127         for (p=0; p<NL_NUM_FAR_PATCHES_BY_TEXTURE; p++)
+00128         {
+00129                 // Cell is NULL ?
+00130                 if (_Patches[p].Patch==NULL)
+00131                 {
+00132                         // Put the patch here and go out.
+00133                         _Patches[p].Patch=pPatch;
+00134                         break;
+00135                 }
+00136         }
+00137         // Check that at least a cell is free
+00138         nlassert (p<NL_NUM_FAR_PATCHES_BY_TEXTURE);
+00139 
+00140         // Position of the invalide rectangle
+00141         int x = ((p & NL_NUM_FAR_PATCHES_BY_EDGE_MASK) * _OriginalWidth) >> NL_NUM_FAR_PATCHES_BY_EDGE_SHIFT;
+00142         int y = ((p >> NL_NUM_FAR_PATCHES_BY_EDGE_SHIFT) * _OriginalHeight) >> NL_NUM_FAR_PATCHES_BY_EDGE_SHIFT;
+00143 
+00144         // Invalidate the rectangle
+00145         CRect rect (x, y, _OriginalWidth>>NL_NUM_FAR_PATCHES_BY_EDGE_SHIFT, _OriginalHeight>>NL_NUM_FAR_PATCHES_BY_EDGE_SHIFT);
+00146         ITexture::touchRect (rect);
+00147 
+00148         // ** Return some values
+00149 
+00150         // Rotation flag
+00151         bRot = ( pPatch->getOrderS() < pPatch->getOrderT() );
+00152 
+00153         // Scale is the same for all
+00154         farUScale=(float)((_OriginalWidth>>NL_NUM_FAR_PATCHES_BY_EDGE_SHIFT)-1)/(float)_OriginalWidth;
+00155         farVScale=(float)((_OriginalHeight>>NL_NUM_FAR_PATCHES_BY_EDGE_SHIFT)-1)/(float)_OriginalHeight;
+00156 
+00157         // UBias is the same for all
+00158         farUBias=((float)x+0.5f)/(float)_OriginalWidth;
+00159 
+00160         // UBias is the same for all
+00161         farVBias=((float)y+0.5f)/(float)_OriginalHeight;
+00162         
+00163         // One more patch
+00164         _PatchCount++;
+00165 
+00166         return (_PatchCount == NL_NUM_FAR_PATCHES_BY_TEXTURE);
+00167 }
+00168 
+00169 // Remove a patch in the CTexture Patch
+00170 bool CTextureFar::removePatch (CPatch *pPatch)
+00171 {
+00172         // Check that at least a cell is used
+00173         nlassert (_PatchCount>0);
+00174 
+00175         // Look for the patch free cell
+00176         sint p;
+00177         for (p=0; p<NL_NUM_FAR_PATCHES_BY_TEXTURE; p++)
+00178         {
+00179                 // Is the good cell ?
+00180                 if (_Patches[p].Patch==pPatch)
+00181                 {
+00182                         // ok, remove it
+00183                         _Patches[p].Patch=NULL;
+00184                         break;
+00185                 }
+00186         }
+00187 
+00188         // Check it has been found
+00189         nlassert (p<NL_NUM_FAR_PATCHES_BY_TEXTURE);
+00190 
+00191         // One patch less
+00192         _PatchCount--;
+00193 
+00194         // Return true if it is empty, else return false
+00195         return (_PatchCount == 0);
+00196 }
+00197 
+00198 uint CTextureFar::touchPatch(uint p)
+00199 {
+00200         // Check param
+00201         nlassert (p<NL_NUM_FAR_PATCHES_BY_TEXTURE);
+00202 
+00203         // if there is still a patch here
+00204         if( _Patches[p].Patch!=NULL )
+00205         {
+00206                 // Position of the invalide rectangle
+00207                 int x = ((p & NL_NUM_FAR_PATCHES_BY_EDGE_MASK) * _OriginalWidth) >> NL_NUM_FAR_PATCHES_BY_EDGE_SHIFT;
+00208                 int y = ((p >> NL_NUM_FAR_PATCHES_BY_EDGE_SHIFT) * _OriginalHeight) >> NL_NUM_FAR_PATCHES_BY_EDGE_SHIFT;
+00209 
+00210                 // Invalidate the associated rectangle
+00211                 CRect rect (x, y, _OriginalWidth>>NL_NUM_FAR_PATCHES_BY_EDGE_SHIFT, _OriginalHeight>>NL_NUM_FAR_PATCHES_BY_EDGE_SHIFT);
+00212                 ITexture::touchRect (rect);
+00213 
+00214                 // return number of pixels touched
+00215                 return (_OriginalWidth>>NL_NUM_FAR_PATCHES_BY_EDGE_SHIFT) * (_OriginalHeight>>NL_NUM_FAR_PATCHES_BY_EDGE_SHIFT);
+00216         }
+00217         else
+00218         {
+00219                 // no touch
+00220                 return 0;
+00221         }
+00222 }
+00223 
+00224 // Generate the texture. See ITexture::doGenerate().
+00225 void CTextureFar::doGenerate ()
+00226 {
+00227         // Resize
+00228         CBitmap::resize (_OriginalWidth, _OriginalHeight, RGBA);
+00229 
+00230         // Rectangle invalidate ?
+00231         if (_ListInvalidRect.begin()!=_ListInvalidRect.end())
+00232         {
+00233                 // Yes, rebuild only those rectangles.
+00234 
+00235                 // For each rectangle to compute
+00236                 std::list<NLMISC::CRect>::iterator ite=_ListInvalidRect.begin();
+00237                 while (ite!=_ListInvalidRect.end())
+00238                 {
+00239                         // Compute rectangle coordinates
+00240                         sint x=(ite->left()<<NL_NUM_FAR_PATCHES_BY_EDGE_SHIFT)/_Width;
+00241                         sint y=(ite->top()<<NL_NUM_FAR_PATCHES_BY_EDGE_SHIFT)/_Height;
+00242 
+00243                         // X and Y coord should be >0 and not be greater or equal to the number of patch stored on a texture edge.
+00244                         nlassert (x>=0);
+00245                         nlassert (x<NL_NUM_FAR_PATCHES_BY_EDGE);
+00246                         nlassert (y>=0);
+00247                         nlassert (y<NL_NUM_FAR_PATCHES_BY_EDGE);
+00248 
+00249                         // ReBuild the rectangle. verify first patch still exist.
+00250                         if (_Patches[x+(y<<NL_NUM_FAR_PATCHES_BY_EDGE_SHIFT)].Patch)
+00251                                 rebuildRectangle (x, y);
+00252 
+00253                         // Next rectangle
+00254                         ite++;
+00255                 }
+00256         }
+00257         else
+00258         {
+00259                 // no, rebuild all the rectangle
+00260                 for (sint y=0; y<NL_NUM_FAR_PATCHES_BY_EDGE; y++)
+00261                 for (sint x=0; x<NL_NUM_FAR_PATCHES_BY_EDGE; x++)
+00262                 {
+00263                         // Rebuild this rectangle
+00264                         if (_Patches[x+(y<<NL_NUM_FAR_PATCHES_BY_EDGE_SHIFT)].Patch)
+00265                                 rebuildRectangle (x, y);
+00266                 }
+00267         }
+00268 }
+00269 
+00270 
+00271 // Rebuild the rectangle passed with coordinate passed in parameter
+00272 void CTextureFar::rebuildRectangle (uint x, uint y)
+00273 {
+00274         // Patch pointer
+00275         CPatch* patch=_Patches[x+(y<<NL_NUM_FAR_PATCHES_BY_EDGE_SHIFT)].Patch;
+00276 
+00277         // Check it exists
+00278         nlassert (patch);
+00279 
+00280         // get the order
+00281         uint nS=patch->getOrderS();
+00282         uint nT=patch->getOrderT();
+00283 
+00284         // Check it is a 16 bits texture
+00285         nlassert (getPixelFormat()==RGBA);
+00286 
+00287         // Check pixels exist
+00288         nlassert (getPixels().size()!=0);
+00289 
+00290         // Base offset of the first pixel of the patch's texture
+00291         uint    nBaseOffset;
+00292 
+00293         // Delta to add to the destination offset when walk for a pixel to the right in the source tile
+00294         sint dstDeltaX;
+00295 
+00296         // Delta to add to the destination offset when walk for a pixel to the bottom in the source tile
+00297         sint dstDeltaY;
+00298 
+00299         // larger size
+00300         uint larger;
+00301 
+00302         // larger than higher  (regular)
+00303         if (nS>=nT)
+00304         {
+00305                 // Regular offset, top left
+00306                 nBaseOffset=((x*_Width)>>NL_NUM_FAR_PATCHES_BY_EDGE_SHIFT)+((y*_Height)>>NL_NUM_FAR_PATCHES_BY_EDGE_SHIFT)*_Width;
+00307 
+00308                 // Regular deltaX, to the right
+00309                 dstDeltaX=1;
+00310 
+00311                 // Regular deltaY, to the bottom
+00312                 dstDeltaY=_Width;
+00313 
+00314                 // Larger size
+00315                 larger=nS;
+00316         }
+00317         // higher than larger (goofy), the patch is stored with a rotation of 1 (to the left of course)
+00318         else
+00319         {
+00320                 // Goofy offset, bottom left
+00321                 nBaseOffset=((x*_Width)>>NL_NUM_FAR_PATCHES_BY_EDGE_SHIFT)+((y*_Height)>>NL_NUM_FAR_PATCHES_BY_EDGE_SHIFT)*_Width;
+00322                 nBaseOffset+=((_Height>>NL_NUM_FAR_PATCHES_BY_EDGE_SHIFT)-1)*_Width;
+00323 
+00324                 // Goofy deltaX, to the top
+00325                 dstDeltaX=-(sint)_Width;
+00326 
+00327                 // Goofy deltaY, to the right
+00328                 dstDeltaY=1;
+00329 
+00330                 // Larger size
+00331                 larger=nT;
+00332         }
+00333                 
+00334         // Compute the order of the patch
+00335         CTileFarBank::TFarOrder orderX=CTileFarBank::order0;
+00336         uint tileSize=0;
+00337         switch ((larger*NL_NUM_FAR_PATCHES_BY_EDGE*NL_NUM_PIXELS_ON_FAR_TILE_EDGE)/_Width)
+00338         {
+00339         case 4:
+00340                 // Ratio 1:4
+00341                 orderX=CTileFarBank::order2;
+00342                 tileSize=NL_NUM_PIXELS_ON_FAR_TILE_EDGE>>2;
+00343                 break;
+00344         case 2:
+00345                 // Ratio 1:2
+00346                 orderX=CTileFarBank::order1;
+00347                 tileSize=NL_NUM_PIXELS_ON_FAR_TILE_EDGE>>1;
+00348                 break;
+00349         case 1:
+00350                 // Ratio 1:1
+00351                 orderX=CTileFarBank::order0;
+00352                 tileSize=NL_NUM_PIXELS_ON_FAR_TILE_EDGE;
+00353                 break;
+00354         default:
+00355                 // no!: must be one of the previous values
+00356                 nlassert (0);
+00357         }
+00358 
+00359 #ifdef NL_DEBUG
+00360         // Compute the Y order
+00361         CTileFarBank::TFarOrder orderY;
+00362         switch ((std::min(nS, nT)*NL_NUM_FAR_PATCHES_BY_EDGE*NL_NUM_PIXELS_ON_FAR_TILE_EDGE)/_Height)
+00363         {
+00364         case 4:
+00365                 // Ratio 1:4
+00366                 orderY=CTileFarBank::order2;
+00367                 break;
+00368         case 2:
+00369                 // Ratio 1:2
+00370                 orderY=CTileFarBank::order1;
+00371                 break;
+00372         case 1:
+00373                 // Ratio 1:1
+00374                 orderY=CTileFarBank::order0;
+00375                 break;
+00376         default:
+00377                 // no!: must be one of the previous values
+00378                 nlassert (0);
+00379         }
+00380 
+00381         // Check the ratio on Y is the same than on X
+00382         nlassert (orderX == orderY);
+00383 #endif // NL_DEBUG
+00384         // Must have a far tile bank pointer set in the CFarTexture
+00385         nlassert (_Bank);
+00386 
+00387         // For all the tiles in the textures
+00388         sint nTileInPatch=0;
+00389 
+00390         // ** Fill the struct for the tile fill method for each layers
+00391         NL3D_CComputeTileFar TileFar;
+00392         TileFar.AsmMMX= false;
+00393 #ifdef NL_OS_WINDOWS
+00394         TileFar.AsmMMX= NLMISC::CSystemInfo::hasMMX();
+00395 #endif
+00396 
+00397         // Destination pointer
+00398 
+00399         // Destination delta
+00400         TileFar.DstDeltaX=dstDeltaX;
+00401         TileFar.DstDeltaY=dstDeltaY;
+00402 
+00403         // ** Build expand lightmap..
+00404         NL3D_CExpandLightmap lightMap;
+00405         
+00406         // Fill the structure
+00407         lightMap.MulFactor=tileSize;
+00408         lightMap.ColorTile=&patch->TileColors[0];
+00409         lightMap.Width=nS+1;
+00410         lightMap.Height=nT+1;
+00411         lightMap.StaticLightColor=patch->getZone()->getLandscape()->getStaticLight();
+00412         lightMap.DstPixels=_LightmapExpanded;
+00413         // Compute current TLI colors.
+00414         patch->computeCurrentTLILightmap(_TileTLIColors);
+00415         lightMap.TLIColor= _TileTLIColors;
+00416 
+00417         // Expand the shadowmap
+00418         patch->unpackShadowMap (_LumelExpanded);
+00419         lightMap.LumelTile=_LumelExpanded;
+00420 
+00421         // Expand the patch lightmap now
+00422         NL3D_expandLightmap (&lightMap);
+00423 
+00424         // DeltaY for lightmap
+00425         TileFar.SrcLightingDeltaY=nS*tileSize;
+00426 
+00427         // Base Dst pointer on the tile line
+00428         uint nBaseDstTileLine=nBaseOffset;
+00429         for (uint t=0; t<nT; t++)
+00430         {
+00431                 // Base Dst pointer on the tile
+00432                 uint nBaseDstTilePixels=nBaseDstTileLine;
+00433 
+00434                 // For each tile of the line
+00435                 for (uint s=0; s<nS; s++)
+00436                 {
+00437                         // Base pointer of the destination texture
+00438                         TileFar.DstPixels=(CRGBA*)&(getPixels()[0])+nBaseDstTilePixels;
+00439 
+00440                         // Lightmap pointer
+00441                         TileFar.SrcLightingPixels=_LightmapExpanded+(s*tileSize)+(t*nS*tileSize*tileSize);
+00442 
+00443                         // For each layer of the tile
+00444                         for (sint l=0; l<3; l++)
+00445                         {
+00446                                 // Use of additive in this layer ?
+00447                                 bool bAdditive=false;
+00448 
+00449                                 // Size of the edge far tile
+00450                                 TileFar.Size=tileSize;
+00451 
+00452                                 // Get a tile element reference for this tile.
+00453                                 const CTileElement &tileElm=patch->Tiles[nTileInPatch];
+00454 
+00455                                 // Check for 256 tiles...
+00456                                 bool    is256x256;
+00457                                 uint8   uvOff;
+00458                                 tileElm.getTile256Info(is256x256, uvOff);
+00459 
+00460                                 // Get the tile number
+00461                                 sint tile=tileElm.Tile[l];
+00462 
+00463                                 // Is the last layer ?
+00464                                 bool lastLayer = ( (l == 2) || (tileElm.Tile[l+1] == NL_TILE_ELM_LAYER_EMPTY) );
+00465 
+00466                                 // Is an non-empty layer ?
+00467                                 if (tile!=NL_TILE_ELM_LAYER_EMPTY)
+00468                                 {
+00469                                         // Get the read only pointer on the far tile
+00470                                         const CTileFarBank::CTileFar*   pTile=_Bank->getTile (tile);
+00471 
+00472                                         // This pointer must not be null, else the farBank is not valid!
+00473                                         if (pTile==NULL)
+00474                                                 nlwarning ("FarBank is not valid!");
+00475 
+00476                                         // If the tile exist
+00477                                         if (pTile)
+00478                                         {
+00479                                                 // Tile exist ?
+00480                                                 if (pTile->isFill (CTileFarBank::diffuse))
+00481                                                 {
+00482                                                         // Get rotation of the tile in this layer
+00483                                                         sint nRot=tileElm.getTileOrient(l);
+00484 
+00485                                                         // Source pointer
+00486                                                         const CRGBA*    pSrcDiffusePixels=pTile->getPixels (CTileFarBank::diffuse, orderX);
+00487                                                         const CRGBA*    pSrcAdditivePixels=NULL;
+00488 
+00489                                                         // Additive ?
+00490                                                         if (pTile->isFill (CTileFarBank::additive))
+00491                                                         {
+00492                                                                 // Use it
+00493                                                                 bAdditive=true;
+00494 
+00495                                                                 // Get additive pointer
+00496                                                                 pSrcAdditivePixels=pTile->getPixels (CTileFarBank::additive, orderX);
+00497                                                         }
+00498 
+00499                                                         // Source size
+00500                                                         sint sourceSize;
+00501 
+00502                                                         // Source offset (for 256)
+00503                                                         uint sourceOffset=0;
+00504 
+00505                                                         // 256 ?
+00506                                                         if (is256x256)
+00507                                                         {
+00508                                                                 // On the left ?
+00509                                                                 if (uvOff&0x02)
+00510                                                                         sourceOffset+=tileSize;
+00511 
+00512                                                                 // On the bottom ?
+00513                                                                 if ((uvOff==1)||(uvOff==2))
+00514                                                                         sourceOffset+=2*tileSize*tileSize;
+00515 
+00516                                                                 // Yes, 256
+00517                                                                 sourceSize=tileSize<<1;
+00518                                                         }
+00519                                                         else
+00520                                                         {
+00521                                                                 // No, 128
+00522                                                                 sourceSize=tileSize;
+00523                                                         }
+00524 
+00525                                                         // Compute offset and deltas
+00526                                                         switch (nRot)
+00527                                                         {
+00528                                                         case 0:
+00529                                                                 // Source pointers
+00530                                                                 TileFar.SrcDiffusePixels=pSrcDiffusePixels+sourceOffset;
+00531                                                                 TileFar.SrcAdditivePixels=pSrcAdditivePixels+sourceOffset;
+00532 
+00533                                                                 // Source delta
+00534                                                                 TileFar.SrcDeltaX=1;
+00535                                                                 TileFar.SrcDeltaY=sourceSize;
+00536                                                                 break;
+00537                                                         case 1:
+00538                                                                 {
+00539                                                                         // Source pointers
+00540                                                                         uint newOffset=sourceOffset+(tileSize-1);
+00541                                                                         TileFar.SrcDiffusePixels=pSrcDiffusePixels+newOffset;
+00542                                                                         TileFar.SrcAdditivePixels=pSrcAdditivePixels+newOffset;
+00543 
+00544                                                                         // Source delta
+00545                                                                         TileFar.SrcDeltaX=sourceSize;
+00546                                                                         TileFar.SrcDeltaY=-1;
+00547                                                                 }
+00548                                                                 break;
+00549                                                         case 2:
+00550                                                                 {
+00551                                                                         // Destination pointer
+00552                                                                         uint newOffset=sourceOffset+(tileSize-1)*sourceSize+tileSize-1;
+00553                                                                         TileFar.SrcDiffusePixels=pSrcDiffusePixels+newOffset;
+00554                                                                         TileFar.SrcAdditivePixels=pSrcAdditivePixels+newOffset;
+00555 
+00556                                                                         // Source delta
+00557                                                                         TileFar.SrcDeltaX=-1;
+00558                                                                         TileFar.SrcDeltaY=-sourceSize;
+00559                                                                 }
+00560                                                                 break;
+00561                                                         case 3:
+00562                                                                 {
+00563                                                                         // Destination pointer
+00564                                                                         uint newOffset=sourceOffset+(tileSize-1)*sourceSize;
+00565                                                                         TileFar.SrcDiffusePixels=pSrcDiffusePixels+newOffset;
+00566                                                                         TileFar.SrcAdditivePixels=pSrcAdditivePixels+newOffset;
+00567 
+00568                                                                         // Source delta
+00569                                                                         TileFar.SrcDeltaX=-sourceSize;
+00570                                                                         TileFar.SrcDeltaY=1;
+00571                                                                 }
+00572                                                                 break;
+00573                                                         }
+00574 
+00575                                                         // *** Draw the layer
+00576 
+00577                                                         // Alpha layer ?
+00578                                                         if (l>0)
+00579                                                         {
+00580                                                                 // Additive layer ?
+00581                                                                 if (bAdditive && lastLayer)
+00582                                                                         NL3D_drawFarTileInFarTextureAdditiveAlpha (&TileFar);
+00583                                                                 else    // No additive layer
+00584                                                                         NL3D_drawFarTileInFarTextureAlpha (&TileFar);
+00585                                                         }
+00586                                                         else    // no alpha
+00587                                                         {
+00588                                                                 // Additive layer ?
+00589                                                                 if (bAdditive && lastLayer)
+00590                                                                         NL3D_drawFarTileInFarTextureAdditive (&TileFar);
+00591                                                                 else    // No additive layer
+00592                                                                         NL3D_drawFarTileInFarTexture (&TileFar);
+00593                                                         }
+00594                                                 }
+00595                                         }
+00596                                 }
+00597                                 else
+00598                                         // Stop, no more layer
+00599                                         break;
+00600                         }
+00601                                                 
+00602                         // Next tile
+00603                         nTileInPatch++;
+00604                         
+00605                         // Next tile on the line
+00606                         nBaseDstTilePixels+=dstDeltaX*tileSize;
+00607                 }
+00608 
+00609                 // Next line of tiles
+00610                 nBaseDstTileLine+=dstDeltaY*tileSize;
+00611         }
+00612 
+00613 }
+00614 
+00615 } // NL3D
+00616 
+00617 
+00618 // ***************************************************************************
+00619 // ***************************************************************************
+00620 // NL3D_ExpandLightmap. C and Asm Part
+00621 // ***************************************************************************
+00622 // ***************************************************************************
+00623 
+00624 #ifdef NL_OS_WINDOWS
+00625 
+00626 
+00627 // EMMS called not in __asm block.
+00628 #  pragma warning (disable : 4799)
+00629 
+00630 
+00631 // ***************************************************************************
+00632 inline  void    NL3D_asmEndMMX()
+00633 {
+00634         __asm
+00635         {
+00636                 // close MMX computation
+00637                 emms
+00638         }
+00639 }
+00640 
+00641 
+00642 // ***************************************************************************
+00646 inline  void    NL3D_asmExpandLineColor565(const uint16 *src, CRGBA *dst, uint du, uint len)
+00647 {
+00648         static  uint64 blank = 0;
+00649         static  uint64 cF800 = 0x0000F8000000F800;
+00650         static  uint64 cE000 = 0x0000E0000000E000;
+00651         static  uint64 c07E0 = 0x000007E0000007E0;
+00652         static  uint64 c0600 = 0x0000060000000600;
+00653         static  uint64 c001F = 0x0000001F0000001F;
+00654         static  uint64 c001C = 0x0000001C0000001C;
+00655         if(len==0)
+00656                 return;
+00657 
+00658 
+00659         // Loop for pix.
+00660         __asm
+00661         {
+00662                 movq    mm7, blank
+00663 
+00664                 // start at pixel 1 => increment dst, and start u= du
+00665                 mov             esi, src
+00666                 mov             edi, dst
+00667                 add             edi, 4
+00668                 mov             ecx, len
+00669                 mov             edx, du
+00670 
+00671                 // Loop
+00672         myLoop:
+00673 
+00674 
+00675                 // Read 565 colors
+00676                 //----------
+00677                 // index u.
+00678                 mov             ebx, edx
+00679                 shr             ebx, 8
+00680 
+00681                 // pack the 2 colors in eax: // Hedx= color0, Ledx= color1
+00682                 xor             eax, eax                        // avoid partial stall.
+00683                 mov             ax, [esi + ebx*2]
+00684                 shl             eax, 16
+00685                 mov             ax, [esi + ebx*2 +2]
+00686                 
+00687                 // store and unpack in mm2: Hmm2= color0, Lmm2= color1
+00688                 movd    mm2, eax
+00689                 punpcklwd       mm2, mm7
+00690 
+00691                 // reset accumulator mm3 to black
+00692                 movq    mm3, mm7
+00693 
+00694                 // Expand 565 to 888: color0 and color1 in parrallel
+00695                 // R
+00696                 movq    mm0, mm2
+00697                 movq    mm1, mm2
+00698                 pand    mm0, cF800
+00699                 pand    mm1, cE000
+00700                 psrld   mm0, 8
+00701                 psrld   mm1, 13
+00702                 por             mm3, mm0
+00703                 por             mm3, mm1
+00704                 // G
+00705                 movq    mm0, mm2
+00706                 movq    mm1, mm2
+00707                 pand    mm0, c07E0
+00708                 pand    mm1, c0600
+00709                 pslld   mm0, 5
+00710                 psrld   mm1, 1
+00711                 por             mm3, mm0
+00712                 por             mm3, mm1
+00713                 // B
+00714                 movq    mm0, mm2
+00715                 movq    mm1, mm2
+00716                 pand    mm0, c001F
+00717                 pand    mm1, c001C
+00718                 pslld   mm0, 19
+00719                 pslld   mm1, 14
+00720                 por             mm3, mm0
+00721                 por             mm3, mm1
+00722 
+00723                 // unpack mm3 quad to mm0=color0 and mm1=color1.
+00724                 movq    mm0, mm3
+00725                 movq    mm1, mm3
+00726                 psrlq   mm0, 32
+00727 
+00728 
+00729                 // Blend.
+00730                 //----------
+00731                 // blend factors
+00732                 mov             ebx, edx
+00733                 mov             eax, 256
+00734 
+00735                 and             ebx, 0xFF
+00736                 sub             eax, ebx
+00737 
+00738                 movd    mm2, ebx                // mm2= factor
+00739                 movd    mm3, eax                // mm3= 1-factor
+00740                 // replicate to the     4 words.
+00741                 punpckldq       mm2, mm2        // mm2= 0000 00AA 0000 00AA
+00742                 punpckldq       mm3, mm3        // mm3= 0000 00AA 0000 00AA
+00743                 packssdw        mm2, mm2        // mm2= 00AA 00AA 00AA 00AA
+00744                 packssdw        mm3, mm3        // mm3= 00AA 00AA 00AA 00AA
+00745 
+00746                 // mul
+00747                 punpcklbw       mm0, mm7
+00748                 punpcklbw       mm1, mm7
+00749                 pmullw          mm0, mm3        // color0*(1-factor)
+00750                 pmullw          mm1, mm2        // color1*factor
+00751                 // add, and unpack
+00752                 paddusw         mm0, mm1
+00753                 psrlw       mm0, 8
+00754                 packuswb    mm0, mm0
+00755 
+00756                 // store
+00757                 movd        [edi], mm0
+00758 
+00759 
+00760                 // next pix
+00761                 add     edx, du
+00762                 add     edi, 4
+00763                 dec ecx
+00764                 jnz myLoop
+00765         }
+00766 }
+00767 
+00768 
+00769 // ***************************************************************************
+00773 inline  void    NL3D_asmExpandLineColor8888(const CRGBA *src, CRGBA *dst, uint du, uint len)
+00774 {
+00775         static  uint64 blank = 0;
+00776         if(len==0)
+00777                 return;
+00778 
+00779 
+00780         // Loop for pix.
+00781         __asm
+00782         {
+00783                 movq    mm7, blank
+00784 
+00785                 // start at pixel 1 => increment dst, and start u= du
+00786                 mov             esi, src
+00787                 mov             edi, dst
+00788                 add             edi, 4
+00789                 mov             ecx, len
+00790                 mov             edx, du
+00791 
+00792                 // Loop
+00793         myLoop:
+00794 
+00795 
+00796                 // Read 8888 colors
+00797                 //----------
+00798                 // index u.
+00799                 mov             ebx, edx
+00800                 shr             ebx, 8
+00801 
+00802                 // read the 2 colors: mm0= color0, mm1= color1
+00803                 movd    mm0 , [esi + ebx*4]
+00804                 movd    mm1 , [esi + ebx*4 + 4]
+00805 
+00806 
+00807                 // Blend.
+00808                 //----------
+00809                 // blend factors
+00810                 mov             ebx, edx
+00811                 mov             eax, 256
+00812 
+00813                 and             ebx, 0xFF
+00814                 sub             eax, ebx
+00815 
+00816                 movd    mm2, ebx                // mm2= factor
+00817                 movd    mm3, eax                // mm3= 1-factor
+00818                 // replicate to the     4 words.
+00819                 punpckldq       mm2, mm2        // mm2= 0000 00AA 0000 00AA
+00820                 punpckldq       mm3, mm3        // mm3= 0000 00AA 0000 00AA
+00821                 packssdw        mm2, mm2        // mm2= 00AA 00AA 00AA 00AA
+00822                 packssdw        mm3, mm3        // mm3= 00AA 00AA 00AA 00AA
+00823 
+00824                 // mul
+00825                 punpcklbw       mm0, mm7
+00826                 punpcklbw       mm1, mm7
+00827                 pmullw          mm0, mm3        // color0*(1-factor)
+00828                 pmullw          mm1, mm2        // color1*factor
+00829                 // add, and unpack
+00830                 paddusw         mm0, mm1
+00831                 psrlw       mm0, 8
+00832                 packuswb    mm0, mm0
+00833 
+00834                 // store
+00835                 movd        [edi], mm0
+00836 
+00837 
+00838                 // next pix
+00839                 add     edx, du
+00840                 add     edi, 4
+00841                 dec ecx
+00842                 jnz myLoop
+00843         }
+00844 }
+00845 
+00846 
+00847 // ***************************************************************************
+00851 inline  void    NL3D_asmBlendLines(CRGBA *dst, const CRGBA *src0, const CRGBA *src1, uint index, uint len)
+00852 {
+00853         static  uint64 blank = 0;
+00854         if(len==0)
+00855                 return;
+00856 
+00857 
+00858         // Loop for pix.
+00859         __asm
+00860         {
+00861                 movq    mm7, blank
+00862 
+00863                 // read the factor and expand it to 4 words.
+00864                 mov             ebx, index
+00865                 mov             eax, 256
+00866                 and             ebx, 0xFF
+00867                 sub             eax, ebx
+00868                 movd    mm2, ebx                // mm2= factor
+00869                 movd    mm3, eax                // mm3= 1-factor
+00870                 punpckldq       mm2, mm2        // mm2= 0000 00AA 0000 00AA
+00871                 punpckldq       mm3, mm3        // mm3= 0000 00AA 0000 00AA
+00872                 packssdw        mm2, mm2        // mm2= 00AA 00AA 00AA 00AA
+00873                 packssdw        mm3, mm3        // mm3= 00AA 00AA 00AA 00AA
+00874 
+00875                 // setup ptrs
+00876                 mov             esi, src0
+00877                 mov             edx, src1
+00878                 sub             edx, esi        // difference between 2 src
+00879                 mov             edi, dst
+00880                 mov             ecx, len
+00881 
+00882                 // Loop
+00883         myLoop:
+00884 
+00885                 // Read
+00886                 movd    mm0, [esi]
+00887                 movd    mm1, [esi+edx]
+00888 
+00889                 // mul
+00890                 punpcklbw       mm0, mm7
+00891                 punpcklbw       mm1, mm7
+00892                 pmullw          mm0, mm3        // color0*(1-factor)
+00893                 pmullw          mm1, mm2        // color1*factor
+00894                 // add, and unpack
+00895                 paddusw         mm0, mm1
+00896                 psrlw       mm0, 8
+00897                 packuswb    mm0, mm0
+00898 
+00899                 // store
+00900                 movd        [edi], mm0
+00901 
+00902 
+00903                 // next pix
+00904                 add     esi, 4
+00905                 add     edi, 4
+00906                 dec ecx
+00907                 jnz myLoop
+00908         }
+00909 }
+00910 
+00911 
+00912 // ***************************************************************************
+00916 static void             NL3D_asmAssembleShading1x1(const uint8 *lumels, const CRGBA *colorMap, 
+00917         const CRGBA *srcTLIs, const CRGBA *srcUSCs, CRGBA *dst, uint lineWidth, uint nbTexel)
+00918 {
+00919         static  uint64 blank = 0;
+00920         if(nbTexel==0)
+00921                 return;
+00922 
+00923         // local var
+00924         uint    offsetTLIs= ((uint)srcTLIs-(uint)dst);
+00925         uint    offsetUSCs= ((uint)srcUSCs-(uint)dst);
+00926 
+00927         // Loop for pix.
+00928         __asm
+00929         {
+00930                 movq            mm7, blank
+00931 
+00932                 // setup ptrs
+00933                 mov                     esi, lumels
+00934                 mov                     edi, dst
+00935                 mov                     ecx, nbTexel
+00936 
+00937                 // Loop
+00938         myLoop:
+00939 
+00940                 // Average shade part
+00941                 //------------
+00942                 mov                     ebx, colorMap
+00943                 mov                     edx, lineWidth
+00944 
+00945                 // read and accumulate shade 
+00946                 xor                     eax,eax                 // avoid partial stall
+00947                 // add with line 0
+00948                 mov                     al, [esi + 0]
+00949                 add                     al, [esi + 1]
+00950                 adc                     ah, 0
+00951                 add                     al, [esi + 2]
+00952                 adc                     ah, 0
+00953                 add                     al, [esi + 3]
+00954                 adc                     ah, 0
+00955                 // add with line 1
+00956                 add                     al, [esi + edx + 0]
+00957                 adc                     ah, 0
+00958                 add                     al, [esi + edx + 1]
+00959                 adc                     ah, 0
+00960                 add                     al, [esi + edx + 2]
+00961                 adc                     ah, 0
+00962                 add                     al, [esi + edx + 3]
+00963                 adc                     ah, 0
+00964                 // add with line 2
+00965                 add                     al, [esi + edx*2 + 0]
+00966                 adc                     ah, 0
+00967                 add                     al, [esi + edx*2 + 1]
+00968                 adc                     ah, 0
+00969                 add                     al, [esi + edx*2 + 2]
+00970                 adc                     ah, 0
+00971                 add                     al, [esi + edx*2 + 3]
+00972                 adc                     ah, 0
+00973                 // add with line 3
+00974                 lea                     edx, [edx + edx*2]
+00975                 add                     al, [esi + edx + 0]
+00976                 adc                     ah, 0
+00977                 add                     al, [esi + edx + 1]
+00978                 adc                     ah, 0
+00979                 add                     al, [esi + edx + 2]
+00980                 adc                     ah, 0
+00981                 add                     al, [esi + edx + 3]
+00982                 adc                     ah, 0
+00983                 // average
+00984                 shr                     eax, 4
+00985 
+00986                 // convert to RGBA from the color Map
+00987                 movd            mm0, [ebx + eax*4]
+00988 
+00989                 // Assemble part
+00990                 //------------
+00991                 mov                     edx, offsetTLIs
+00992                 mov                     ebx, offsetUSCs
+00993 
+00994                 // Add with TLI, and clamp.
+00995                 paddusb         mm0, [edi + edx]
+00996 
+00997                 // mul with USC
+00998                 movd            mm1, [edi + ebx]
+00999                 punpcklbw       mm0, mm7
+01000                 punpcklbw       mm1, mm7
+01001                 pmullw          mm0, mm1
+01002                 // unpack
+01003                 psrlw       mm0, 8
+01004                 packuswb    mm0, mm0
+01005 
+01006                 // store
+01007                 movd        [edi], mm0
+01008 
+01009 
+01010                 // next pix
+01011                 add                     esi, 4          // skip 4 lumels
+01012                 add                     edi, 4          // next texel
+01013                 dec                     ecx
+01014                 jnz                     myLoop
+01015         }
+01016 }
+01017 
+01018 
+01019 // ***************************************************************************
+01023 static void             NL3D_asmAssembleShading2x2(const uint8 *lumels, const CRGBA *colorMap, 
+01024         const CRGBA *srcTLIs, const CRGBA *srcUSCs, CRGBA *dst, uint lineWidth, uint nbTexel)
+01025 {
+01026         static  uint64 blank = 0;
+01027         if(nbTexel==0)
+01028                 return;
+01029 
+01030         // local var
+01031         uint    offsetTLIs= ((uint)srcTLIs-(uint)dst);
+01032         uint    offsetUSCs= ((uint)srcUSCs-(uint)dst);
+01033 
+01034         // Loop for pix.
+01035         __asm
+01036         {
+01037                 movq            mm7, blank
+01038 
+01039                 // setup ptrs
+01040                 mov                     esi, lumels
+01041                 mov                     edi, dst
+01042                 mov                     ecx, nbTexel
+01043 
+01044                 // Loop
+01045         myLoop:
+01046 
+01047                 // Average shade part
+01048                 //------------
+01049                 mov                     ebx, colorMap
+01050                 mov                     edx, lineWidth
+01051 
+01052                 // read and accumulate shade 
+01053                 xor                     eax,eax                 // avoid partial stall
+01054                 mov                     al, [esi]               // read lumel
+01055                 // add with nbors
+01056                 add                     al, [esi + 1]
+01057                 adc                     ah, 0
+01058                 add                     al, [esi + edx]
+01059                 adc                     ah, 0
+01060                 add                     al, [esi + edx + 1]
+01061                 adc                     ah, 0
+01062                 // average
+01063                 shr                     eax, 2
+01064 
+01065                 // convert to RGBA from the color Map
+01066                 movd            mm0, [ebx + eax*4]
+01067 
+01068                 // Assemble part
+01069                 //------------
+01070                 mov                     edx, offsetTLIs
+01071                 mov                     ebx, offsetUSCs
+01072 
+01073                 // Add with TLI, and clamp.
+01074                 paddusb         mm0, [edi + edx]
+01075 
+01076                 // mul with USC
+01077                 movd            mm1, [edi + ebx]
+01078                 punpcklbw       mm0, mm7
+01079                 punpcklbw       mm1, mm7
+01080                 pmullw          mm0, mm1
+01081                 // unpack
+01082                 psrlw       mm0, 8
+01083                 packuswb    mm0, mm0
+01084 
+01085                 // store
+01086                 movd        [edi], mm0
+01087 
+01088 
+01089                 // next pix
+01090                 add                     esi, 2          // skip 2 lumels
+01091                 add                     edi, 4          // next texel
+01092                 dec                     ecx
+01093                 jnz                     myLoop
+01094         }
+01095 }
+01096 
+01097 
+01098 // ***************************************************************************
+01099 #  pragma warning (disable : 4731)                      // frame pointer register 'ebp' modified by inline assembly code
+01100 
+01103 static void             NL3D_asmAssembleShading4x4(const uint8 *lumels, const CRGBA *colorMap, 
+01104         const CRGBA *srcTLIs, const CRGBA *srcUSCs, CRGBA *dst, uint nbTexel)
+01105 {
+01106         static  uint64 blank = 0;
+01107         if(nbTexel==0)
+01108                 return;
+01109 
+01110         // Loop for pix.
+01111         __asm
+01112         {
+01113                 // Use ebp as a register for faster access...
+01114                 push            ebp
+01115 
+01116                 movq            mm7, blank
+01117 
+01118                 // setup ptrs
+01119                 mov                     esi, lumels
+01120                 mov                     edi, dst
+01121                 mov                     edx, srcTLIs
+01122                 sub                     edx, edi        // difference src and dest
+01123                 mov                     ebx, srcUSCs
+01124                 sub                     ebx, edi        // difference src and dest
+01125                 mov                     ecx, nbTexel
+01126 
+01127                 // set ebp after reading locals...
+01128                 mov                     ebp, colorMap
+01129 
+01130                 // Loop
+01131         myLoop:
+01132 
+01133                 // read shade RGBA into the color Map
+01134                 xor                     eax,eax                 // avoid partial stall
+01135                 mov                     al,[esi]                // read lumel
+01136                 movd            mm0, [ebp + eax*4]
+01137 
+01138                 // Add with TLI, and clamp.
+01139                 paddusb         mm0, [edi + edx]
+01140 
+01141                 // mul with USC
+01142                 movd            mm1, [edi + ebx]
+01143                 punpcklbw       mm0, mm7
+01144                 punpcklbw       mm1, mm7
+01145                 pmullw          mm0, mm1
+01146                 // unpack
+01147                 psrlw       mm0, 8
+01148                 packuswb    mm0, mm0
+01149 
+01150                 // store
+01151                 movd        [edi], mm0
+01152 
+01153 
+01154                 // next pix
+01155                 add                     esi, 1          // next lumel
+01156                 add                     edi, 4          // next texel
+01157                 dec                     ecx
+01158                 jnz                     myLoop
+01159 
+01160                 // restore
+01161                 pop                     ebp
+01162         }
+01163 
+01164 }
+01165 
+01166 #  pragma warning (default : 4731)                      // frame pointer register 'ebp' modified by inline assembly code
+01167 
+01168 
+01169 #else // NL_OS_WINDOWS
+01170 
+01171 // Dummy for non-windows platforms
+01172 inline  void    NL3D_asmEndMMX() {}
+01173 inline  void    NL3D_asmExpandLineColor565(const uint16 *src, CRGBA *dst, uint du, uint len) {}
+01174 inline  void    NL3D_asmExpandLineColor8888(const CRGBA *src, CRGBA *dst, uint du, uint len) {}
+01175 inline  void    NL3D_asmBlendLines(CRGBA *dst, const CRGBA *src0, const CRGBA *src1, uint index, uint len) {}
+01176 static void             NL3D_asmAssembleShading1x1(const uint8 *lumels, const CRGBA *colorMap, 
+01177         const CRGBA *srcTLIs, const CRGBA *srcUSCs, CRGBA *dst, uint lineWidth, uint nbTexel)
+01178 {
+01179 }
+01180 static void             NL3D_asmAssembleShading2x2(const uint8 *lumels, const CRGBA *colorMap, 
+01181         const CRGBA *srcTLIs, const CRGBA *srcUSCs, CRGBA *dst, uint lineWidth, uint nbTexel)
+01182 {
+01183 }
+01184 static void             NL3D_asmAssembleShading4x4(const uint8 *lumels, const CRGBA *colorMap, 
+01185         const CRGBA *srcTLIs, const CRGBA *srcUSCs, CRGBA *dst, uint nbTexel)
+01186 {
+01187 }
+01188 
+01189 #endif // NL_OS_WINDOWS
+01190 
+01191 
+01192 // ***************************************************************************
+01193 extern "C" void NL3D_expandLightmap (const NL3D_CExpandLightmap* pLightmap)
+01194 {
+01195         bool    asmMMX= false;
+01196 #ifdef  NL_OS_WINDOWS
+01197         asmMMX= CSystemInfo::hasMMX();
+01198         // A CTileColor must be a 565 only.
+01199         nlassert(sizeof(CTileColor)==2);
+01200 #endif
+01201 
+01202         // Expanded width
+01203         uint dstWidth=(pLightmap->Width-1)*pLightmap->MulFactor;
+01204         uint dstHeight=(pLightmap->Height-1)*pLightmap->MulFactor;
+01205 
+01206         // *** First expand user color and TLI colors
+01207         // First pass, expand on U
+01208         static CRGBA expandedUserColorLine[ (NL_MAX_TILES_BY_PATCH_EDGE+1)*
+01209                 (NL_MAX_TILES_BY_PATCH_EDGE+1)*NL_LUMEL_BY_TILE ];
+01210         static CRGBA expandedTLIColorLine[ (NL_MAX_TILES_BY_PATCH_EDGE+1)*
+01211                 (NL_MAX_TILES_BY_PATCH_EDGE+1)*NL_LUMEL_BY_TILE ];
+01212         // Second pass, expand on V.
+01213         static CRGBA expandedUserColor[ (NL_MAX_TILES_BY_PATCH_EDGE+1)*NL_LUMEL_BY_TILE * 
+01214                 (NL_MAX_TILES_BY_PATCH_EDGE+1)*NL_LUMEL_BY_TILE ];
+01215         static CRGBA expandedTLIColor[ (NL_MAX_TILES_BY_PATCH_EDGE+1)*NL_LUMEL_BY_TILE * 
+01216                 (NL_MAX_TILES_BY_PATCH_EDGE+1)*NL_LUMEL_BY_TILE ];
+01217 
+01218 
+01219         // ** Expand on U
+01220         //=========
+01221         uint u, v;
+01222 
+01223         // Expansion factor
+01224         uint expandFactor=((pLightmap->Width-1)<<8)/(dstWidth-1);
+01225 
+01226         // Destination  pointer
+01227         CRGBA *expandedUserColorLinePtr= expandedUserColorLine;
+01228         CRGBA *expandedTLIColorLinePtr= expandedTLIColorLine;
+01229 
+01230         // Source pointer
+01231         const NL3D::CTileColor  *colorTilePtr=pLightmap->ColorTile;
+01232         const NLMISC::CRGBA             *colorTLIPtr= pLightmap->TLIColor;
+01233 
+01234         // Go for U
+01235         for (v=0; v<pLightmap->Height; v++)
+01236         {
+01237                 // First pixel
+01238                 expandedUserColorLinePtr[0].set565 (colorTilePtr[0].Color565);
+01239                 expandedTLIColorLinePtr[0]= colorTLIPtr[0];
+01240 
+01241                 // MMX implementation.
+01242                 //-------------
+01243                 if(asmMMX)
+01244                 {
+01245                         NL3D_asmExpandLineColor565(&colorTilePtr->Color565, expandedUserColorLinePtr, expandFactor, dstWidth-2);
+01246                         NL3D_asmExpandLineColor8888(colorTLIPtr, expandedTLIColorLinePtr, expandFactor, dstWidth-2);
+01247                 }
+01248                 // C implementation
+01249                 //-------------
+01250                 else
+01251                 {
+01252                         // Index next pixel
+01253                         uint srcIndexPixel=expandFactor;
+01254 
+01255                         for (u=1; u<dstWidth-1; u++)
+01256                         {
+01257                                 // Check
+01258                                 nlassert ( (u+v*dstWidth) < (sizeof(expandedUserColorLine)/sizeof(CRGBA)) );
+01259 
+01260                                 // Color index
+01261                                 uint srcIndex=srcIndexPixel>>8;
+01262                                 nlassert (srcIndex>=0);
+01263                                 nlassert (srcIndex<pLightmap->Width-1);
+01264 
+01265                                 // Compute current color
+01266                                 CRGBA color0;
+01267                                 CRGBA color1;
+01268                                 color0.set565 (colorTilePtr[srcIndex].Color565);
+01269                                 color1.set565 (colorTilePtr[srcIndex+1].Color565);
+01270                                 expandedUserColorLinePtr[u].blendFromui (color0, color1, srcIndexPixel&0xff);
+01271                                 // Compute current TLI color
+01272                                 color0= colorTLIPtr[srcIndex];
+01273                                 color1= colorTLIPtr[srcIndex+1];
+01274                                 expandedTLIColorLinePtr[u].blendFromui (color0, color1, srcIndexPixel&0xff);
+01275 
+01276                                 // Next index
+01277                                 srcIndexPixel+=expandFactor;
+01278                         }
+01279                 }
+01280 
+01281                 // Last pixel
+01282                 expandedUserColorLinePtr[dstWidth-1].set565 (colorTilePtr[pLightmap->Width-1].Color565);
+01283                 expandedTLIColorLinePtr[dstWidth-1]= colorTLIPtr[pLightmap->Width-1];
+01284 
+01285                 // Next line
+01286                 expandedUserColorLinePtr+= dstWidth;
+01287                 expandedTLIColorLinePtr+= dstWidth;
+01288                 colorTilePtr+=pLightmap->Width;
+01289                 colorTLIPtr+=pLightmap->Width;
+01290         }
+01291 
+01292         // stop MMX if used
+01293         if(asmMMX)
+01294                 NL3D_asmEndMMX();
+01295 
+01296         // ** Expand on V
+01297         //=========
+01298 
+01299         // Expansion factor
+01300         expandFactor=((pLightmap->Height-1)<<8)/(dstHeight-1);
+01301 
+01302         // Destination  pointer
+01303         CRGBA *expandedUserColorPtr= expandedUserColor;
+01304         CRGBA *expandedTLIColorPtr= expandedTLIColor;
+01305 
+01306         // Src pointer
+01307         expandedUserColorLinePtr= expandedUserColorLine;
+01308         expandedTLIColorLinePtr= expandedTLIColorLine;
+01309 
+01310         // Copy first row
+01311         memcpy(expandedUserColorPtr, expandedUserColorLinePtr, dstWidth*sizeof(CRGBA));
+01312         memcpy(expandedTLIColorPtr, expandedTLIColorLinePtr, dstWidth*sizeof(CRGBA));
+01313 
+01314         // Next line
+01315         expandedUserColorPtr+=dstWidth;
+01316         expandedTLIColorPtr+=dstWidth;
+01317 
+01318         // Index next pixel
+01319         uint indexPixel=expandFactor;
+01320 
+01321         // Go for V
+01322         for (v=1; v<dstHeight-1; v++)
+01323         {
+01324                 // Color index
+01325                 uint index=indexPixel>>8;
+01326 
+01327                 // Source pointer
+01328                 CRGBA *colorTilePtr0= expandedUserColorLine + index*dstWidth;
+01329                 CRGBA *colorTilePtr1= expandedUserColorLine + (index+1)*dstWidth;
+01330                 CRGBA *colorTLIPtr0= expandedTLIColorLine + index*dstWidth;
+01331                 CRGBA *colorTLIPtr1= expandedTLIColorLine + (index+1)*dstWidth;
+01332 
+01333                 // MMX implementation.
+01334                 //-------------
+01335                 if(asmMMX)
+01336                 {
+01337                         NL3D_asmBlendLines(expandedUserColorPtr, colorTilePtr0, colorTilePtr1, indexPixel, dstWidth);
+01338                         NL3D_asmBlendLines(expandedTLIColorPtr, colorTLIPtr0, colorTLIPtr1, indexPixel, dstWidth);
+01339                 }
+01340                 // C implementation
+01341                 //-------------
+01342                 else
+01343                 {
+01344                         // Copy the row
+01345                         for (u=0; u<dstWidth; u++)
+01346                         {
+01347                                 expandedUserColorPtr[u].blendFromui (colorTilePtr0[u], colorTilePtr1[u], indexPixel&0xff);
+01348                                 expandedTLIColorPtr[u].blendFromui (colorTLIPtr0[u], colorTLIPtr1[u],  indexPixel&0xff);
+01349                         }
+01350                 }
+01351 
+01352                 // Next index
+01353                 indexPixel+=expandFactor;
+01354 
+01355                 // Next line
+01356                 expandedUserColorPtr+=dstWidth;
+01357                 expandedTLIColorPtr+=dstWidth;
+01358         }
+01359 
+01360         // stop MMX if used
+01361         if(asmMMX)
+01362                 NL3D_asmEndMMX();
+01363 
+01364         // Last row
+01365         // Destination  pointer
+01366         expandedUserColorPtr= expandedUserColor + dstWidth*(dstHeight-1);
+01367         expandedTLIColorPtr= expandedTLIColor + dstWidth*(dstHeight-1);
+01368         // Src pointer
+01369         expandedUserColorLinePtr= expandedUserColorLine + dstWidth*(pLightmap->Height-1);
+01370         expandedTLIColorLinePtr= expandedTLIColorLine + dstWidth*(pLightmap->Height-1);
+01371 
+01372         // Copy last row
+01373         memcpy(expandedUserColorPtr, expandedUserColorLinePtr, dstWidth*sizeof(CRGBA));
+01374         memcpy(expandedTLIColorPtr, expandedTLIColorLinePtr, dstWidth*sizeof(CRGBA));
+01375 
+01376         // *** Now combine with shading
+01377         //=========
+01378 
+01379         // Switch to the optimal method for each expansion value
+01380         switch (pLightmap->MulFactor)
+01381         {
+01382         case 1:
+01383                 {
+01384                         // Make 4x4 -> 1x1 blend
+01385                         CRGBA *lineUSCPtr= expandedUserColor;
+01386                         CRGBA *lineTLIPtr= expandedTLIColor;
+01387                         CRGBA *lineDestPtr=pLightmap->DstPixels;
+01388                         const uint8 *lineLumelPtr=pLightmap->LumelTile;
+01389                         uint lineWidth=dstWidth<<2;
+01390                         uint lineWidthx2=lineWidth<<1;
+01391                         uint lineWidthx3=lineWidthx2+lineWidth;
+01392                         uint lineWidthx4=lineWidth<<2;
+01393 
+01394                         // For each line
+01395                         for (v=0; v<dstHeight; v++)
+01396                         {
+01397                                 // MMX implementation.
+01398                                 //-------------
+01399                                 if(asmMMX)
+01400                                 {
+01401                                         NL3D_asmAssembleShading1x1(lineLumelPtr, pLightmap->StaticLightColor, lineTLIPtr, lineUSCPtr, lineDestPtr,
+01402                                                 lineWidth, dstWidth);
+01403                                 }
+01404                                 // C implementation
+01405                                 //-------------
+01406                                 else
+01407                                 {
+01408                                         // For each lumel block
+01409                                         for (u=0; u<dstWidth; u++)
+01410                                         {
+01411                                                 // index
+01412                                                 uint lumelIndex=u<<2;
+01413 
+01414                                                 // Shading is filtred
+01415                                                 uint shading=
+01416                                                          ((uint)lineLumelPtr[lumelIndex]+(uint)lineLumelPtr[lumelIndex+1]+(uint)lineLumelPtr[lumelIndex+2]+(uint)lineLumelPtr[lumelIndex+3]
+01417                                                         +(uint)lineLumelPtr[lumelIndex+lineWidth]+(uint)lineLumelPtr[lumelIndex+1+lineWidth]+(uint)lineLumelPtr[lumelIndex+2+lineWidth]+(uint)lineLumelPtr[lumelIndex+3+lineWidth]
+01418                                                         +(uint)lineLumelPtr[lumelIndex+lineWidthx2]+(uint)lineLumelPtr[lumelIndex+1+lineWidthx2]+(uint)lineLumelPtr[lumelIndex+2+lineWidthx2]+(uint)lineLumelPtr[lumelIndex+3+lineWidthx2]
+01419                                                         +(uint)lineLumelPtr[lumelIndex+lineWidthx3]+(uint)lineLumelPtr[lumelIndex+1+lineWidthx3]+(uint)lineLumelPtr[lumelIndex+2+lineWidthx3]+(uint)lineLumelPtr[lumelIndex+3+lineWidthx3]
+01420                                                         )>>4;
+01421 
+01422                                                 // Add shading with TLI color.
+01423                                                 CRGBA   col;
+01424                                                 col.addRGBOnly(pLightmap->StaticLightColor[shading], lineTLIPtr[u]);
+01425 
+01426                                                 // Mul by the userColor
+01427                                                 lineDestPtr[u].modulateFromColorRGBOnly(col, lineUSCPtr[u]);
+01428                                         }
+01429                                 }
+01430 
+01431                                 // Next line
+01432                                 lineUSCPtr+=dstWidth;
+01433                                 lineTLIPtr+=dstWidth;
+01434                                 lineDestPtr+=dstWidth;
+01435                                 lineLumelPtr+=lineWidthx4;
+01436                         }
+01437                         break;
+01438                 }
+01439         case 2:
+01440                 {
+01441                         // Make 2x2 -> 1x1 blend
+01442                         CRGBA *lineUSCPtr= expandedUserColor;
+01443                         CRGBA *lineTLIPtr= expandedTLIColor;
+01444                         CRGBA *lineDestPtr=pLightmap->DstPixels;
+01445                         const uint8 *lineLumelPtr=pLightmap->LumelTile;
+01446                         uint lineWidth=dstWidth*2;
+01447                         uint lineWidthx2=lineWidth<<1;
+01448 
+01449                         // For each line
+01450                         for (v=0; v<dstHeight; v++)
+01451                         {
+01452                                 // MMX implementation.
+01453                                 //-------------
+01454                                 if(asmMMX)
+01455                                 {
+01456                                         NL3D_asmAssembleShading2x2(lineLumelPtr, pLightmap->StaticLightColor, lineTLIPtr, lineUSCPtr, lineDestPtr,
+01457                                                 lineWidth, dstWidth);
+01458                                 }
+01459                                 // C implementation
+01460                                 //-------------
+01461                                 else
+01462                                 {
+01463                                         // For each lumel block
+01464                                         for (u=0; u<dstWidth; u++)
+01465                                         {
+01466                                                 // index
+01467                                                 uint lumelIndex=u<<1;
+01468 
+01469                                                 // Shading is filtred
+01470                                                 uint shading=
+01471                                                         ((uint)lineLumelPtr[lumelIndex]+(uint)lineLumelPtr[lumelIndex+1]+(uint)lineLumelPtr[lumelIndex+lineWidth]+(uint)lineLumelPtr[lumelIndex+1+lineWidth])>>2;
+01472 
+01473                                                 // Add shading with TLI color.
+01474                                                 CRGBA   col;
+01475                                                 col.addRGBOnly(pLightmap->StaticLightColor[shading], lineTLIPtr[u]);
+01476 
+01477                                                 // Mul by the userColor
+01478                                                 lineDestPtr[u].modulateFromColorRGBOnly(col, lineUSCPtr[u]);
+01479                                         }
+01480                                 }
+01481 
+01482                                 // Next line
+01483                                 lineUSCPtr+=dstWidth;
+01484                                 lineTLIPtr+=dstWidth;
+01485                                 lineDestPtr+=dstWidth;
+01486                                 lineLumelPtr+=lineWidthx2;
+01487                         }
+01488                         break;
+01489                 }
+01490 
+01491         case 4:
+01492                         // Make copy
+01493                         CRGBA *lineUSCPtr= expandedUserColor;
+01494                         CRGBA *lineTLIPtr= expandedTLIColor;
+01495                         CRGBA *lineDestPtr=pLightmap->DstPixels;
+01496                         const uint8 *lineLumelPtr=pLightmap->LumelTile;
+01497                         uint nbTexel=dstWidth*dstHeight;
+01498 
+01499                         // MMX implementation.
+01500                         //-------------
+01501                         if(asmMMX)
+01502                         {
+01503                                 NL3D_asmAssembleShading4x4(lineLumelPtr, pLightmap->StaticLightColor, lineTLIPtr, lineUSCPtr, lineDestPtr,
+01504                                         nbTexel);
+01505                         }
+01506                         // C implementation
+01507                         //-------------
+01508                         else
+01509                         {
+01510                                 // For each pixel
+01511                                 for (u=0; u<nbTexel; u++)
+01512                                 {
+01513                                         // Shading is filtred
+01514                                         uint shading=lineLumelPtr[u];
+01515 
+01516                                         // Add shading with TLI color.
+01517                                         CRGBA   col;
+01518                                         col.addRGBOnly(pLightmap->StaticLightColor[shading], lineTLIPtr[u]);
+01519 
+01520                                         // Mul by the userColor
+01521                                         lineDestPtr[u].modulateFromColorRGBOnly(col, lineUSCPtr[u]);
+01522                                 }
+01523                         }
+01524                         break;
+01525         }
+01526 
+01527         // stop MMX if used
+01528         if(asmMMX)
+01529                 NL3D_asmEndMMX();
+01530 
+01531 }
+01532 
+01533 
+01534 // ***************************************************************************
+01535 // ***************************************************************************
+01536 // NL3D_drawFarTileInFar*. C and Asm Part
+01537 // ***************************************************************************
+01538 // ***************************************************************************
+01539 
+01540 
+01541 #ifdef NL_OS_WINDOWS
+01542 
+01543 
+01544 // ***************************************************************************
+01545 inline  void    NL3D_asmModulateLineColors(CRGBA *dst, const CRGBA *src0, const CRGBA *src1, 
+01546         uint len, uint  src0DeltaX, uint dstDeltaX)
+01547 {
+01548         static  uint64  blank= 0;
+01549         if(len==0)
+01550                 return;
+01551 
+01552         __asm
+01553         {
+01554                 movq            mm7, blank
+01555 
+01556                 mov                     esi, src0       // esi point to src Pixels
+01557                 mov                     edx, src1       // edx point to src lighting pixels
+01558                 mov                     edi, dst
+01559                 mov                     ecx, len
+01560                 // compute increments for esi and edi
+01561                 mov                     eax, src0DeltaX
+01562                 mov                     ebx, dstDeltaX
+01563                 sal                     eax, 2
+01564                 sal                     ebx, 2
+01565 
+01566         myLoop:
+01567                 // read colors
+01568                 movd            mm0, [esi]
+01569                 movd            mm1, [edx]
+01570 
+01571                 // mul mm0 and mm1
+01572                 punpcklbw       mm0, mm7
+01573                 punpcklbw       mm1, mm7
+01574                 pmullw          mm0, mm1
+01575                 psrlw       mm0, 8
+01576                 // pack
+01577                 packuswb    mm0, mm0
+01578 
+01579                 // out
+01580                 movd            [edi], mm0
+01581 
+01582                 // increment
+01583                 add                     esi, eax
+01584                 add                     edi, ebx
+01585                 add                     edx, 4
+01586                 dec                     ecx
+01587                 jnz                     myLoop
+01588         }
+01589 }
+01590 
+01591 
+01592 // ***************************************************************************
+01593 inline  void    NL3D_asmModulateAndBlendLineColors(CRGBA *dst, const CRGBA *src0, const CRGBA *src1, 
+01594         uint len, uint  src0DeltaX, uint dstDeltaX)
+01595 {
+01596         static  uint64  blank= 0;
+01597         static  uint64  one= 0x0100010001000100;
+01598         if(len==0)
+01599                 return;
+01600 
+01601         __asm
+01602         {
+01603                 movq            mm7, blank
+01604                 movq            mm6, one
+01605 
+01606                 mov                     esi, src0       // esi point to src Pixels
+01607                 mov                     edx, src1       // edx point to src lighting pixels
+01608                 mov                     edi, dst
+01609                 mov                     ecx, len
+01610                 // compute increments for esi and edi
+01611                 mov                     eax, src0DeltaX
+01612                 mov                     ebx, dstDeltaX
+01613                 sal                     eax, 2
+01614                 sal                     ebx, 2
+01615 
+01616         myLoop:
+01617                 // read colors
+01618                 movd            mm0, [esi]
+01619                 movd            mm1, [edx]
+01620 
+01621                 // save and unpack Alpha. NB: ABGR
+01622                 movq            mm2, mm0
+01623                 psrld           mm2, 24         // mm2= 0000 0000 0000 00AA
+01624                 punpckldq       mm2, mm2        // mm2= 0000 00AA 0000 00AA
+01625                 packssdw        mm2, mm2        // mm2= 00AA 00AA 00AA 00AA
+01626                 // negate with 256.
+01627                 movq            mm3, mm6
+01628                 psubusw         mm3, mm2
+01629 
+01630                 // mul mm0 and mm1
+01631                 punpcklbw       mm0, mm7
+01632                 punpcklbw       mm1, mm7
+01633                 pmullw          mm0, mm1
+01634                 psrlw       mm0, 8
+01635 
+01636                 // Alpha Blend with mm3 and mm2
+01637                 movd            mm1, [edi]      // read dest
+01638                 punpcklbw       mm1, mm7
+01639                 pmullw          mm0, mm2        // mm0= srcColor*A
+01640                 pmullw          mm1, mm3        // mm1= dstColor*(1-A)
+01641 
+01642                 // add and pack
+01643                 paddusw         mm0, mm1
+01644                 psrlw       mm0, 8
+01645                 packuswb    mm0, mm0
+01646 
+01647                 // out
+01648                 movd            [edi], mm0
+01649 
+01650                 // increment
+01651                 add                     esi, eax
+01652                 add                     edi, ebx
+01653                 add                     edx, 4
+01654                 dec                     ecx
+01655                 jnz                     myLoop
+01656         }
+01657 }
+01658 
+01659 
+01660 #else // NL_OS_WINDOWS
+01661 
+01662 // Dummy for non-windows platforms
+01663 inline  void    NL3D_asmModulateLineColors(CRGBA *dst, const CRGBA *src0, const CRGBA *src1, 
+01664         uint len, uint  src0DeltaX, uint dstDeltaX)
+01665 {
+01666 }
+01667 inline  void    NL3D_asmModulateAndBlendLineColors(CRGBA *dst, const CRGBA *src0, const CRGBA *src1, 
+01668         uint len, uint  src0DeltaX, uint dstDeltaX)
+01669 {
+01670 }
+01671 
+01672 #endif
+01673 
+01674 // ***************************************************************************
+01675 void NL3D_drawFarTileInFarTexture (const NL3D_CComputeTileFar* pTileFar)
+01676 {
+01677         // Pointer of the Src diffuse pixels
+01678         const CRGBA* pSrcPixels=pTileFar->SrcDiffusePixels;
+01679 
+01680         // Pointer of the Dst pixels
+01681         const CRGBA* pSrcLightPixels=pTileFar->SrcLightingPixels;
+01682 
+01683         // Pointer of the Dst pixels
+01684         CRGBA* pDstPixels=pTileFar->DstPixels;
+01685 
+01686         // For each pixels
+01687         int x, y;
+01688         for (y=0; y<pTileFar->Size; y++)
+01689         {
+01690                 // MMX implementation
+01691                 //---------
+01692                 if(pTileFar->AsmMMX)
+01693                 {
+01694                         NL3D_asmModulateLineColors(pDstPixels, pSrcPixels, pSrcLightPixels, 
+01695                                 pTileFar->Size, pTileFar->SrcDeltaX, pTileFar->DstDeltaX);
+01696                 }
+01697                 // C Implementation.
+01698                 //---------
+01699                 else
+01700                 {
+01701                         // Pointer of the source line
+01702                         const CRGBA* pSrcLine=pSrcPixels;
+01703 
+01704                         // Pointer of the source lighting line
+01705                         const CRGBA* pSrcLightingLine=pSrcLightPixels;
+01706                         
+01707                         // Pointer of the destination line
+01708                         CRGBA* pDstLine=pDstPixels;
+01709 
+01710                         // For each pixels on the line
+01711                         for (x=0; x<pTileFar->Size; x++)
+01712                         {
+01713                                 // Read and write a pixel
+01714                                 pDstLine->R=(uint8)(((uint)pSrcLine->R*(uint)pSrcLightingLine->R)>>8);
+01715                                 pDstLine->G=(uint8)(((uint)pSrcLine->G*(uint)pSrcLightingLine->G)>>8);
+01716                                 pDstLine->B=(uint8)(((uint)pSrcLine->B*(uint)pSrcLightingLine->B)>>8);
+01717 
+01718                                 // Next pixel
+01719                                 pSrcLine+=pTileFar->SrcDeltaX;
+01720                                 pSrcLightingLine++;
+01721                                 pDstLine+=pTileFar->DstDeltaX;
+01722                         }
+01723                 }
+01724 
+01725                 // Next line
+01726                 pSrcPixels+=pTileFar->SrcDeltaY;
+01727                 pSrcLightPixels+=pTileFar->SrcLightingDeltaY;
+01728                 pDstPixels+=pTileFar->DstDeltaY;
+01729         }
+01730 
+01731         // stop MMX if used
+01732         if(pTileFar->AsmMMX)
+01733                 NL3D_asmEndMMX();
+01734 }
+01735 
+01736 
+01737 // ***************************************************************************
+01738 void NL3D_drawFarTileInFarTextureAlpha (const NL3D_CComputeTileFar* pTileFar)
+01739 {
+01740         // Pointer of the Src pixels
+01741         const CRGBA* pSrcPixels=pTileFar->SrcDiffusePixels;
+01742 
+01743         // Pointer of the Dst pixels
+01744         const CRGBA* pSrcLightPixels=pTileFar->SrcLightingPixels;
+01745 
+01746         // Pointer of the Dst pixels
+01747         CRGBA* pDstPixels=pTileFar->DstPixels;
+01748 
+01749         // Fill the buffer with layer 0
+01750         int x, y;
+01751         for (y=0; y<pTileFar->Size; y++)
+01752         {
+01753                 // MMX implementation
+01754                 //---------
+01755                 if(pTileFar->AsmMMX)
+01756                 {
+01757                         NL3D_asmModulateAndBlendLineColors(pDstPixels, pSrcPixels, pSrcLightPixels, 
+01758                                 pTileFar->Size, pTileFar->SrcDeltaX, pTileFar->DstDeltaX);
+01759                 }
+01760                 // C Implementation.
+01761                 //---------
+01762                 else
+01763                 {
+01764                         // Pointer of the source line
+01765                         const CRGBA* pSrcLine=pSrcPixels;
+01766 
+01767                         // Pointer of the source lighting line
+01768                         const CRGBA* pSrcLightingLine=pSrcLightPixels;
+01769 
+01770                         // Pointer of the Dst pixels
+01771                         CRGBA* pDstLine=pDstPixels;
+01772 
+01773                         // For each pixels on the line
+01774                         for (x=0; x<pTileFar->Size; x++)
+01775                         {
+01776                                 // Read and write a pixel
+01777                                 register uint alpha=pSrcLine->A;
+01778                                 register uint oneLessAlpha=255-pSrcLine->A;
+01779                                 pDstLine->R=(uint8)(((((uint)pSrcLine->R*(uint)pSrcLightingLine->R)>>8)*alpha+(uint)pDstLine->R*oneLessAlpha)>>8);
+01780                                 pDstLine->G=(uint8)(((((uint)pSrcLine->G*(uint)pSrcLightingLine->G)>>8)*alpha+(uint)pDstLine->G*oneLessAlpha)>>8);
+01781                                 pDstLine->B=(uint8)(((((uint)pSrcLine->B*(uint)pSrcLightingLine->B)>>8)*alpha+(uint)pDstLine->B*oneLessAlpha)>>8);
+01782 
+01783                                 // Next pixel
+01784                                 pSrcLine+=pTileFar->SrcDeltaX;
+01785                                 pSrcLightingLine++;
+01786                                 pDstLine+=pTileFar->DstDeltaX;
+01787                         }
+01788                 }
+01789 
+01790                 // Next line
+01791                 pSrcPixels+=pTileFar->SrcDeltaY;
+01792                 pSrcLightPixels+=pTileFar->SrcLightingDeltaY;
+01793                 pDstPixels+=pTileFar->DstDeltaY;
+01794         }
+01795 
+01796         // stop MMX if used
+01797         if(pTileFar->AsmMMX)
+01798                 NL3D_asmEndMMX();
+01799 }
+01800 
+01801 
+01802 // ***************************************************************************
+01803 // TODO: asm implementation of this function \\//
+01804 //#ifdef NL_NO_ASM
+01805 void NL3D_drawFarTileInFarTextureAdditive (const NL3D_CComputeTileFar* pTileFar)
+01806 {
+01807         // Pointer of the Src diffuse pixels
+01808         const CRGBA* pSrcPixels=pTileFar->SrcDiffusePixels;
+01809 
+01810         // Pointer of the Src additive pixels
+01811         const CRGBA* pSrcAddPixels=pTileFar->SrcAdditivePixels;
+01812 
+01813         // Pointer of the Dst pixels
+01814         const CRGBA* pSrcLightPixels=pTileFar->SrcLightingPixels;
+01815 
+01816         // Pointer of the Dst pixels
+01817         CRGBA* pDstPixels=pTileFar->DstPixels;
+01818 
+01819         // For each pixels
+01820         int x, y;
+01821         for (y=0; y<pTileFar->Size; y++)
+01822         {
+01823                 // Pointer of the source line
+01824                 const CRGBA* pSrcLine=pSrcPixels;
+01825 
+01826                 // Pointer of the source line
+01827                 const CRGBA* pSrcAddLine=pSrcAddPixels;
+01828 
+01829                 // Pointer of the source lighting line
+01830                 const CRGBA* pSrcLightingLine=pSrcLightPixels;
+01831 
+01832                 // Pointer of the destination line
+01833                 CRGBA* pDstLine=pDstPixels;
+01834 
+01835                 // For each pixels on the line
+01836                 for (x=0; x<pTileFar->Size; x++)
+01837                 {
+01838                         // Read and write a pixel
+01839                         uint nTmp=(((uint)pSrcLine->R*(uint)pSrcLightingLine->R)>>8)+(uint)pSrcAddLine->R;
+01840                         if (nTmp>255)
+01841                                 nTmp=255;
+01842                         pDstLine->R=(uint8)nTmp;
+01843                         nTmp=(((uint)pSrcLine->G*(uint)pSrcLightingLine->G)>>8)+(uint)pSrcAddLine->G;
+01844                         if (nTmp>255)
+01845                                 nTmp=255;
+01846                         pDstLine->G=(uint8)nTmp;
+01847                         nTmp=(((uint)pSrcLine->B*(uint)pSrcLightingLine->B)>>8)+(uint)pSrcAddLine->B;
+01848                         if (nTmp>255)
+01849                                 nTmp=255;
+01850                         pDstLine->B=(uint8)nTmp;
+01851 
+01852                         // Next pixel
+01853                         pSrcLine+=pTileFar->SrcDeltaX;
+01854                         pSrcAddLine+=pTileFar->SrcDeltaX;
+01855                         pSrcLightingLine++;
+01856                         pDstLine+=pTileFar->DstDeltaX;
+01857                 }
+01858 
+01859                 // Next line
+01860                 pSrcPixels+=pTileFar->SrcDeltaY;
+01861                 pSrcAddPixels+=pTileFar->SrcDeltaY;
+01862                 pSrcLightPixels+=pTileFar->SrcLightingDeltaY;
+01863                 pDstPixels+=pTileFar->DstDeltaY;
+01864         }
+01865 }
+01866 //#endif // NL_NO_ASM
+01867 
+01868 
+01869 // ***************************************************************************
+01870 // TODO: asm implementation of this function \\//
+01871 //#ifdef NL_NO_ASM
+01872 void NL3D_drawFarTileInFarTextureAdditiveAlpha (const NL3D_CComputeTileFar* pTileFar)
+01873 {
+01874         // Pointer of the Src pixels
+01875         const CRGBA* pSrcPixels=pTileFar->SrcDiffusePixels;
+01876 
+01877         // Pointer of the Src pixels
+01878         const CRGBA* pSrcAddPixels=pTileFar->SrcAdditivePixels;
+01879 
+01880         // Pointer of the Dst pixels
+01881         const CRGBA* pSrcLightPixels=pTileFar->SrcLightingPixels;
+01882 
+01883         // Pointer of the Dst pixels
+01884         CRGBA* pDstPixels=pTileFar->DstPixels;
+01885 
+01886         // Fill the buffer with layer 0
+01887         int x, y;
+01888         for (y=0; y<pTileFar->Size; y++)
+01889         {
+01890                 // Pointer of the source line
+01891                 const CRGBA* pSrcLine=pSrcPixels;
+01892 
+01893                 // Pointer of the source line
+01894                 const CRGBA* pSrcAddLine=pSrcAddPixels;
+01895 
+01896                 // Pointer of the source lighting line
+01897                 const CRGBA* pSrcLightingLine=pSrcLightPixels;
+01898 
+01899                 // Pointer of the Dst pixels
+01900                 CRGBA* pDstLine=pDstPixels;
+01901 
+01902                 // For each pixels on the line
+01903                 for (x=0; x<pTileFar->Size; x++)
+01904                 {
+01905                         // Read and write a pixel
+01906                         register uint alpha=pSrcLine->A;
+01907                         register uint oneLessAlpha=255-pSrcLine->A;
+01908                         
+01909                         // Read and write a pixel
+01910                         uint nTmp=(((uint)pSrcLine->R*(uint)pSrcLightingLine->R)>>8)+(uint)pSrcAddLine->R;
+01911                         if (nTmp>255)
+01912                                 nTmp=255;
+01913                         pDstLine->R=(uint8)((nTmp*alpha+pDstLine->R*oneLessAlpha)>>8);
+01914                         nTmp=(((uint)pSrcLine->G*(uint)pSrcLightingLine->G)>>8)+(uint)pSrcAddLine->G;
+01915                         if (nTmp>255)
+01916                                 nTmp=255;
+01917                         pDstLine->G=(uint8)((nTmp*alpha+pDstLine->G*oneLessAlpha)>>8);
+01918                         nTmp=(((uint)pSrcLine->B*(uint)pSrcLightingLine->B)>>8)+(uint)pSrcAddLine->B;
+01919                         if (nTmp>255)
+01920                                 nTmp=255;
+01921                         pDstLine->B=(uint8)((nTmp*alpha+pDstLine->B*oneLessAlpha)>>8);
+01922 
+01923                         // Next pixel
+01924                         pSrcLine+=pTileFar->SrcDeltaX;
+01925                         pSrcAddLine+=pTileFar->SrcDeltaX;
+01926                         pSrcLightingLine++;
+01927                         pDstLine+=pTileFar->DstDeltaX;
+01928                 }
+01929 
+01930                 // Next line
+01931                 pSrcPixels+=pTileFar->SrcDeltaY;
+01932                 pSrcAddPixels+=pTileFar->SrcDeltaY;
+01933                 pSrcLightPixels+=pTileFar->SrcLightingDeltaY;
+01934                 pDstPixels+=pTileFar->DstDeltaY;
+01935         }
+01936 }
+01937 //#endif // NL_NO_ASM
+
+ + +
                                                                                                                                                                    +
+ + -- cgit v1.2.1