blitter.h

Go to the documentation of this file.
00001 /*
00002     This file is part of Advanced Strategic Command; http://www.asc-hq.de
00003     Copyright (C) 1994-2010  Martin Bickel  and  Marc Schellenberger
00004  
00005     This program is free software; you can redistribute it and/or modify
00006     it under the terms of the GNU General Public License as published by
00007     the Free Software Foundation; either version 2 of the License, or
00008     (at your option) any later version.
00009  
00010     This program is distributed in the hope that it will be useful,
00011     but WITHOUT ANY WARRANTY; without even the implied warranty of
00012     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013     GNU General Public License for more details.
00014  
00015     You should have received a copy of the GNU General Public License
00016     along with this program; see the file COPYING. If not, write to the
00017     Free Software Foundation, Inc., 59 Temple Place, Suite 330,
00018     Boston, MA  02111-1307  USA
00019 */
00020 
00021 #ifndef blitterH
00022  #define blitterH
00023 
00024 #include <cmath>
00025  #include <map>
00026  #include "loki/static_check.h"
00027  #include "../libs/sdlmm/src/sdlmm.h"
00028  #include "surface.h"
00029 
00030 #include "../misc.h"
00031  #include "../palette.h"
00032  #include "../basegfx.h"
00033 
00034 typedef SDLmm::Color Color;
00035 
00036 class NullParamType
00037    {}
00038 ;
00039 extern NullParamType nullParam;
00040 
00041 
00042 template<int BytesPerPixel>
00043 class PixelSize2Type;
00044 
00045 template<>
00046 class PixelSize2Type<1>
00047 {
00048    public:
00049       typedef Uint8  PixelType;
00050 };
00051 template<>
00052 class PixelSize2Type<2>
00053 {
00054    public:
00055       typedef Uint16 PixelType;
00056 };
00057 template<>
00058 class PixelSize2Type<4>
00059 {
00060    public:
00061       typedef Uint32 PixelType;
00062 };
00063 
00064 
00065 
00066 class TargetPixelSelector_All
00067 {
00068    protected:
00069       int skipTarget( int x, int y )
00070       {
00071          return 0;
00072       };
00073       void init( const Surface& srv, const SPoint& pos, int xrange, int yrange )
00074       {}
00075       ;
00076    public:
00077       TargetPixelSelector_All ( NullParamType npt = nullParam )
00078       {}
00079       ;
00080 };
00081 
00082 class TargetPixelSelector_Valid
00083 {
00084       int w,h;
00085       int xrange;
00086       SPoint dstPos;
00087    protected:
00088       int skipTarget( int x, int y )
00089       {
00090          x += dstPos.x;
00091          y += dstPos.y;
00092 
00093          if ( x >= 0 && y >= 0 && x < w && y < h )
00094             return 0;
00095          else
00096             if ( x < 0 )
00097                return -x;
00098             else
00099                return xrange - x + dstPos.x;
00100       };
00101       void init( const Surface& srv, const SPoint& pos, int xrange, int yrange )
00102       {
00103          w = srv.w();
00104          h = srv.h();
00105          dstPos = pos;
00106          this->xrange = xrange;
00107       };
00108    public:
00109       TargetPixelSelector_Valid ( NullParamType npt = nullParam ) :w(0xffffff),h(0xffffff),xrange(1)
00110       {}
00111       ;
00112 };
00113 
00114 
00115 
00116 
00117 
00118 
00119 
00120 template<int pixelsize>
00121 class SourcePixelSelector_Plain
00122 {
00123       typedef typename PixelSize2Type<pixelsize>::PixelType PixelType;
00124       const PixelType* pointer;
00125       int pitch;
00126       int linelength;
00127       const Surface* surface;
00128    protected:
00129       SourcePixelSelector_Plain() : pointer(NULL), surface(NULL)
00130       {}
00131       ;
00132 
00133       void init ( const Surface& srv )
00134       {
00135          surface = &srv;
00136          pointer = (const PixelType*)(srv.pixels());
00137          linelength = srv.pitch()/sizeof(PixelType);
00138          pitch = linelength - srv.w();
00139       };
00140 
00141       PixelType getPixel(int x, int y)
00142       {
00143          if ( x >= 0 && y >= 0 && x < surface->w() && y < surface->h() )
00144             return surface->GetPixel(SPoint(x,y));
00145          else
00146             return surface->GetPixelFormat().colorkey();
00147       };
00148 
00149       PixelType nextPixel()
00150       {
00151          return *(pointer++);
00152       };
00153       void nextLine()
00154       {
00155          pointer += pitch;
00156       };
00157       void skipPixels( int pixNum )
00158       {
00159          pointer += pixNum;
00160       };
00161 
00162       int getSourcePixelSkip()
00163       {
00164          return 0;
00165       };
00166       
00167       void skipWholeLine()
00168       {
00169          pointer += linelength;
00170       };
00171 
00172       int getWidth()
00173       {
00174          return surface->w();
00175       };
00176       int getHeight()
00177       {
00178          return surface->h();
00179       };
00180    public:
00181       SourcePixelSelector_Plain ( NullParamType npt )
00182       {}
00183       ;
00184 };
00185 
00186 
00187 template<
00188 int BytesPerSourcePixel,
00189 int BytesPerTargetPixel
00190 >
00191 class ColorConverter
00192 {
00193    public:
00194       typedef typename PixelSize2Type<BytesPerTargetPixel>::PixelType SourcePixelType;
00195       typedef typename PixelSize2Type<BytesPerTargetPixel>::PixelType TargetPixelType;
00196    private:
00197       SourcePixelType srcColorKey;
00198       TargetPixelType destColorKey;
00199    public:
00200       ColorConverter( const Surface& sourceSurface, Surface& targetSurface )
00201       {}
00202       ;
00203       TargetPixelType convert ( SourcePixelType sp )
00204       {
00205          return sp;
00206       };
00207 };
00208 
00209 
00210 template<>
00211 class ColorConverter<4,1>
00212 {
00213       int rshift, gshift, bshift;
00214    public:
00215       typedef  PixelSize2Type<4>::PixelType SourcePixelType;
00216       typedef  PixelSize2Type<1>::PixelType TargetPixelType;
00217    private:
00218       SourcePixelType srcColorKey;
00219       TargetPixelType destColorKey;
00220       bool srcHasColorKey;
00221       int srcColorMask;
00222    public:
00223 
00224       ColorConverter( const Surface& sourceSurface, Surface& targetSurface )
00225       {
00226          rshift = sourceSurface.GetPixelFormat().Rshift() + 2;
00227          gshift = sourceSurface.GetPixelFormat().Gshift() + 2;
00228          bshift = sourceSurface.GetPixelFormat().Bshift() + 2;
00229          srcColorMask = ~sourceSurface.GetPixelFormat().Amask();
00230          srcColorKey = sourceSurface.GetPixelFormat().colorkey() & srcColorMask;
00231 
00232          srcHasColorKey = sourceSurface.flags() & SDL_SRCCOLORKEY;
00233          if ( targetSurface.flags() & SDL_SRCCOLORKEY )
00234             destColorKey = targetSurface.GetPixelFormat().colorkey();
00235          else
00236             destColorKey = 0xff;
00237 
00238 
00239       };
00240       TargetPixelType convert ( SourcePixelType sp )
00241       {
00242          #ifdef use_truecolor2pal
00243          if ( srcHasColorKey && (sp & srcColorMask) == srcColorKey )
00244             return destColorKey;
00245          else
00246             return truecolor2pal_table[ ((sp >> rshift) & 0x3f) + (((sp >> gshift) & 0x3f) << 6) + (((sp >> bshift) & 0x3f) << 12)];
00247          #else
00248          return destColorKey;
00249          #endif
00250       };
00251 };
00252 
00253 template<>
00254 class ColorConverter<1,4>
00255 {
00256    public:
00257       typedef  PixelSize2Type<1>::PixelType SourcePixelType;
00258       typedef  PixelSize2Type<4>::PixelType TargetPixelType;
00259    private:
00260       SDL_Color* palette;
00261       int rshift, gshift, bshift,ashift;
00262       bool hasColorKey;
00263       TargetPixelType colorKey;
00264    public:
00265 
00266       ColorConverter( const Surface& sourceSurface, Surface& targetSurface )
00267       {
00268          if ( targetSurface.flags() & SDL_SRCCOLORKEY ) {
00269             hasColorKey = true;
00270             colorKey = targetSurface.GetPixelFormat().colorkey();
00271          } else {
00272             hasColorKey = false;
00273             colorKey = 0;
00274          }
00275 
00276          palette = sourceSurface.GetPixelFormat().palette()->colors;
00277          rshift = targetSurface.GetPixelFormat().Rshift();
00278          gshift = targetSurface.GetPixelFormat().Gshift();
00279          bshift = targetSurface.GetPixelFormat().Bshift();
00280          if ( targetSurface.GetPixelFormat().Amask() )
00281             ashift = targetSurface.GetPixelFormat().Ashift();
00282          else
00283             ashift = getFirstBit( ~( targetSurface.GetPixelFormat().Rmask() | targetSurface.GetPixelFormat().Gmask() | targetSurface.GetPixelFormat().Bmask()));
00284 
00285       };
00286 
00287       TargetPixelType convert ( SourcePixelType sp )
00288       {
00289          if ( sp == 0xff ) {
00290             if ( hasColorKey )
00291                return colorKey;
00292             else
00293                return Surface::transparent << ashift;
00294          } else {
00295             TargetPixelType a = Surface::opaque;
00296             a <<= ashift;
00297             return TargetPixelType(palette[sp].r << rshift) + TargetPixelType(palette[sp].g << gshift) + TargetPixelType(palette[sp].b << bshift) + a;
00298          }
00299       };
00300 
00301 };
00302 
00303 
00304 
00305 template<
00306 int BytesPerSourcePixel,
00307 int BytesPerTargetPixel,
00308 template<int> class SourceColorTransform, // = ColorTransform_None,
00309 template<int> class ColorMerger, // = ColorMerger_PlainOverwrite,
00310 template<int> class SourcePixelSelector = SourcePixelSelector_Plain,
00311 class TargetPixelSelector = TargetPixelSelector_All,
00312 template<int,int> class MyColorConverter = ColorConverter
00313 >
00314 class MegaBlitter : public SourceColorTransform<BytesPerSourcePixel>,
00315          public ColorMerger<BytesPerTargetPixel>,
00316          public SourcePixelSelector<BytesPerSourcePixel>,
00317          public TargetPixelSelector
00318 {
00319       typedef typename PixelSize2Type<BytesPerSourcePixel>::PixelType SourcePixelType;
00320       typedef typename PixelSize2Type<BytesPerTargetPixel>::PixelType TargetPixelType;
00321    public:
00322       MegaBlitter()
00323       { }
00324       ;
00325       MegaBlitter( const SourceColorTransform<BytesPerSourcePixel>& scm, const ColorMerger<BytesPerTargetPixel>& cm, const SourcePixelSelector<BytesPerSourcePixel>& sps, const TargetPixelSelector& tps ) :
00326             SourceColorTransform<BytesPerSourcePixel>( scm ),
00327             ColorMerger<BytesPerTargetPixel>( cm ),
00328             SourcePixelSelector<BytesPerSourcePixel>( sps ),
00329             TargetPixelSelector( tps )
00330       { }
00331       ;
00332 
00333       int getWidth()
00334       {
00335          return SourcePixelSelector<BytesPerTargetPixel>::getWidth();
00336       };
00337       int getHeight()
00338       {
00339          return SourcePixelSelector<BytesPerTargetPixel>::getHeight();
00340       };
00341 
00342       void initSource( const Surface& src )
00343       {
00344          SourcePixelSelector<BytesPerSourcePixel>::init( src );
00345       }
00346 
00347 
00348       void blit( const Surface& src, Surface& dst, SPoint dstPos )
00349       {
00350          assert( src.GetPixelFormat().BytesPerPixel() == BytesPerSourcePixel );
00351          assert( dst.GetPixelFormat().BytesPerPixel() == BytesPerTargetPixel );
00352 
00353          SurfaceLock sl( dst );
00354 
00355          ColorMerger<BytesPerTargetPixel>::init( BytesPerSourcePixel == BytesPerTargetPixel ? src : dst );
00356          SourcePixelSelector<BytesPerSourcePixel>::init( src );
00357 
00358          MyColorConverter<BytesPerSourcePixel,BytesPerTargetPixel> colorConverter( src, dst );
00359 
00360          SourceColorTransform<BytesPerSourcePixel>::init( src );
00361 
00362          int h = SourcePixelSelector<BytesPerSourcePixel>::getHeight();
00363          int w = SourcePixelSelector<BytesPerSourcePixel>::getWidth();
00364 
00365          TargetPixelSelector::init( dst, dstPos, w, h );
00366          
00367          TargetPixelType* pix = (TargetPixelType*)( dst.pixels() );
00368 
00369          pix += dstPos.y * dst.pitch()/BytesPerTargetPixel + dstPos.x;
00370 
00371          int pitch = dst.pitch()/BytesPerTargetPixel - w;
00372 
00373          typedef SourcePixelSelector<BytesPerTargetPixel> SPS;
00374          for ( int y = 0; y < h; ++y ) {
00375             for ( int x = 0; x < w; ++x ) {
00376                int s = TargetPixelSelector::skipTarget(x,y);
00377                if ( s >= 0 && SourcePixelSelector<BytesPerSourcePixel>::getSourcePixelSkip() > s )
00378                   s = SourcePixelSelector<BytesPerSourcePixel>::getSourcePixelSkip();
00379                
00380                if ( s==0 ) {
00381                   ColorMerger<BytesPerTargetPixel>::assign ( colorConverter.convert( SourceColorTransform<BytesPerSourcePixel>::transform( SourcePixelSelector<BytesPerSourcePixel>::nextPixel())), pix );
00382                   ++pix;
00383                } else {
00384                   if ( s > 0 ) {
00385                      SourcePixelSelector<BytesPerSourcePixel>::skipPixels( s );
00386                      pix += s;
00387                      x += s - 1 ;
00388                   } else
00389                      return;
00390                }
00391             }
00392             SourcePixelSelector<BytesPerSourcePixel>::nextLine();
00393             pix += pitch;
00394          }
00395       };
00396 
00397 };
00398 
00399 
00400 template<
00401 template<int> class SourceColorTransform,
00402 template<int> class ColorMerger,
00403 template<int> class SourcePixelSelector,
00404 class TargetPixelSelector,
00405 typename SourceColorTransformParameter,
00406 typename ColorMergerParameter,
00407 typename SourcePixelSelectorParameter,
00408 typename TargetPixelSelectorParameter
00409 >
00410 void megaBlitter  ( const Surface& src,
00411                     Surface& dst,
00412                     const SPoint& pos,
00413                     const SourceColorTransformParameter& scmp = nullParam,
00414                     const ColorMergerParameter& cmp  = nullParam,
00415                     const SourcePixelSelectorParameter spsp  = nullParam,
00416                     const TargetPixelSelectorParameter tpsp  = nullParam )
00417 {
00418    switch ( src.GetPixelFormat().BytesPerPixel() ) {
00419       case 1: {
00420             switch ( dst.GetPixelFormat().BytesPerPixel() ) {
00421                case 1: {
00422                      MegaBlitter<
00423                      1,1,
00424                      SourceColorTransform,
00425                      ColorMerger,
00426                      SourcePixelSelector,
00427                      TargetPixelSelector
00428                      >  blitter (
00429                         (SourceColorTransform<1>)( scmp ),
00430                         (ColorMerger<1>)( cmp ),
00431                         (SourcePixelSelector<1>)( spsp ),
00432                         TargetPixelSelector(tpsp)
00433                      );
00434                      blitter.blit( src, dst, pos );
00435                   }
00436                   break;
00437                case 3:
00438                case 4: {
00439                      MegaBlitter<
00440                      1,4,
00441                      SourceColorTransform,
00442                      ColorMerger,
00443                      SourcePixelSelector,
00444                      TargetPixelSelector
00445                      >  blitter (
00446                         (SourceColorTransform<1>)( scmp ),
00447                         (ColorMerger<4>)( cmp ),
00448                         (SourcePixelSelector<1>)( spsp ),
00449                         TargetPixelSelector(tpsp)
00450                      );
00451                      blitter.blit( src, dst, pos );
00452                   }
00453                   break;
00454             };
00455          }
00456          break;
00457       case 3:
00458       case 4:  {
00459             switch ( dst.GetPixelFormat().BytesPerPixel() ) {
00460                case 1: {
00461                      MegaBlitter<
00462                      4,1,
00463                      SourceColorTransform,
00464                      ColorMerger,
00465                      SourcePixelSelector,
00466                      TargetPixelSelector
00467                      >  blitter (
00468                         (SourceColorTransform<4>)( scmp ),
00469                         (ColorMerger<1>)( cmp ),
00470                         (SourcePixelSelector<4>)( spsp ),
00471                         TargetPixelSelector(tpsp)
00472                      );
00473                      blitter.blit( src, dst, pos );
00474                   }
00475                   break;
00476                case 3:
00477                case 4: {
00478                      MegaBlitter<
00479                      4,4,
00480                      SourceColorTransform,
00481                      ColorMerger,
00482                      SourcePixelSelector,
00483                      TargetPixelSelector
00484                      >  blitter (
00485                         (SourceColorTransform<4>)( scmp ),
00486                         (ColorMerger<4>)( cmp ),
00487                         (SourcePixelSelector<4>)( spsp ),
00488                         TargetPixelSelector(tpsp)
00489                      );
00490                      blitter.blit( src, dst, pos );
00491                   }
00492                   break;
00493             };
00494          }
00495          break;
00496    }
00497 }
00498 
00499 
00500 
00502 
00503 class Player;
00504 
00505 
00506 template<int pixelsize>
00507 class ColorTransform_None
00508 {
00509       typedef typename PixelSize2Type<pixelsize>::PixelType PixelType;
00510    protected:
00511       ColorTransform_None()
00512       {}
00513       ;
00514       PixelType transform( PixelType col)
00515       {
00516          return col;
00517       };
00518       void init( const Surface& src )
00519       {}
00520       ;
00521    public:
00522       ColorTransform_None ( NullParamType npt )
00523       {}
00524       ;
00525 };
00526 
00527 
00528 
00529 
00530 template<int pixelSize>
00531 class ColorTransform_XLAT
00532 {
00533       const char* table;
00534 
00535    protected:
00536       ColorTransform_XLAT() : table(NULL)
00537       {}
00538       ;
00539 
00540       void init( const Surface& src )
00541       {}
00542       ;
00543 
00544       Color transform( Color col)
00545       {
00546          if ( table )
00547             return table[col];
00548          else
00549             return col;
00550       };
00551 
00552    public:
00553       void setTranslationTable( const char* translationTable )
00554       {
00555          table = translationTable;
00556       };
00557 
00558       ColorTransform_XLAT ( NullParamType npt ) : table(NULL)
00559       {}
00560       ;
00561 
00562       ColorTransform_XLAT ( const char* t ) : table ( t )
00563       {}
00564       ;
00565 };
00566 
00567 
00568 template<int pixelSize>
00569 class ColorTransform_Gray
00570    { }
00571 ;
00572 
00573 
00574 template<>
00575 class ColorTransform_Gray<4>
00576 {
00577    protected:
00578       ColorTransform_Gray()
00579       {}
00580       ;
00581 
00582       Color transform( Color col)
00583       {
00584          int i = ((col & 0xff) + ((col >> 8) & 0xff) + ((col >> 16) & 0xff)) / 3;
00585          return i + (i<<8) + (i <<16) + (col & 0xff000000);
00586       };
00587 
00588       void init( const Surface& src )
00589       {}
00590       ;
00591 
00592    public:
00593       ColorTransform_Gray ( NullParamType npt )
00594       {}
00595       ;
00596 };
00597 
00598 
00600 
00601 template<int pixelsize>
00602 class ColorMerger_PlainOverwrite
00603 {
00604       typedef typename PixelSize2Type<pixelsize>::PixelType PixelType;
00605    protected:
00606       ColorMerger_PlainOverwrite()
00607       {}
00608       ;
00609       void init( const Surface& dst )
00610       {}
00611       ;
00612       void assign ( PixelType src, PixelType* dest )
00613       {
00614          *dest = src;
00615       };
00616    public:
00617       ColorMerger_PlainOverwrite ( NullParamType npt )
00618       {}
00619       ;
00620 };
00621 
00622 template<int pixelsize>
00623 class ColorMerger_ColoredOverwrite
00624 {
00625       typedef typename PixelSize2Type<pixelsize>::PixelType PixelType;
00626       DI_Color col;
00627       mutable PixelType transformedColor;
00628    public:
00629       void init( const Surface& dst ) const
00630       {
00631          transformedColor =  dst.GetPixelFormat().MapRGB( col );
00632       };
00633       void assign ( PixelType src, PixelType* dest ) const
00634       {
00635          *dest = src;
00636       };
00637       void assign ( PixelType* dest ) const
00638       {
00639          *dest = transformedColor;
00640       };
00641       ColorMerger_ColoredOverwrite ( DI_Color color ) : col(color)
00642       {}
00643       ;
00644 };
00645 
00646 
00647 template<int pixelsize>
00648 class ColorMerger_AlphaHandler
00649 {
00650       typedef typename PixelSize2Type<pixelsize>::PixelType PixelType;
00651       int colorKey;
00652       int mask;
00653    protected:
00654       ColorMerger_AlphaHandler() : mask ( -1 )
00655       {}
00656       ;
00657 
00658       void init( const Surface& srf )
00659       {
00660          if ( srf.flags() & SDL_SRCCOLORKEY ) {
00661             colorKey = srf.GetPixelFormat().colorkey();
00662             if ( pixelsize > 1 )
00663                mask = srf.GetPixelFormat().Rmask() | srf.GetPixelFormat().Gmask() | srf.GetPixelFormat().Bmask();
00664          } else
00665             if ( pixelsize == 1 )
00666                colorKey = 0xff;
00667             else
00668                colorKey = 0xfefefe00;
00669       };
00670 
00671       bool isOpaque( PixelType src )
00672       {
00673          return (src & mask ) != colorKey;
00674       }
00675 };
00676 
00677 
00678 template<>
00679 class ColorMerger_AlphaHandler<1>
00680 {
00681       typedef PixelSize2Type<1>::PixelType PixelType;
00682       int colorKey;
00683       int mask;
00684    protected:
00685       ColorMerger_AlphaHandler() : mask ( -1 )
00686       {}
00687       ;
00688 
00689       void init( const Surface& srf )
00690       {
00691          if ( srf.flags() & SDL_SRCCOLORKEY ) {
00692             colorKey = srf.GetPixelFormat().colorkey();
00693          } else
00694             colorKey = 0xff;
00695       };
00696 
00697       bool isOpaque( PixelType src )
00698       {
00699          return (src & mask ) != colorKey;
00700       }
00701 };
00702 
00703 template<>
00704 class ColorMerger_AlphaHandler<4>
00705 {
00706       typedef PixelSize2Type<4>::PixelType PixelType;
00707    protected:
00708       int amask, ashift;
00709       PixelType colorKey;
00710       bool hasColorKey;
00711       int ckmask;
00712    protected:
00713       ColorMerger_AlphaHandler() : amask ( -1 ), ashift(0), colorKey(0), hasColorKey(false), ckmask(0)
00714       {}
00715       ;
00716 
00717       void init( const Surface& srf )
00718       {
00719          if ( srf.flags() & SDL_SRCCOLORKEY ) {
00720             hasColorKey = true;
00721             colorKey = srf.GetPixelFormat().colorkey();
00722             ckmask = srf.GetPixelFormat().Rmask() | srf.GetPixelFormat().Gmask() | srf.GetPixelFormat().Bmask();
00723          } else {
00724             if ( srf.GetPixelFormat().Amask() ) {
00725                amask = srf.GetPixelFormat().Amask();
00726                ashift = srf.GetPixelFormat().Ashift();
00727             } else {
00728                amask = ~( srf.GetPixelFormat().Rmask() | srf.GetPixelFormat().Gmask() | srf.GetPixelFormat().Bmask() );
00729                ashift = getFirstBit(amask);
00730             }
00731          }
00732       };
00733 
00734       bool isOpaque( PixelType src )
00735       {
00736          if ( hasColorKey )
00737             return (src & ckmask) != colorKey;
00738          else
00739             return PixelType((src & amask ) >> ashift) >= 128;
00740       };
00741 };
00742 
00743 
00744 template<int pixelsize>
00745 class ColorMerger_AlphaOverwrite : public ColorMerger_AlphaHandler<pixelsize>
00746 {
00747       typedef typename PixelSize2Type<pixelsize>::PixelType PixelType;
00748    protected:
00749 
00750       void assign ( PixelType src, PixelType* dest )
00751       {
00752          if ( this->isOpaque(src ) ) {
00753             *dest = src;
00754          }
00755       };
00756 
00757    public:
00758       ColorMerger_AlphaOverwrite( NullParamType npt = nullParam )
00759       {}
00760       ;
00761 };
00762 
00763 
00764 template<int pixelsize>
00765 class ColorMerger_AlphaMerge : public ColorMerger_AlphaHandler<pixelsize>
00766 {
00767       typedef typename PixelSize2Type<pixelsize>::PixelType PixelType;
00768    protected:
00769 
00770       void assign ( PixelType src, PixelType* dest )
00771       {
00772          if ( this->isOpaque(src ) ) {
00773             *dest = src;
00774          }
00775       };
00776 
00777    public:
00778       ColorMerger_AlphaMerge( NullParamType npt = nullParam )
00779       {}
00780       ;
00781 };
00782 
00783 template<>
00784 class ColorMerger_AlphaMerge<4> : public ColorMerger_AlphaHandler<4>
00785 {
00786       typedef  PixelSize2Type<4>::PixelType PixelType;
00787    protected:
00788 
00789       void assign ( PixelType src, PixelType* dest )
00790       {
00791          if ( hasColorKey ) {
00792             if ( (src & ckmask) != colorKey )
00793                *dest = src;
00794          } else {
00795             PixelType alpha = PixelType((src & amask ) >> ashift);
00796             if ( alpha == PixelType(Surface::opaque) )
00797                *dest = src;
00798             else
00799                if ( alpha != PixelType(Surface::transparent)) {
00800                   // copied from SDL
00801 
00802                   /*
00803                    * take out the middle component (green), and process
00804                    * the other two in parallel. One multiply less.
00805                    */
00806                   PixelType d = *dest;
00807                   PixelType dalpha = d & 0xff000000;
00808                   if ( dalpha == Surface::transparent ) {
00809                      *dest = src;
00810                   } else {
00811                      PixelType s1 = src & 0xff00ff;
00812                      PixelType d1 = d & 0xff00ff;
00813                      d1 = (d1 + ((s1 - d1) * alpha >> 8)) & 0xff00ff;
00814                      src &= 0xff00;
00815                      d &= 0xff00;
00816                      d = (d + ((src - d) * alpha >> 8)) & 0xff00;
00817                      *dest = d1 | d | dalpha;
00818                   }
00819                }
00820 
00821          }
00822       };
00823 
00824    public:
00825       ColorMerger_AlphaMerge( NullParamType npt = nullParam )
00826       {}
00827       ;
00828 };
00829 
00830 
00831 
00832 
00833 template<int pixelsize>
00834 class ColorMerger_AlphaShadow
00835    {}
00836 ;
00837 
00838 
00839 template<>
00840 class ColorMerger_AlphaShadow<1> : public ColorMerger_AlphaHandler<1>
00841 {
00842       typedef PixelSize2Type<1>::PixelType PixelType;
00843       const char* table;
00844    protected:
00845 
00846       void assign ( PixelType src, PixelType* dest )
00847       {
00848          // STATIC_CHECK ( pixelsize == 1, wrong_pixel_size );
00849          if ( this->isOpaque(src ) ) {
00850             *dest = table[*dest];
00851          }
00852       };
00853    public:
00854       ColorMerger_AlphaShadow ( NullParamType npt = nullParam) : table ( xlattables.a.dark1 )
00855       {}
00856       ;
00857       ColorMerger_AlphaShadow ( const char* translationTable ) : table ( translationTable )
00858       {}
00859       ;
00860 };
00861 
00862 template<>
00863 class ColorMerger_AlphaShadow<4> : public ColorMerger_AlphaHandler<4>
00864 {
00865       typedef PixelSize2Type<4>::PixelType PixelType;
00866    protected:
00867 
00868       void init( const Surface& srf )
00869       {
00870          ColorMerger_AlphaHandler<4>::init(srf);
00871       };
00872 
00873 
00874       void assign ( PixelType src, PixelType* dest )
00875       {
00876          if ( this->isOpaque(src ) ) {
00877             *dest = ((*dest >> 1) & 0x7f7f7f7f) | (*dest & 0xff000000 );
00878          }
00879       };
00880    public:
00881       ColorMerger_AlphaShadow ( NullParamType npt = nullParam)
00882       {}
00883       ;
00884       ColorMerger_AlphaShadow ( const char* translationTable )
00885       {}
00886       ;
00887 };
00888 
00889 
00890 
00891 template<int pixelsize>
00892 class ColorMerger_AlphaMixer
00893    {}
00894 ;
00895 
00896 
00897 template<>
00898 class ColorMerger_AlphaMixer<1> : public ColorMerger_AlphaHandler<1>
00899 {
00900       typedef  PixelSize2Type<1>::PixelType PixelType;
00901    protected:
00902       void assign ( PixelType src, PixelType* dest )
00903       {
00904          if ( this->isOpaque(src ) )
00905             *dest = colormixbufchar[*dest + src*256 ];
00906       };
00907    public:
00908       ColorMerger_AlphaMixer ( NullParamType npt = nullParam )
00909    {}
00910       ;
00911 };
00912 
00913 template<>
00914 class ColorMerger_AlphaMixer<4> : public ColorMerger_AlphaHandler<4>
00915 {
00916       typedef  PixelSize2Type<4>::PixelType PixelType;
00917    protected:
00918       void assign ( PixelType src, PixelType* dest )
00919       {
00920          // STATIC_CHECK ( pixelsize == 1, wrong_pixel_size );
00921          if ( this->isOpaque(src ) ) {
00922             *dest = ((*dest >> 1) & 0x7f7f7f7f) + ((src >> 1) & 0x7f7f7f7f);
00923          }
00924       };
00925    public:
00926       ColorMerger_AlphaMixer ( NullParamType npt = nullParam )
00927       {}
00928       ;
00929 };
00930 
00931 
00932 
00933 extern const int ColorMerger_Alpha_XLAT_Table_shadings[8]; 
00934 
00935 template<int pixelsize>
00936 class ColorMerger_Alpha_XLAT_TableShifter : public ColorMerger_AlphaHandler<pixelsize>
00937 {
00938       typedef typename PixelSize2Type<pixelsize>::PixelType PixelType;
00939       const char* table;
00940    protected:
00941       void assign ( PixelType src, PixelType* dest )
00942       {
00943          if ( src == 0 || src >= 8 )
00944             return;
00945 
00946          *dest = lighten_Color( *dest, ColorMerger_Alpha_XLAT_Table_shadings[src] );
00947          /*
00948                      // STATIC_CHECK ( pixelsize == 1, wrong_pixel_size );
00949                      if ( isOpaque(src ) ) {
00950                         *dest = table[ *dest + src*256 ];
00951                      }
00952                      */
00953       };
00954 
00955    public:
00956       void setNeutralTranslationTable( const char* translationTable )
00957       {
00958          table = translationTable;
00959       };
00960 
00961       ColorMerger_Alpha_XLAT_TableShifter( NullParamType npt = nullParam ) : table ( NULL )
00962       {}
00963       ;
00964       ColorMerger_Alpha_XLAT_TableShifter ( const char* translationTable ) : table ( translationTable )
00965       {}
00966       ;
00967 };
00968 
00969 template<>
00970 class ColorMerger_Alpha_XLAT_TableShifter<1> : public ColorMerger_AlphaHandler<1>
00971 {
00972       typedef PixelSize2Type<1>::PixelType PixelType;
00973       const char* table;
00974    protected:
00975       void assign ( PixelType src, PixelType* dest )
00976       {
00977          // STATIC_CHECK ( pixelsize == 1, wrong_pixel_size );
00978          if ( this->isOpaque(src ) ) {
00979             *dest = table[ *dest + src*256 ];
00980          }
00981       };
00982 
00983    public:
00984       void setNeutralTranslationTable( const char* translationTable )
00985       {
00986          table = translationTable;
00987       };
00988 
00989       ColorMerger_Alpha_XLAT_TableShifter( NullParamType npt = nullParam ) : table ( NULL )
00990       {}
00991       ;
00992       ColorMerger_Alpha_XLAT_TableShifter ( const char* translationTable ) : table ( translationTable )
00993       {}
00994       ;
00995 };
00996 
00997 
00998 template<int pixelsize>
00999 class ColorMerger_Brightness
01000 {
01001       typedef typename PixelSize2Type<pixelsize>::PixelType PixelType;
01002       float b;
01003    public:
01004 
01005       void assign ( PixelType src, PixelType* dest ) const
01006       {
01007          PixelType d = 0;
01008          for ( int i = 0; i < 3; ++i)
01009             d |= min( max( int( float(((*dest) >> (i*8)) & 0xff) * b ), 0 ), 255) << (i*8);
01010          d |= (*dest & 0xff000000);
01011 
01012          *dest = d;
01013       };
01014 
01015       ColorMerger_Brightness( float brightness )
01016       {
01017          b = brightness;
01018       };
01019 };
01020 
01021 
01022 template<int pixelsize>
01023 class ColorMerger_Set
01024 {
01025       typedef typename PixelSize2Type<pixelsize>::PixelType PixelType;
01026       SDLmm::Color col;
01027    public:
01028 
01029       void assign ( PixelType src, PixelType* dest ) const
01030       {
01031          *dest = col;
01032       };
01033 
01034      
01035       ColorMerger_Set( SDLmm::Color color )
01036       {
01037          col = color;
01038       };
01039 };
01040 
01041 
01043 
01044 
01045 
01046 template<int pixelsize, class SourcePixelSelector = SourcePixelSelector_Plain<pixelsize> >
01047 class SourcePixelSelector_Rotation: public SourcePixelSelector
01048 {
01049       typedef typename PixelSize2Type<pixelsize>::PixelType PixelType;
01050       int degrees;
01051       int x,y;
01052       int w,h;
01053    protected:
01054 
01055       void init ( const Surface& srv )
01056       {
01057          SourcePixelSelector::init(srv);
01058          w = SourcePixelSelector::getWidth();
01059          h = SourcePixelSelector::getHeight();
01060       };
01061 
01062 
01063       PixelType getPixel(int x, int y)
01064       {
01065          SPoint newpos = ::getPixelRotationLocation( SPoint(x,y), w, h, degrees );
01066          return SourcePixelSelector::getPixel ( newpos.x, newpos.y );
01067       };
01068 
01069       PixelType nextPixel()
01070       {
01071          return getPixel(x++, y);
01072       };
01073 
01074       void skipPixels( int pixNum )
01075       {
01076          x += pixNum;
01077       };
01078 
01079       int getSourcePixelSkip()
01080       {
01081          return 0;
01082       };
01083 
01084       void nextLine()
01085       {
01086          x = 0;
01087          y +=1;
01088       };
01089 
01090    public:
01091       void setAngle( int degrees )
01092       {
01093          this->degrees = degrees;
01094       };
01095 
01096       SourcePixelSelector_Rotation( NullParamType npt = nullParam )  : degrees(0),x(0),y(0),w(0),h(0)
01097       {}
01098 
01099       SourcePixelSelector_Rotation( int degreesToRotate )  : degrees(degreesToRotate),x(0),y(0),w(0),h(0)
01100       {}
01101 };
01102 
01103 template<int pixelsize>
01104 class SourcePixelSelector_DirectRotation: public SourcePixelSelector_Rotation<pixelsize>
01105 {
01106    public:
01107       SourcePixelSelector_DirectRotation( NullParamType npt = nullParam )
01108       {}
01109       SourcePixelSelector_DirectRotation( int degreesToRotate )  : SourcePixelSelector_Rotation<pixelsize>(degreesToRotate)
01110       {}
01111 }
01112 ;
01113 
01114 
01115 
01116 class RotationCache
01117 {
01118    protected:
01119       static map<int,int*> cache;
01120       static int xsize;
01121       static int ysize;
01122 };
01123 
01124 template<int pixelsize>
01125 class SourcePixelSelector_CacheRotation : public RotationCache
01126 {
01127       typedef typename PixelSize2Type<pixelsize>::PixelType PixelType;
01128       const Surface* surface;
01129       int degrees;
01130       bool useCache;
01131       const PixelType* pixelStart;
01132       const PixelType* currentPixel;
01133       int tableIndex;
01134       int pitch;
01135       int* cacheIndex;
01136       int x,y,w,h;
01137    protected:
01138 
01139       void init ( const Surface& srv )
01140       {
01141          if ( !surface ) {
01142             surface = &srv;
01143          } else {
01144             assert ( surface == &srv );
01145          }
01146          tableIndex = 0;
01147          pixelStart = currentPixel = (PixelType*)surface->pixels();
01148          pitch = srv.pitch()/sizeof(PixelType) - srv.w();
01149          w = srv.w();
01150          h = srv.h();
01151       }
01152 
01153       PixelType nextPixel()
01154       {
01155          if ( useCache && degrees != 0 ) {
01156             ++currentPixel;
01157 
01158             assert ( cacheIndex );
01159             int index = cacheIndex[tableIndex++];
01160             if ( index >= 0 )
01161                return pixelStart[index];
01162             else
01163                return surface->GetPixelFormat().colorkey();
01164          } else {
01165             if ( degrees == 0 ) {
01166                ++tableIndex;
01167                return *(currentPixel++);
01168             } else {
01169                SPoint newpos = ::getPixelRotationLocation( SPoint(x++,y), w, h, degrees );
01170                return getSourcePixel ( newpos.x, newpos.y );
01171             }
01172          }
01173       };
01174 
01175       void skipPixels( int pixNum )
01176       {
01177          currentPixel += pixNum;
01178          tableIndex += pixNum;
01179          x += pixNum;
01180       };
01181 
01182       int getSourcePixelSkip()
01183       {
01184          return 0;
01185       };
01186 
01187       void nextLine()
01188       {
01189          currentPixel += pitch;
01190          ++y;
01191          x = 0;
01192       };
01193 
01194       int getWidth()
01195       {
01196          return surface->w();
01197       };
01198       int getHeight()
01199       {
01200          return surface->h();
01201       };
01202 
01203    private:
01204       PixelType getSourcePixel(int x, int y)
01205       {
01206          if ( x >= 0 && y >= 0 && x < surface->w() && y < surface->h() )
01207             return surface->GetPixel(SPoint(x,y));
01208          else
01209             return surface->GetPixelFormat().colorkey();
01210       };
01211 
01212 
01213    public:
01214       void setAngle( const Surface& srv, int degrees )
01215       {
01216          init ( srv );
01217 
01218          if ( xsize == -1 ) {
01219             xsize = surface->w();
01220             ysize = surface->h();
01221          }
01222 
01223          this->degrees = degrees;
01224          if ( degrees != 0 && surface->w() == xsize && surface->h() == ysize ) {
01225             useCache = true;
01226             if ( cache.find( degrees ) == cache.end() ) {
01227                int* index = new int[surface->w() * surface->h()];
01228                cache[degrees] = index;
01229                for ( int y = 0; y < surface->h(); ++y )
01230                   for ( int x = 0; x < surface->w(); ++x ) {
01231                      SPoint pnt = getPixelRotationLocation( SPoint(x,y), surface->w(),surface->h(), degrees );
01232                      if ( pnt.x >= 0 && pnt.y >= 0 && pnt.x < surface->w() && pnt.y < surface->h() )
01233                         *index++ = pnt.x + pnt.y * surface->pitch()/pixelsize;
01234                      else
01235                         *index++ = -1;
01236                   }
01237             }
01238             cacheIndex = cache[degrees];
01239          }
01240       }
01241 
01242       SourcePixelSelector_CacheRotation( NullParamType npt = nullParam ) : surface(NULL), degrees(0), useCache(false),pixelStart(NULL), currentPixel(NULL),tableIndex(0),pitch(0), cacheIndex(NULL),x(0),y(0),w(0),h(0)
01243    {}
01244       ;
01245 
01246       SourcePixelSelector_CacheRotation( const Surface& srv, int degrees ) : surface(NULL), degrees(0), useCache(false),pixelStart(NULL), currentPixel(NULL),tableIndex(0),pitch(0), cacheIndex(NULL),x(0),y(0),w(0),h(0)
01247       {
01248          setAngle ( srv, degrees );
01249       };
01250 
01251       SourcePixelSelector_CacheRotation( pair<const Surface*, int> p ) : surface(NULL), degrees(0), useCache(false),pixelStart(NULL), currentPixel(NULL),tableIndex(0),pitch(0), cacheIndex(NULL),x(0),y(0),w(0),h(0)
01252       {
01253          setAngle ( *(p.first), p.second );
01254       };
01255 
01256 
01257 };
01258 
01259 
01260 template<int pixelsize, class SourcePixelSelector = SourcePixelSelector_Plain<pixelsize> >
01261 class SourcePixelSelector_Zoom: public SourcePixelSelector
01262 {
01263       typedef typename PixelSize2Type<pixelsize>::PixelType PixelType;
01264       float zoomFactorX;
01265       float zoomFactorY;
01266       int x,y;
01267    protected:
01268 
01269       int getWidth()
01270       {
01271          return int( zoomFactorX * SourcePixelSelector::getWidth()  );
01272       };
01273       int getHeight()
01274       {
01275          return int( zoomFactorY * SourcePixelSelector::getHeight() );
01276       };
01277 
01278       PixelType getPixel(int x, int y)
01279       {
01280          return SourcePixelSelector::getPixel( int(float(x) / zoomFactorX), int(float(y) / zoomFactorY));
01281       };
01282 
01283       PixelType nextPixel()
01284       {
01285          return getPixel(x++, y);
01286       };
01287 
01288       void skipPixels( int pixNum )
01289       {
01290          x += pixNum;
01291       };
01292 
01293       int getSourcePixelSkip()
01294       {
01295          return 0;
01296       };
01297       
01298       void nextLine()
01299       {
01300          x= 0;
01301          ++y;
01302       };
01303 
01304    public:
01305       void setZoom( float factor )
01306       {
01307          this->zoomFactorX = factor;
01308          this->zoomFactorY = factor;
01309       };
01310       void setZoom( float factorX, float factorY )
01311       {
01312          this->zoomFactorX = factorX;
01313          this->zoomFactorY = factorY;
01314       };
01315 
01316       float getZoomX()
01317       {
01318          return zoomFactorX;
01319       };
01320       float getZoomY()
01321       {
01322          return zoomFactorY;
01323       };
01324 
01325       void setSize( int sourceWidth, int sourceHeight, int targetWidth, int targetHeight, bool forceSquare = true )
01326       {
01327          float zw = float(targetWidth) / float(sourceWidth);
01328          float zh = float(targetHeight)/ float(sourceHeight);
01329          if ( forceSquare )
01330             setZoom( min ( zw,zh));
01331          else
01332             setZoom( zw,zh );
01333       };
01334 
01335       SourcePixelSelector_Zoom( NullParamType npt = nullParam) : zoomFactorX(1),zoomFactorY(1),x(0),y(0)
01336    {}
01337       ;
01338 
01339 };
01340 
01341 template<int pixelsize>
01342 class SourcePixelSelector_DirectZoom: public SourcePixelSelector_Zoom<pixelsize>
01343 {
01344    public:
01345       SourcePixelSelector_DirectZoom( NullParamType npt = nullParam)
01346       {}
01347       ;
01348 };
01349 
01350 
01351 class ZoomCache
01352 {
01353    protected:
01354       typedef map<float,int*> ZoomMap;
01355       static ZoomMap zoomCache;
01356 };
01357 
01358 
01359 template<int pixelsize, class SourcePixelSelector = SourcePixelSelector_Plain<pixelsize> >
01360 class SourcePixelSelector_CacheZoom : private ZoomCache, public SourcePixelSelector
01361 {
01362       typedef typename PixelSize2Type<pixelsize>::PixelType PixelType;
01363       const Surface* surface;
01364       float zoomFactor;
01365 
01366       int currSrcX;
01367       int currSrcY;
01368       int* xp;
01369       int* yp;
01370       int offsetx;
01371       int offsety;
01372       ZoomMap::iterator cacheit;
01373    protected:
01374 
01375       int getWidth()
01376       {
01377          return int( zoomFactor * SourcePixelSelector::getWidth()  );
01378       };
01379       int getHeight()
01380       {
01381          return int( zoomFactor * SourcePixelSelector::getHeight() );
01382       };
01383 
01384       PixelType getPixel(int x, int y)
01385       {
01386          return SourcePixelSelector::getPixel( int(float(x) / zoomFactor), int(float(y) / zoomFactor));
01387       };
01388 
01389       PixelType nextPixel()
01390       {
01391          for ( int i = 0; i < *xp; ++i )
01392             SourcePixelSelector::nextPixel();
01393          ++xp;
01394 
01395          return SourcePixelSelector::nextPixel();
01396       };
01397 
01398       void skipPixels( int pixNum )
01399       {
01400          int count = pixNum;
01401          for ( int i = 0; i < pixNum; ++i ) {
01402             count += *xp;
01403             ++xp;
01404          }
01405          SourcePixelSelector::skipPixels( count );
01406       };
01407 
01408       int getSourcePixelSkip()
01409       {
01410          int s = SourcePixelSelector::getSourcePixelSkip();
01411          if ( s ) {
01412             s = int(floor( float(s) * zoomFactor )) -2;  // to prevent rounding errors
01413             if ( s < 1 )
01414                return 1;
01415             else
01416                return s;
01417          } else
01418             return 0;
01419       };
01420 
01421       
01422       void nextLine()
01423       {
01424          SourcePixelSelector::nextLine();
01425          for ( int i = 0; i < *yp; ++i )
01426             SourcePixelSelector::skipWholeLine();
01427 
01428          xp = &cacheit->second[offsetx];
01429          yp++;
01430       };
01431 
01432 
01433    public:
01434 
01435       
01436       void setZoomOffset( int x, int y )
01437       {
01438          offsetx = x;
01439          offsety = y;
01440          /*
01441          for ( int i = 0; i < y; ++y )
01442             next
01443          */
01444       }
01445       
01446       
01447       void setZoom( float factor )
01448       {
01449          this->zoomFactor = factor;
01450          assert ( factor > 0 );
01451          assert ( factor <= 1 );
01452 
01453          cacheit = zoomCache.find( factor );
01454          if ( cacheit == zoomCache.end() ) {
01455             int size  = max ( SDLmm::Display::GetDisplay().w(), SDLmm::Display::GetDisplay().h() );
01456 
01457             int* buf = new int[size+1];
01458             buf[0] = 0;
01459 
01460             for ( int i = 0; i < size; ++i ) {
01461                int a1 =  int( floor( float(i) / zoomFactor ));
01462                int a2 =  int( floor( float(i+1) / zoomFactor ));
01463 
01464                buf[i+1] = a2 - a1 - 1;
01465             }
01466 
01467             zoomCache[zoomFactor] = buf;
01468             cacheit = zoomCache.find( factor );
01469          }
01470          xp = &cacheit->second[offsetx];
01471          yp = &cacheit->second[offsety];
01472       }
01473 
01474       SourcePixelSelector_CacheZoom( NullParamType npt = nullParam ) : surface(NULL), zoomFactor(1), xp(NULL), yp(NULL), offsetx(0), offsety(0)
01475       {
01476          cacheit = zoomCache.end();
01477       };
01478 
01479       SourcePixelSelector_CacheZoom( float zoom ) : surface(NULL), zoomFactor(1), xp(NULL), yp(NULL), offsetx(0), offsety(0)
01480       {
01481          cacheit = zoomCache.end();
01482          setZoom ( zoom );
01483       };
01484 
01485 
01486 };
01487 
01488 
01489 
01490 
01491 template<int pixelsize, class SourcePixelSelector = SourcePixelSelector_Plain<pixelsize> >
01492 class SourcePixelSelector_Flip: public SourcePixelSelector
01493 {
01494       typedef typename PixelSize2Type<pixelsize>::PixelType PixelType;
01495       bool hflip;
01496       bool vflip;
01497       int x,y;
01498       int w,h;
01499    protected:
01500 
01501       void init ( const Surface& srv )
01502       {
01503          SourcePixelSelector::init(srv);
01504          w = SourcePixelSelector::getWidth()-1;
01505          h = SourcePixelSelector::getHeight()-1;
01506       };
01507 
01508 
01509 
01510       PixelType getPixel(int x, int y)
01511       {
01512          return SourcePixelSelector::getPixel( hflip? w-x : x , vflip ? h-y : y );
01513       };
01514 
01515       PixelType nextPixel()
01516       {
01517          return getPixel(x++, y);
01518       };
01519 
01520       void skipPixels( int pixNum )
01521       {
01522          x += pixNum;
01523       };
01524       
01525       int getSourcePixelSkip()
01526       {
01527          return 0;
01528       };
01529 
01530       void nextLine()
01531       {
01532          x= 0;
01533          ++y;
01534       };
01535 
01536    public:
01537       void setFlipping( bool horizontal, bool vertical )
01538       {
01539          hflip = horizontal;
01540          vflip = vertical;
01541       };
01542 
01543       SourcePixelSelector_Flip( NullParamType npt = nullParam) : hflip(false),vflip(false),x(0),y(0),w(0),h(0)
01544       {}
01545       ;
01546 
01547       SourcePixelSelector_Flip( int flip) : hflip(flip&1),vflip(flip&2),x(0),y(0),w(0),h(0)
01548       {}
01549       ;
01550 
01551 };
01552 
01553 template<int pixelsize>
01554 class SourcePixelSelector_DirectFlip : public SourcePixelSelector_Flip<pixelsize>
01555 {
01556    public:
01557       SourcePixelSelector_DirectFlip( NullParamType npt = nullParam)
01558       {}
01559       ;
01560       SourcePixelSelector_DirectFlip( int flip) : SourcePixelSelector_Flip<pixelsize>(flip)
01561       {}
01562       ;
01563 };
01564 
01565 // template<int pixelsize, class SourcePixelSelector = SourcePixelSelector_Plain<pixelsize> > // MSVC7 fails to understand that...
01566 template<int pixelsize>
01567 class SourcePixelSelector_Rectangle: public SourcePixelSelector_Plain<pixelsize>
01568 {
01569       typedef typename PixelSize2Type<pixelsize>::PixelType PixelType;
01570       int x,y,x1,y1;
01571       int w,h;
01572    protected:
01573       SourcePixelSelector_Rectangle() : x(0),y(0),x1(0),y1(0),w(0),h(0)
01574       {}
01575       ;
01576 public:
01577 
01578       SourcePixelSelector_Rectangle( const SDLmm::SRect& rect ) : x(0),y(0),x1(0),y1(0),w(0),h(0)
01579       {
01580          setSrcRectangle( rect );
01581       }
01582 protected:
01583 
01584       int getWidth()
01585       {
01586          return min(w, SourcePixelSelector_Plain<pixelsize>::getWidth() -x1 );
01587       };
01588       int getHeight()
01589       {
01590          return min(h, SourcePixelSelector_Plain<pixelsize>::getHeight()-y1 );
01591       };
01592 
01593 
01594       PixelType getPixel(int x, int y)
01595       {
01596          return SourcePixelSelector_Plain<pixelsize>::getPixel( x + x1, y + y1 );
01597       };
01598 
01599       PixelType nextPixel()
01600       {
01601          return getPixel(x++, y);
01602       };
01603 
01604       void skipWholeLine()
01605       {
01606          ++y;
01607       };
01608 
01609       void skipPixels( int pixNum )
01610       {
01611          x += pixNum;
01612       };
01613 
01614       int getSourcePixelSkip()
01615       {
01616          return 0;
01617       };
01618       
01619       void nextLine()
01620       {
01621          x= 0;
01622          ++y;
01623       };
01624 
01625    public:
01626       void setSrcRectangle( SPoint pos, int width, int height )
01627       {
01628          x1 = pos.x;
01629          y1 = pos.y;
01630          w = width;
01631          h = height;
01632       };
01633       void setSrcRectangle( const SDLmm::SRect& rect )
01634       {
01635          x1 = rect.x;
01636          y1 = rect.y;
01637          w = rect.w;
01638          h = rect.h;
01639       };
01640 
01641 };
01642 
01643 template<int pixelsize>
01644 class SourcePixelSelector_DirectRectangle
01645 {
01646       typedef typename PixelSize2Type<pixelsize>::PixelType PixelType;
01647       int y,x1,y1;
01648       int w,h;
01649 
01650       const PixelType* pointer;
01651       const PixelType* startPointer;
01652       int pitch;
01653       int linelength;
01654       const Surface* surface;
01655    protected:
01656       SourcePixelSelector_DirectRectangle() : y(0),x1(0),y1(0),w(0),h(0),pointer(NULL), surface(NULL)
01657       {}
01658       ;
01659 
01660       int getWidth()
01661       {
01662          return min(w, surface->w() -x1 );
01663       };
01664       int getHeight()
01665       {
01666          return min(h, surface->h()-y1 );
01667       };
01668 
01669 
01670       void init ( const Surface& srv )
01671       {
01672          surface = &srv;
01673          startPointer = pointer = (const PixelType*)(srv.pixels());
01674          linelength = srv.pitch()/sizeof(PixelType);
01675          pitch = linelength - w -1  ;
01676          y = y1;
01677          pointer += x1 + y1 * linelength;
01678       };
01679 
01680       PixelType getPixel(int x, int y)
01681       {
01682          x += x1;
01683          y += y1;
01684          if ( x >= 0 && y >= 0 && x < surface->w() && y < surface->h() )
01685             return surface->GetPixel(SPoint(x,y));
01686          else
01687             return surface->GetPixelFormat().colorkey();
01688       };
01689 
01690 
01691       PixelType nextPixel()
01692       {
01693          return *(pointer++);
01694       };
01695 
01696 
01697       void skipWholeLine()
01698       {
01699          pointer += linelength;
01700          ++y;
01701       };
01702 
01703       void skipPixels( int pixNum )
01704       {
01705          pointer += pixNum;
01706       };
01707 
01708       int getSourcePixelSkip()
01709       {
01710          return 0;
01711       };
01712       
01713       void nextLine()
01714       {
01715          pointer = startPointer + x1 + (y++) * linelength;
01716       };
01717 
01718    public:
01719       void setSrcRectangle( SPoint pos, int width, int height )
01720       {
01721          x1 = pos.x;
01722          y1 = pos.y;
01723          w = width;
01724          h = height;
01725       };
01726       void setSrcRectangle( const SDLmm::SRect& rect )
01727       {
01728          x1 = rect.x;
01729          y1 = rect.y;
01730          w = rect.w;
01731          h = rect.h;
01732       };
01733 
01734 };
01735 
01736 
01737 class TargetPixelSelector_Rect {
01738         SDLmm::SRect rect; 
01739         int x2,y2;
01740         int xrange;
01741         int w,h;
01742         SPoint pos;
01743      protected:
01744         int skipTarget( int x, int y ) 
01745         { 
01746            int nx = x + pos.x;
01747            int ny = y + pos.y;
01748            if ( nx >= rect.x && ny >= rect.y && nx < x2 && ny < y2 )
01749               return 0; 
01750            else {
01751               if ( ny < rect.y )
01752                  return xrange - x;
01753               else
01754                  if ( nx < rect.x )
01755                     return rect.x - nx;
01756                  else   
01757                     if (ny >= y2 )
01758                        return -1;
01759                     else
01760                        if ( nx >= x2 )
01761                           return xrange - x;
01762                        else
01763                           return 1;     
01764            }      
01765         };
01766         void init( const Surface& srv, const SPoint& position, int xrange, int yrange ) 
01767         {
01768            w = srv.w();
01769            h = srv.h();
01770            pos = position;
01771            this->xrange = xrange;
01772         };
01773         
01774      public:
01775         void setTargetRect( const SDL_Rect& r  ) 
01776         { 
01777            rect = r; 
01778            x2 = r.x + r.w; 
01779            y2 = r.y + r.h;
01780         };
01781         
01782         void setClippingRect( SDL_Surface*  srv  ) 
01783         { 
01784            setTargetRect( srv->clip_rect );
01785         };
01786         
01787         TargetPixelSelector_Rect ( NullParamType npt = nullParam ) :w(0xffffff),h(0xffffff) {};   
01788   };
01789 
01790 
01791 /*
01792  
01793  template<class SourceColorTransform, class ColorMerger, class SourcePixelSelector>
01794  void megaBlit( const Surface& src, Surface& dst, SPoint dstPos )
01795  {
01796     switch ( dst.GetPixelFormat().BytesPerPixel() ) {
01797        case 1: megaBlit<1,SourceColorTransform,ColorMerger,SourcePixelSelector>( src, dst, dstPos ); break;
01798        case 2: megaBlit<2,SourceColorTransform,ColorMerger,SourcePixelSelector>( src, dst, dstPos ); break;
01799        case 4: megaBlit<4,SourceColorTransform,ColorMerger,SourcePixelSelector>( src, dst, dstPos ); break;
01800     };
01801  }
01802  
01803 */
01804 
01805 #endif
01806 

Generated on Mon May 21 01:26:29 2012 for Advanced Strategic Command by  doxygen 1.5.1