Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

surface.cpp

Go to the documentation of this file.
00001 
00002 /*
00003     This file is part of Advanced Strategic Command; http://www.asc-hq.de
00004     Copyright (C) 1994-2003  Martin Bickel  and  Marc Schellenberger
00005 
00006     This program is free software; you can redistribute it and/or modify
00007     it under the terms of the GNU General Public License as published by
00008     the Free Software Foundation; either version 2 of the License, or
00009     (at your option) any later version.
00010 
00011     This program is distributed in the hope that it will be useful,
00012     but WITHOUT ANY WARRANTY; without even the implied warranty of
00013     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014     GNU General Public License for more details.
00015 
00016     You should have received a copy of the GNU General Public License
00017     along with this program; see the file COPYING. If not, write to the
00018     Free Software Foundation, Inc., 59 Temple Place, Suite 330,
00019     Boston, MA  02111-1307  USA
00020 */
00021 
00022 #include <SDL_image.h>
00023 #include <cmath>
00024 #include "../sdl/sdlstretch.h"
00025 #include "surface.h"
00026 #include "blitter.h"
00027 #include "../basegfx.h"
00028 #include "../basestrm.h"
00029 #include "../misc.h"
00030 #include "../messaginghub.h"
00031 #include <iostream>
00032 
00033 DI_Color::DI_Color() {
00034         r = 0;
00035         g = 0;
00036         b = 0;
00037 }
00038 
00039 DI_Color::DI_Color(const SDL_Color& c) {
00040         *this = c;
00041 }
00042 
00043 DI_Color::DI_Color(Uint32 c) {
00044         *this = c;
00045 }
00046 
00047 DI_Color::DI_Color(Uint8 r, Uint8 g, Uint8 b) {
00048         *this = (Uint32)((r << 16) | (g << 8) | b);
00049 }
00050 
00051 DI_Color& DI_Color::operator=(const SDL_Color& c) {
00052         r = c.r;
00053         g = c.g;
00054         b = c.b;
00055         
00056         return *this;
00057 }
00058 
00059 DI_Color& DI_Color::operator=(Uint32 c) {
00060         r = (c >> 16) & 0xFF;
00061         g = (c >> 8) & 0xFF;
00062         b = c & 0xFF;
00063         
00064         return *this;
00065 }
00066 
00067 /*
00068 DI_Color::operator Uint32() const {
00069         return (r << 16) | (g << 8) | b;
00070 }
00071 */
00072 
00073 
00074 
00075  SDLmm::PixelFormat* Surface::default8bit  = NULL;
00076  SDLmm::PixelFormat* Surface::default32bit = NULL;
00077 
00078 void Surface::SetScreen( SDL_Surface* screen )
00079 {
00080   if ( screen && screen->format->BitsPerPixel == 32 )    
00081      default32bit = new SDLmm::PixelFormat ( screen->format );
00082 }
00083 
00084 
00085 Surface Surface::Duplicate() const 
00086 {
00087    Surface new_surface(CreateSurface(*this));
00088 
00089    megaBlitter<ColorTransform_None, ColorMerger_PlainOverwrite, SourcePixelSelector_Plain, TargetPixelSelector_All>(*this, new_surface, SPoint(0,0), nullParam, nullParam, nullParam, nullParam); 
00090 
00091    new_surface.Blit(*this); 
00092    return new_surface;
00093 }
00094  
00095  
00096  void writeDefaultPixelFormat ( SDLmm::PixelFormat pf, tnstream& stream )
00097  {
00098     stream.writeInt( 1 );
00099     stream.writeInt(pf.BitsPerPixel()) ;
00100     stream.writeInt(pf.BytesPerPixel()) ;
00101     stream.writeInt(pf.Rmask()) ;
00102     stream.writeInt(pf.Gmask()) ;
00103     stream.writeInt(pf.Bmask()) ;
00104     stream.writeInt(pf.Amask()) ;
00105     stream.writeInt(pf.Rshift()) ;
00106     stream.writeInt(pf.Gshift()) ;
00107     stream.writeInt(pf.Bshift()) ;
00108     stream.writeInt(pf.Ashift()) ; 
00109     stream.writeInt(pf.Rloss()) ;
00110     stream.writeInt(pf.Gloss()) ;
00111     stream.writeInt(pf.Bloss()) ;
00112     stream.writeInt(pf.Aloss()) ;
00113     stream.writeInt(pf.colorkey()) ;
00114     stream.writeInt(pf.alpha()) ;
00115  }
00116 
00117  SDL_PixelFormat* readSDLPixelFormat( tnstream& stream )
00118  {
00119     SDL_PixelFormat* pf = new SDL_PixelFormat;
00120     int version = stream.readInt();
00121     if ( version != 1 )
00122        throw tinvalidversion( stream.getLocation(), 1, version );
00123        
00124     pf->BitsPerPixel = stream.readInt();
00125     pf->BytesPerPixel = stream.readInt();
00126     pf->Rmask = stream.readInt();
00127     pf->Gmask = stream.readInt();
00128     pf->Bmask = stream.readInt();
00129     pf->Amask = stream.readInt();
00130     pf->Rshift = stream.readInt();
00131     pf->Gshift = stream.readInt();
00132     pf->Bshift = stream.readInt();
00133     pf->Ashift = stream.readInt();
00134     pf->Rloss = stream.readInt();
00135     pf->Gloss = stream.readInt();
00136     pf->Bloss = stream.readInt();
00137     pf->Aloss = stream.readInt();
00138     pf->colorkey = stream.readInt();
00139     pf->alpha = stream.readInt();
00140     return pf;
00141  }
00142 
00143  
00144  
00145 Surface::Surface( SDL_Surface *surface) : SDLmm::Surface ( surface ), pixelDataPointer(NULL)
00146 {
00147    if ( me )
00148       convert();
00149 }
00150 
00151 void Surface::convert()
00152 {
00153    if ( GetPixelFormat().BitsPerPixel() == 24 ) {
00154       Surface s = Surface::createSurface(w(), h(), 32 );
00155       s.Blit( *this );
00156       if ( flags() & SDL_SRCCOLORKEY ) 
00157          s.SetColorKey( SDL_SRCCOLORKEY, GetPixelFormat().colorkey() );
00158       *this = s;   
00159    }
00160 
00161    if ( default32bit && GetPixelFormat().BytesPerPixel() == 4 )  {
00162       if ( default32bit->Rmask() != GetPixelFormat().Rmask() || default32bit->Gmask() != GetPixelFormat().Gmask() || default32bit->Bmask() != GetPixelFormat().Bmask() ) {
00163          SDL_Surface *tmp;
00164          if ( flags() & SDL_SRCALPHA )
00165             tmp  = SDL_DisplayFormatAlpha(me);
00166          else
00167             tmp  = SDL_DisplayFormat(me);
00168 
00169          if ( !tmp )
00170             return;
00171 
00172          SetSurface(tmp);
00173       }
00174    }
00175 
00176 }
00177 
00178 /*
00179 SDLmm::ColorRGB  Surface::GetRGB(SDLmm::Color pixel) const
00180 {
00181    if ( GetPixelFormat().BytesPerPixel() == 1 ) {
00182       assert( pixel < 256 );
00183       return SDLmm::ColorRGB( pal[pixel][0] * 4, pal[pixel][1] * 4, pal[pixel][2] * 4 );
00184    } else
00185       return GetPixelFormat().GetRGB( pixel );
00186 }
00187 
00188 SDLmm::ColorRGBA Surface::GetRGBA(SDLmm::Color pixel) const
00189 {
00190    if ( GetPixelFormat().BytesPerPixel() == 1 ) {
00191       assert( pixel < 256 );
00192       return SDLmm::ColorRGBA( pal[pixel][0] * 4, pal[pixel][1] * 4, pal[pixel][2] * 4, opaque );
00193    } else
00194       return GetPixelFormat().GetRGBA( pixel );
00195 }
00196 */
00197 
00198 Surface::Surface(const SDLmm::Surface& other) : SDLmm::Surface ( other ), pixelDataPointer(NULL)
00199 {
00200    if ( me )
00201       convert();
00202 }
00203 
00204  
00205  void Surface::readDefaultPixelFormat ( tnstream& stream )
00206  {
00207      default8bit = new SDLmm::PixelFormat( readSDLPixelFormat( stream ) );
00208      default32bit = new SDLmm::PixelFormat( readSDLPixelFormat( stream ) );
00209  }
00210 
00211  void Surface::writeDefaultPixelFormat ( tnstream& stream )
00212  {
00213      ::writeDefaultPixelFormat( GetPixelFormat(),stream );
00214  }
00215 
00216  const int surfaceVersion = 2;
00217 
00218 void Surface::write ( tnstream& stream ) const
00219 {
00220    if ( !valid() ) {
00221       stream.writeWord( 16974 );
00222       stream.writeWord ( 1 );
00223       stream.writeChar ( 0 );
00224       stream.writeWord ( 0 );
00225       stream.writeWord ( 0 );
00226       return;
00227    } 
00228    stream.writeWord( 16974 );
00229    stream.writeWord ( 1 );
00230    stream.writeChar ( 0 );
00231    stream.writeWord ( w() );
00232    stream.writeWord ( h() );
00233    stream.writeInt( surfaceVersion );
00234 
00235    SDLmm::PixelFormat pf = GetPixelFormat();
00236 
00237    stream.writeChar ( pf.BitsPerPixel() );
00238    stream.writeChar ( pf.BytesPerPixel() );
00239    stream.writeInt ( GetPixelFormat().colorkey());
00240    stream.writeInt( flags() );
00241    if ( pf.BytesPerPixel() == 1 ) {
00242       for ( int y = 0; y < h(); ++y )
00243          stream.writedata( ((char*)me->pixels) + y*pitch(), w() );
00244       /*
00245       for ( int y = 0; y < h(); ++y )
00246          for ( int x = 0; x < w(); ++x )
00247             stream.writeChar( GetPixel(x,y));
00248       */      
00249    } else {
00250       SDLmm::PixelFormat pf = GetPixelFormat();
00251       stream.writeInt(pf.Rmask()) ;
00252       stream.writeInt(pf.Gmask()) ;
00253       stream.writeInt(pf.Bmask()) ;
00254       stream.writeInt(pf.Amask()) ;
00255       for ( int y = 0; y < h(); ++y ) {
00256          for ( int x = 0; x < w(); ++x )
00257             stream.writeInt( GetPixel(x,y));
00258             
00259       }
00260    }
00261 
00262 }
00263 
00264  
00265 void Surface::read ( tnstream& stream )
00266 {
00267   trleheader   hd;
00268 
00269   hd.id = stream.readWord();
00270   hd.size = stream.readWord();
00271   hd.rle = stream.readChar();
00272   hd.x = stream.readWord();
00273   hd.y = stream.readWord();
00274   
00275   if ( hd.x == 0 && hd.y == 0 ) {
00276       SetSurface( NULL );
00277       return;  
00278   }
00279 
00280    if (hd.id == 16973) {
00281       char *pnter = new char [ hd.size + sizeof(hd) ];
00282       memcpy( pnter, &hd, sizeof(hd));
00283       char* q = pnter + sizeof(hd);
00284 
00285       stream.readdata( q, hd.size);  // endian ok ?
00286 
00287       char* uncomp = (char*) uncompress_rlepict ( pnter );
00288       pixelDataPointer = uncomp;
00289       
00290       // TODO fix memory leak: uncomp will not be deleted
00291       delete[] pnter;
00292 
00293       SetSurface( SDL_CreateRGBSurfaceFrom(uncomp+4, hd.x+1, hd.y+1, 8, hd.x+1, 0, 0, 0, 0 ));
00294       SetColorKey( SDL_SRCCOLORKEY, 255 );
00295       assignDefaultPalette();
00296    }
00297    else {
00298       if (hd.id == 16974) {
00299          int version = stream.readInt();
00300          if ( version > surfaceVersion )
00301             throw tinvalidversion( stream.getLocation(), version, surfaceVersion );
00302              
00303          stream.readChar(); // int bitsPerPixel = 
00304          int bytesPerPixel = stream.readChar();
00305          int colorkey = stream.readInt();
00306          int flags = stream.readInt();
00307          if ( bytesPerPixel == 1 ) {
00308             SDL_Surface* s = SDL_CreateRGBSurface ( SDL_SWSURFACE, hd.x, hd.y, 8, 0xff, 0xff, 0xff, 0xff );
00309             Uint8* p = (Uint8*)( s->pixels );
00310             for ( int y = 0; y < hd.y; ++y )
00311                stream.readdata( p + y*s->pitch, hd.x );
00312             
00313                /*for ( int x = 0; x< hd.x; ++x )
00314                   *(p++) = stream.readChar();*/
00315                   
00316             SetSurface( s );
00317             assignDefaultPalette();
00318 
00319          } else {
00320             int Rmask = stream.readInt();
00321             int Gmask = stream.readInt();
00322             int Bmask = stream.readInt();
00323             int Amask = stream.readInt();
00324 
00325             SDL_Surface* s = SDL_CreateRGBSurface ( SDL_SWSURFACE, hd.x, hd.y, 32, Rmask, Gmask, Bmask, Amask );
00326             Uint32* p = (Uint32*)( s->pixels );
00327             for ( int y = 0; y < hd.y; ++y ) {
00328                for ( int x = 0; x< hd.x; ++x )
00329                   *(p++) = stream.readInt();
00330             }
00331             SetSurface( s );
00332          }
00333          if ( flags & SDL_SRCCOLORKEY )
00334             SetColorKey( SDL_SRCCOLORKEY, colorkey );
00335             
00336          if ( flags & SDL_SRCALPHA )
00337             SetAlpha ( SDL_SRCALPHA, GetPixelFormat().alpha());
00338          else
00339             SetAlpha ( 0, SDL_ALPHA_OPAQUE);
00340             
00341       } else {
00342          // int w =  (hd.id + 1) * (hd.size + 1) ;
00343          
00344          SDL_Surface* s = SDL_CreateRGBSurface( SDL_SWSURFACE, hd.id+1, hd.size+1, 8, 0,0,0,0 );
00345 
00346          for ( int y = 0; y <= hd.size; ++y ) {
00347             char* pixeldata = (char*)(s->pixels) + y * s->pitch;
00348             if ( y == 0 ) {
00349                memcpy ( pixeldata, ((char*)&hd) + 4, sizeof ( hd ) - 4);
00350                char* q = pixeldata + sizeof(hd) - 4;
00351                stream.readdata ( q, s->w - sizeof(hd) + 4 ); 
00352             } else {
00353                stream.readdata ( pixeldata, s->w ); 
00354             }
00355          }
00356 /*
00357 
00358          char* pntr = (char*) asc_malloc( w );
00359          stream.readdata ( q, w - sizeof(hd) + 4 ); // endian ok ?
00360 
00361          SDL_SWSURFACE
00362          SDL_Surface* s = SDL_CreateRGBSurfaceFrom(pntr, hd.id+1, hd.size+1, 8, hd.id+1, 0, 0, 0, 0 );
00363 //         s->flags &= ~SDL_PREALLOC;
00364   */       
00365          SetSurface( s );
00366          SetColorKey( SDL_SRCCOLORKEY, 255 );
00367          assignDefaultPalette();
00368       }
00369    }
00370    convert();
00371 }
00372 
00373 void Surface::readImageFile( tnstream& stream )
00374 {
00375    SetSurface( IMG_Load_RW( SDL_RWFromStream ( &stream ), true ));
00376    convert();
00377 }
00378 
00379 
00380 Surface Surface::createSurface( int width, int height, SDLmm::Color color )
00381 {
00382    Surface s = createSurface ( width, height, 8, color );
00383    s.SetColorKey( SDL_SRCCOLORKEY, 255 );
00384    return s;
00385 }
00386 
00387 Surface Surface::createSurface( int width, int height, int depth, SDLmm::Color color )
00388 {
00389    assert ( depth == 32 || depth == 8 );
00390 
00391    SDL_Surface* surf = NULL;   
00392    if ( depth == 32 && default32bit ) {
00393       int rmask = default32bit->Rmask();
00394       int gmask = default32bit->Gmask();
00395       int bmask = default32bit->Bmask();
00396       int amask = ~(rmask | gmask | bmask );
00397       surf = SDL_CreateRGBSurface(SDL_SWSURFACE, width, height, depth, rmask, gmask, bmask, amask );
00398    } else
00399       surf = SDL_CreateRGBSurface(SDL_SWSURFACE, width, height, depth, 0xff, 0xff00, 0xff0000, 0xff000000 );
00400    
00401    Surface s ( surf );
00402    if ( depth == 32 )
00403       s.Fill(color);
00404    else {
00405       s.Fill(color & 0xff );
00406       s.assignDefaultPalette();
00407    }
00408    // s.SetColorKey( SDL_SRCCOLORKEY, 255 );
00409    return s;
00410 }
00411 
00412 void Surface::FillTransparent()
00413 {
00414    if ( GetPixelFormat().BitsPerPixel() == 32 ) {
00415       Fill( 0 );
00416    } else {
00417       Fill( GetPixelFormat().colorkey() );
00418    }      
00419 }
00420 
00421 
00422 void Surface::assignDefaultPalette()
00423 {
00424    if ( me && GetPixelFormat().BytesPerPixel() == 1 ) {
00425         SDL_Color spal[256];
00426         memset ( spal, 0, 256* sizeof(SDL_Color));
00427         for ( int i = 0; i < 256; i++ ) {
00428            spal[i].r = pal[i][0] * 4;;
00429            spal[i].g = pal[i][1] * 4;;
00430            spal[i].b = pal[i][2] * 4;;
00431          }
00432          SDL_SetColors ( me, spal, 0, 256 );
00433    }
00434 }
00435 
00436 
00437 void Surface::assignPalette(SDL_Color* colors, int startColor, int colorNum )
00438 {
00439    if ( me )
00440       SDL_SetColors ( me, colors, startColor, colorNum );
00441 }
00442 
00443 
00444 /*
00445 void SDL_StretchSurface(SDL_Surface* src_surface, int xs1, int ys1, int xs2, int ys2, SDL_Surface* dst_surface, int xd1, int yd1, int xd2, int yd2, Uint32* lutVOI)
00446 {
00447 }
00448 */
00449 
00450 void Surface::strech ( int width, int height )
00451 {
00452    if ( width != w() || height != h() ) {
00453       SDL_Surface* s;
00454       if( GetPixelFormat().BytesPerPixel() == 1 )
00455          s = SDL_CreateRGBSurface ( SDL_SWSURFACE, width, height, 8, 0,0,0,0 );
00456       else
00457          s = SDL_CreateRGBSurface ( SDL_SWSURFACE, width, height, 32, 0xff, 0xff00, 0xff0000, 0xff000000 );
00458          
00459       SDL_StretchSurface( me,0,0,w()-1,h()-1, s, 0,0,width-1, height-1);
00460 
00461       SetSurface(s);
00462       if( GetPixelFormat().BytesPerPixel() == 1 ) {
00463          assignDefaultPalette();
00464          detectColorKey();
00465       }
00466    }
00467 }
00468 
00469 bool Surface::hasAlpha() 
00470 {
00471    if ( GetPixelFormat().BitsPerPixel() > 8 ) {
00472       for ( int y = 0; y < h(); ++y )
00473          for ( int x = 0; x < w(); ++x )
00474             if ( (GetPixel(x,y) >> GetPixelFormat().Ashift())  != SDL_ALPHA_OPAQUE ) {
00475                // GetSurface()->flags |= SDL_SRCALPHA;
00476                return true;
00477             }
00478 
00479       // GetSurface()->flags &= ~SDL_SRCALPHA; 
00480    }
00481    return false;
00482 }
00483 
00484 
00485 
00486 void Surface::detectColorKey ( bool RLE )
00487 {
00488 
00489    // detect if image has per pixel alpha - don't use ColorKey then
00490    if ( GetPixelFormat().BitsPerPixel() > 8 ) 
00491       if ( hasAlpha() ) 
00492          return;
00493    
00494    int flags = SDL_SRCCOLORKEY;
00495    if ( RLE )
00496       flags |= SDL_RLEACCEL;
00497       
00498    SetAlpha ( 0, 0 );
00499       
00500    if ( GetPixelFormat().BitsPerPixel() > 8 ) {
00501       SetColorKey( flags, GetPixel(0,0) & ( GetPixelFormat().Rmask() | GetPixelFormat().Gmask() | GetPixelFormat().Bmask()));
00502    } else
00503       SetColorKey( flags, GetPixel(0,0));
00504       // SetColorKey( flags, 255 );
00505 }
00506 
00507 
00508 bool Surface::isTransparent( SDLmm::Color col ) const
00509 {
00510    if ( flags() & SDL_SRCCOLORKEY ) 
00511       return (col & (GetPixelFormat().Rmask() | GetPixelFormat().Gmask() | GetPixelFormat().Bmask())) == GetPixelFormat().colorkey();
00512    else {
00513       if ( GetPixelFormat().BitsPerPixel() == 8 )
00514          return false;
00515       else {
00516          if ( ((col & GetPixelFormat().Amask()) >> GetPixelFormat().Ashift()) < opaque/2)
00517             return true;
00518          else
00519             return false;
00520       }
00521    }
00522 }
00523 
00524 Surface::~Surface()
00525 {/*
00526    if ( pixelDataPointer ) {
00527       asc_free( pixelDataPointer );
00528       pixelDataPointer = NULL;
00529    }
00530    */
00531 }
00532 
00533 
00534 
00535 
00536 Surface& getFieldMask()
00537 {
00538    static Surface* mask8 = NULL;
00539    if ( !mask8 ) {
00540       try {
00541          tnfilestream st ( "largehex.pcx", tnstream::reading );
00542          RWOPS_Handler rwo ( SDL_RWFromStream( &st ) );
00543          mask8 = new Surface ( IMG_LoadPCX_RW ( rwo.Get() ));
00544          rwo.Close();
00545 
00546          assert ( mask8->GetPixelFormat().BitsPerPixel() == 8);
00547          mask8->SetColorKey( SDL_SRCCOLORKEY, 0 );
00548       }
00549       catch ( tfileerror err ) {
00550          fatalError( "could not access " + err.getFileName() );
00551       }
00552       
00553    }
00554    return *mask8;
00555 
00556 }
00557 
00558 
00559 template<int pixelsize>
00560 class ColorMerger_MaskApply : public ColorMerger_AlphaHandler<pixelsize>
00561 {
00562       int alphamask;
00563       typedef typename PixelSize2Type<pixelsize>::PixelType PixelType;
00564    protected:
00565 
00566       void init( const Surface& srf )
00567       {
00568          alphamask = ~(srf.GetPixelFormat().Amask());
00569          ColorMerger_AlphaHandler<pixelsize>::init(srf);
00570       }
00571 
00572 
00573       void assign ( PixelType src, PixelType* dest )
00574       {
00575          if ( !isOpaque(src ) )
00576             *dest &= alphamask;
00577       };
00578 
00579    public:
00580       ColorMerger_MaskApply( NullParamType npt = nullParam )
00581       {}
00582       ;
00583 };
00584 
00585 
00586 void applyFieldMask( Surface& s, int x, int y, bool detecColorKey )
00587 {
00588    if ( s.GetPixelFormat().BitsPerPixel() == 8 ) {
00589       // we don't want any transformations from one palette to another; we just assume that all 8-Bit images use the same colorspace
00590       MegaBlitter<1,1,ColorTransform_None,ColorMerger_AlphaOverwrite> blitter;
00591       blitter.blit( getFieldMask(), s, SPoint(0,0)  );
00592       s.detectColorKey (  );
00593    } else {
00594       if ( detecColorKey ) {
00595          s.Blit( getFieldMask() );
00596          s.detectColorKey (  );
00597       } else {
00598          MegaBlitter<1,4,ColorTransform_None,ColorMerger_MaskApply> blitter;
00599          blitter.blit( getFieldMask(), s, SPoint(0,0)  );
00600       }
00601    }
00602 }
00603 
00604 void applyLegacyFieldMask( Surface& s, int x, int y, bool detectColorKey )
00605 {
00606    static Surface* mask32 = NULL;
00607    if ( !mask32 ) {
00608       Surface& mask8 = getFieldMask();
00609       
00610       mask32 = new Surface ( Surface::createSurface( mask8.w(), mask8.h(), 32 ));
00611       for ( int y = 0; y < mask8.h(); ++y ) {
00612          Uint8* s = ((Uint8*) mask8.pixels()) + mask8.pitch() * y;
00613          Uint32* d = (Uint32*) ((Uint8*)(mask32->pixels()) + mask32->pitch() * y);
00614          for ( int x = 0; x < mask8.w(); ++x, ++s, ++d)
00615             if ( *s == 0 )
00616                *d = 0;   
00617             else
00618                *d = 0xfffefefe;
00619       }
00620               
00621       mask32->SetColorKey( SDL_SRCCOLORKEY, 0 );
00622       
00623    }
00624    if ( s.GetPixelFormat().BitsPerPixel() == 8 ) {
00625       // we don't want any transformations from one palette to another; we just assume that all 8-Bit images use the same colorspace
00626       MegaBlitter<1,1,ColorTransform_None,ColorMerger_AlphaOverwrite> blitter;
00627       blitter.blit( getFieldMask(), s, SPoint(0,0)  );
00628       s.detectColorKey (  );
00629    } else {
00630       if ( !detectColorKey || s.hasAlpha() ) {
00631          MegaBlitter<1,4,ColorTransform_None,ColorMerger_MaskApply> blitter;
00632          blitter.blit( getFieldMask(), s, SPoint(0,0)  );
00633       } else {
00634          s.Blit( *mask32 );
00635          s.detectColorKey (  );
00636       }
00637    }
00638 }
00639 
00640 /*
00641 void colorShift ( Surface& s, int startcolor, int colNum, int shift )
00642 {
00643    if ( s.GetPixelFormat().BitsPerPixel() != 8)
00644       fatalError ( "colorShift can only be done with 8 Bit surfaces");
00645 
00646    SDL_Color spal[256];
00647    int col;
00648    for ( int i = 0; i < 256; i++ ) {
00649       int src;
00650       if ( i >= startcolor && i < startcolor + colNum )
00651          src = i + shift;
00652       else
00653          src = i;
00654       for ( int c = 0; c < 3; c++ ) {
00655          col = pal[src][c];
00656          switch ( c ) {
00657             case 0: spal[i].r = col * 4; break;
00658             case 1: spal[i].g = col * 4; break;
00659             case 2: spal[i].b = col * 4; break;
00660          };
00661       }
00662    }
00663    s.assignPalette( spal, 0, 256 );
00664 }
00665 */
00666 
00667 Surface rotateSurface( Surface& s, int degrees )
00668 {
00669    SurfaceLock sl1 ( s );
00670 
00671    Surface dest = s.Duplicate();
00672 
00673    SurfaceLock sl2( dest );
00674 
00675    if ( s.GetPixelFormat().BitsPerPixel() == 8 )
00676       dest.Fill ( 255 );
00677    else {
00678       dest.Fill(0xfefefe);
00679    }
00680    dest.detectColorKey();
00681 
00682    for ( int y = 0; y < s.h(); y++ ) {
00683       for ( int x = 0; x < s.w(); x++ ) {
00684          SPoint newpos = getPixelRotationLocation( SPoint(x,y), s.w(),s.h(), degrees );
00685 
00686          if ( newpos.x >= 0 && newpos.y >= 0 && newpos.x < s.w() && newpos.y < s.h() )
00687             dest.SetPixel( x, y, s.GetPixel ( newpos ));
00688       }
00689    }
00690 
00691    return dest;
00692 }
00693 
00694 
00695 void* Surface::toBGI() const
00696 {
00697    void* p = asc_malloc( imagesize(1,1,w(),h()) );
00698    char* c = (char*) p;
00699    Uint16* ww = (Uint16*) p;
00700    ww[0] = w()-1;
00701    ww[1] = h()-1;
00702    c += 4;
00703    for ( int y = 0; y < h(); ++y )
00704       for ( int x = 0; x < w(); ++x )
00705           *c++ = GetPixel(x,y);
00706    return p;
00707 }
00708 
00709 int Surface::getMemoryFootprint() const
00710 {
00711    int size = sizeof(*this);
00712    
00713    const SDL_Surface* s = getBaseSurface();
00714    if ( s ) {
00715       size += sizeof( SDL_Surface );
00716       if ( s->format ) {
00717          size += sizeof( SDL_PixelFormat );
00718          if ( s->format->palette )
00719             size += sizeof ( SDL_Palette ) + s->format->palette->ncolors * sizeof(SDL_Color);
00720       }
00721       size += s->h * s->pitch;
00722    }
00723    return size;
00724 }
00725 
00726 
00727 void Surface::ColorKey2AlphaChannel() 
00728 {
00729    Lock();
00730    for ( int y = 0; y < h(); ++y ) {
00731       char* cp = (char*) pixels();
00732       cp += y * pitch();
00733       int* ip = (int*) cp;
00734       for ( int x = 0; x < w(); ++x, ++ip ) 
00735          if ( (*ip & ~(0xff << GetPixelFormat().Ashift())) == GetPixelFormat().colorkey())
00736             *ip &= ~(Surface::transparent << GetPixelFormat().Ashift());
00737    }
00738    GetSurface()->flags &= ~SDL_SRCCOLORKEY;
00739    Unlock();
00740 }
00741 

Generated on Tue Jun 24 01:27:52 2008 for Advanced Strategic Command by  doxygen 1.4.2