00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include <vector>
00019 #include <algorithm>
00020 #include <iostream>
00021 #include <SDL_image.h>
00022 #include <boost/regex.hpp>
00023
00024 #include "global.h"
00025 #include "ascstring.h"
00026 #include "fieldimageloader.h"
00027 #include "typen.h"
00028 #include "graphics/blitter.h"
00029
00030 #include "basestreaminterface.h"
00031 #include "stringtokenizer.h"
00032 #include "graphics/surface2png.h"
00033
00034
00035 const char* fileNameDelimitter = " =*/+<>,";
00036
00037
00038 void snowify( Surface& s, bool adaptive )
00039 {
00040 if ( !s.valid() )
00041 return;
00042
00043 if ( s.GetPixelFormat().BitsPerPixel() != 32 )
00044 return;
00045
00046
00047 const int targetWhite = 210;
00048
00049 float avg = 0;
00050 if ( adaptive ) {
00051 for ( int y = 0; y < s.h(); ++y ) {
00052 const char* c = (char*) s.pixels();
00053 c += y * s.pitch();
00054 for ( int x = 0; x < s.w(); ++x ) {
00055 uint32_t* i = (uint32_t*) c;
00056 avg += ((*i >> s.GetPixelFormat().Rshift()) & 0xff )
00057 + ((*i >> s.GetPixelFormat().Gshift()) & 0xff )
00058 + ((*i >> s.GetPixelFormat().Bshift()) & 0xff ) ;
00059 c += 4;
00060 }
00061 }
00062
00063 avg /= float(s.h() * s.w() * 3);
00064 } else
00065 avg = 150;
00066
00067 for ( int y = 0; y < s.h(); ++y ) {
00068 char* c = (char*) s.pixels();
00069 c += y * s.pitch();
00070 for ( int x = 0; x < s.w(); ++x ) {
00071 uint32_t* i = (uint32_t*) c;
00072 if ( ((*i >> s.GetPixelFormat().Ashift()) & 0xff ) != Surface::transparent ) {
00073 int v = ((*i >> s.GetPixelFormat().Rshift()) & 0xff )
00074 + ((*i >> s.GetPixelFormat().Gshift()) & 0xff )
00075 + ((*i >> s.GetPixelFormat().Bshift()) & 0xff ) ;
00076 v /= 3;
00077
00078 int nv = targetWhite + ( v - int(avg)) * (255-targetWhite) / 64;
00079 if ( nv > 255)
00080 nv = 255;
00081 if ( nv < 0 )
00082 nv = 0;
00083
00084 *i = (nv << s.GetPixelFormat().Rshift()) | (nv << s.GetPixelFormat().Gshift() ) | (nv << s.GetPixelFormat().Bshift()) | (*i & s.GetPixelFormat().Amask() );
00085 }
00086 c += 4;
00087 }
00088 }
00089 }
00090
00091 bool imageEmpty( const Surface& s )
00092 {
00093 bool allWhite = true;
00094 bool allTransparent = true;
00095 int amask = s.GetPixelFormat().Amask();
00096 int areference = Surface::transparent << s.GetPixelFormat().Ashift();
00097
00098 int colmask = s.GetPixelFormat().Rmask() | s.GetPixelFormat().Gmask() | s.GetPixelFormat().Bmask();
00099 int colref = (0xff << s.GetPixelFormat().Rshift()) | (0xff << s.GetPixelFormat().Gshift()) | (0xff << s.GetPixelFormat().Bshift());
00100
00101 for ( int y = 0; y < s.h(); ++y ) {
00102 const char* c = (char*) s.pixels();
00103 c += y * s.pitch();
00104 for ( int x = 0; x < s.w(); ++x ) {
00105 const uint32_t* i = (uint32_t*) c;
00106 if( (*i & amask) != areference )
00107 allTransparent = false;
00108
00109 if ( (*i & colmask) != colref )
00110 allWhite = false;
00111
00112 c += 4;
00113 }
00114 if ( !allWhite && !allTransparent )
00115 return false;
00116 }
00117 return allWhite || allTransparent;
00118 }
00119
00120 vector<Surface> loadASCFieldImageArray ( const ASCString& file, int num )
00121 {
00122 vector<Surface> images;
00123
00124 int xsize;
00125 if ( num <= 10)
00126 xsize = (num+1)* 100;
00127 else
00128 xsize = 1100;
00129
00130
00131 tnfilestream fs ( file, tnstream::reading );
00132
00133 Surface s ( IMG_Load_RW ( SDL_RWFromStream( &fs ), 1));
00134 if ( !s.valid() )
00135 fatalError("could not read image " + file );
00136
00137 if ( s.GetPixelFormat().BitsPerPixel() == 8 )
00138 s.assignDefaultPalette();
00139
00140
00141 int depth = s.GetPixelFormat().BitsPerPixel();
00142
00143 for ( int i = 0; i < num; i++ ) {
00144 int x1 = (i % 10) * 100;
00145 int y1 = (i / 10) * 100;
00146 if ( depth > 8 && depth < 32 )
00147 depth = 32;
00148
00149 Surface s2 = Surface::createSurface(fieldsizex,fieldsizey, depth );
00150
00151 if ( s2.GetPixelFormat().BitsPerPixel() != 8 || s.GetPixelFormat().BitsPerPixel() != 8 ) {
00152
00153 bool colorKeyAllowed = false;
00154 static boost::regex pcx( ".*\\.pcx$");
00155 boost::smatch what;
00156 if( boost::regex_match( copytoLower(file) , what, pcx)) {
00157
00158 colorKeyAllowed = true;
00159 }
00160
00161 if ( s.GetPixelFormat().BitsPerPixel() == 32 ) {
00162 MegaBlitter<4,4,ColorTransform_None,ColorMerger_PlainOverwrite,SourcePixelSelector_Rectangle > blitter;
00163 blitter.setSrcRectangle(SDLmm::SRect(SPoint(x1,y1),fieldsizex,fieldsizey));
00164 blitter.blit( s, s2, SPoint(0,0) );
00165 } else {
00166 s2.Blit( s, SDLmm::SRect(SPoint(x1,y1),fieldsizex,fieldsizey), SPoint(0,0));
00167 }
00168 applyLegacyFieldMask(s2,0,0, colorKeyAllowed);
00169 if ( colorKeyAllowed )
00170 s2.ColorKey2AlphaChannel();
00171
00172 s2.detectColorKey();
00173 if ( depth != 32 || imageEmpty(s2))
00174 images.push_back( Surface() );
00175 else
00176 images.push_back ( s2 );
00177
00178 } else {
00179
00180 MegaBlitter<1,1,ColorTransform_None,ColorMerger_AlphaOverwrite,SourcePixelSelector_Rectangle > blitter;
00181 blitter.setSrcRectangle(SDLmm::SRect(SPoint(x1,y1),fieldsizex,fieldsizey));
00182 blitter.blit( s, s2, SPoint(0,0) );
00183 applyFieldMask(s2);
00184 s2.detectColorKey();
00185 images.push_back ( s2 );
00186 }
00187 }
00188 return images;
00189 }
00190
00191 Surface loadASCFieldImage ( const ASCString& file, bool applyFieldMaskToImage )
00192 {
00193 StringTokenizer st ( file, fileNameDelimitter );
00194 FileName fn = st.getNextToken();
00195 fn.toLower();
00196
00197 displayLogMessage ( 6, "loading file " + file + "\n" );
00198
00199 if ( fn.suffix() == "png" ) {
00200 SDLmm::Surface* s = NULL;
00201 do {
00202 tnfilestream fs ( fn, tnstream::reading );
00203 RWOPS_Handler rwo( SDL_RWFromStream( &fs ) );
00204 SDLmm::Surface s2 ( IMG_LoadPNG_RW ( rwo.Get() ));
00205 rwo.Close();
00206
00207 if ( !s )
00208 s = new SDLmm::Surface ( s2 );
00209 else {
00210 int res = s->Blit ( s2 );
00211 if ( res < 0 )
00212 warningMessage ( "ImageProperty::operation_eq - couldn't blit surface "+fn);
00213 }
00214
00215 fn = st.getNextToken();
00216 } while ( !fn.empty() );
00217 if ( s ) {
00218 Surface s3( *s );
00219 if ( applyFieldMaskToImage )
00220 applyFieldMask(s3,0,0,false);
00221
00222 delete s;
00223 return s3;
00224 } else
00225 return Surface();
00226
00227 } else
00228 if ( fn.suffix() == "pcx" ) {
00229 SDL_Surface* surface;
00230 {
00231 tnfilestream fs ( fn, tnstream::reading );
00232
00233 RWOPS_Handler rwo ( SDL_RWFromStream( &fs ));
00234 surface = IMG_LoadPCX_RW ( rwo.Get() );
00235 rwo.Close();
00236 }
00237
00238 if ( !surface )
00239 errorMessage( "error loading file " + fn );
00240
00241 Surface s ( surface );
00242
00243 if ( s.GetPixelFormat().BitsPerPixel() == 8)
00244 s.SetColorKey( SDL_SRCCOLORKEY, 255 );
00245
00246
00247
00248
00249
00250
00251 fn = st.getNextToken();
00252 while ( !fn.empty() ) {
00253 tnfilestream fs ( fn, tnstream::reading );
00254 RWOPS_Handler rwo( SDL_RWFromStream( &fs ) );
00255 SDLmm::Surface s2 ( IMG_LoadPNG_RW ( rwo.Get() ));
00256 rwo.Close();
00257 int res = s.Blit ( s2 );
00258 if ( res < 0 )
00259 warningMessage ( "ImageProperty::operation_eq - couldn't blit surface "+fn);
00260
00261 fn = st.getNextToken();
00262 }
00263
00264
00265 if ( applyFieldMaskToImage )
00266 if ( s.w() >= fieldsizex && s.h() >= fieldsizey )
00267 applyFieldMask(s,0,0,false);
00268
00269 return s;
00270 }
00271 throw ASCexception();
00272 }
00273
00274