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 avg += c[0] + c[1] + c[2];
00056 c += 4;
00057 }
00058 }
00059
00060 avg /= float(s.h() * s.w() * 3);
00061 } else
00062 avg = 150;
00063
00064 for ( int y = 0; y < s.h(); ++y ) {
00065 char* c = (char*) s.pixels();
00066 c += y * s.pitch();
00067 for ( int x = 0; x < s.w(); ++x ) {
00068 if ( c[3] != Surface::transparent ) {
00069 int v = (c[0] + c[1] + c[2]) / 3;
00070
00071 int nv = targetWhite + ( v - int(avg)) * (255-targetWhite) / 64;
00072 if ( nv > 255)
00073 nv = 255;
00074 if ( nv < 0 )
00075 nv = 0;
00076 c[0] = c[1] = c[2] = nv;
00077 }
00078 c += 4;
00079
00080 }
00081 }
00082 }
00083
00084 bool imageEmpty( const Surface& s )
00085 {
00086 bool allWhite = true;
00087 bool allTransparent = true;
00088 for ( int y = 0; y < s.h(); ++y ) {
00089 const char* c = (char*) s.pixels();
00090 c += y * s.pitch();
00091 for ( int x = 0; x < s.w(); ++x ) {
00092 if( c[3] != Surface::transparent )
00093 allTransparent = false;
00094
00095 int* i = (int*) c;
00096 if ( (*i & 0xffffff) != 0xffffff )
00097 allWhite = false;
00098
00099 c += 4;
00100 }
00101 if ( !allWhite && !allTransparent )
00102 return false;
00103 }
00104 return allWhite || allTransparent;
00105 }
00106
00107 vector<Surface> loadASCFieldImageArray ( const ASCString& file, int num )
00108 {
00109 vector<Surface> images;
00110
00111 int xsize;
00112 if ( num <= 10)
00113 xsize = (num+1)* 100;
00114 else
00115 xsize = 1100;
00116
00117
00118 tnfilestream fs ( file, tnstream::reading );
00119
00120 Surface s ( IMG_Load_RW ( SDL_RWFromStream( &fs ), 1));
00121 if ( !s.valid() )
00122 fatalError("could not read image " + file );
00123
00124 if ( s.GetPixelFormat().BitsPerPixel() == 8 )
00125 s.assignDefaultPalette();
00126
00127
00128 int depth = s.GetPixelFormat().BitsPerPixel();
00129
00130 for ( int i = 0; i < num; i++ ) {
00131 int x1 = (i % 10) * 100;
00132 int y1 = (i / 10) * 100;
00133 if ( depth > 8 && depth < 32 )
00134 depth = 32;
00135
00136 Surface s2 = Surface::createSurface(fieldsizex,fieldsizey, depth );
00137
00138 if ( s2.GetPixelFormat().BitsPerPixel() != 8 || s.GetPixelFormat().BitsPerPixel() != 8 ) {
00139
00140 bool colorKeyAllowed = false;
00141 static boost::regex pcx( ".*\\.pcx$");
00142 boost::smatch what;
00143 if( boost::regex_match( copytoLower(file) , what, pcx)) {
00144
00145 colorKeyAllowed = true;
00146 }
00147
00148 if ( s.GetPixelFormat().BitsPerPixel() == 32 ) {
00149 MegaBlitter<4,4,ColorTransform_None,ColorMerger_PlainOverwrite,SourcePixelSelector_Rectangle > blitter;
00150 blitter.setSrcRectangle(SDLmm::SRect(SPoint(x1,y1),fieldsizex,fieldsizey));
00151 blitter.blit( s, s2, SPoint(0,0) );
00152 } else {
00153 s2.Blit( s, SDLmm::SRect(SPoint(x1,y1),fieldsizex,fieldsizey), SPoint(0,0));
00154 }
00155 applyLegacyFieldMask(s2,0,0, colorKeyAllowed);
00156 if ( colorKeyAllowed )
00157 s2.ColorKey2AlphaChannel();
00158
00159 s2.detectColorKey();
00160 if ( depth != 32 || imageEmpty(s2))
00161 images.push_back( Surface() );
00162 else
00163 images.push_back ( s2 );
00164
00165 } else {
00166
00167 MegaBlitter<1,1,ColorTransform_None,ColorMerger_AlphaOverwrite,SourcePixelSelector_Rectangle > blitter;
00168 blitter.setSrcRectangle(SDLmm::SRect(SPoint(x1,y1),fieldsizex,fieldsizey));
00169 blitter.blit( s, s2, SPoint(0,0) );
00170 applyFieldMask(s2);
00171 s2.detectColorKey();
00172 images.push_back ( s2 );
00173 }
00174 }
00175 return images;
00176 }
00177
00178 Surface loadASCFieldImage ( const ASCString& file, bool applyFieldMaskToImage )
00179 {
00180 StringTokenizer st ( file, fileNameDelimitter );
00181 FileName fn = st.getNextToken();
00182 fn.toLower();
00183 if ( fn.suffix() == "png" ) {
00184 SDLmm::Surface* s = NULL;
00185 do {
00186 tnfilestream fs ( fn, tnstream::reading );
00187 RWOPS_Handler rwo( SDL_RWFromStream( &fs ) );
00188 SDLmm::Surface s2 ( IMG_LoadPNG_RW ( rwo.Get() ));
00189 rwo.Close();
00190
00191 if ( !s )
00192 s = new SDLmm::Surface ( s2 );
00193 else {
00194 int res = s->Blit ( s2 );
00195 if ( res < 0 )
00196 warning ( "ImageProperty::operation_eq - couldn't blit surface "+fn);
00197 }
00198
00199 fn = st.getNextToken();
00200 } while ( !fn.empty() );
00201 if ( s ) {
00202 Surface s3( *s );
00203 if ( applyFieldMaskToImage )
00204 applyFieldMask(s3,0,0,false);
00205
00206 delete s;
00207 return s3;
00208 } else
00209 return Surface();
00210
00211 } else
00212 if ( fn.suffix() == "pcx" ) {
00213 SDL_Surface* surface;
00214 {
00215 tnfilestream fs ( fn, tnstream::reading );
00216
00217 RWOPS_Handler rwo ( SDL_RWFromStream( &fs ));
00218 surface = IMG_LoadPCX_RW ( rwo.Get() );
00219 rwo.Close();
00220 }
00221
00222 if ( !surface )
00223 errorMessage( "error loading file " + fn );
00224
00225 Surface s ( surface );
00226
00227 if ( s.GetPixelFormat().BitsPerPixel() == 8)
00228 s.SetColorKey( SDL_SRCCOLORKEY, 255 );
00229
00230
00231
00232
00233
00234
00235 fn = st.getNextToken();
00236 while ( !fn.empty() ) {
00237 tnfilestream fs ( fn, tnstream::reading );
00238 RWOPS_Handler rwo( SDL_RWFromStream( &fs ) );
00239 SDLmm::Surface s2 ( IMG_LoadPNG_RW ( rwo.Get() ));
00240 rwo.Close();
00241 int res = s.Blit ( s2 );
00242 if ( res < 0 )
00243 warning ( "ImageProperty::operation_eq - couldn't blit surface "+fn);
00244
00245 fn = st.getNextToken();
00246 }
00247
00248
00249 if ( applyFieldMaskToImage )
00250 if ( s.w() >= fieldsizex && s.h() >= fieldsizey )
00251 applyFieldMask(s,0,0,false);
00252
00253 return s;
00254 }
00255 throw ASCexception();
00256 }
00257
00258