00001 #include "SdlArs.h"
00002
00003 namespace Ars
00004 {
00005 namespace Graf
00006 {
00007 static map<string,vector<SDL_Surface *> > imgContainer;
00008 static vector<string> idContainer;
00009
00010 void ResetImage( void )
00011 {
00012 for( vector<string>::iterator it = idContainer.begin() ; it != idContainer.end() ; ++it )
00013 {
00014 map<string,vector<SDL_Surface *> >::iterator pos = imgContainer.find( *it );
00015 if( pos != imgContainer.end() && !pos->second.empty() )
00016 {
00017 for( vector<SDL_Surface *>::iterator jt = pos->second.begin() ; jt != pos->second.end() ; ++jt )
00018 SDL_FreeSurface( *jt );
00019 pos->second.clear();
00020 }
00021 }
00022
00023 idContainer.clear();
00024 imgContainer.clear();
00025
00026 vector<SDL_Surface *> v0 , v1;
00027
00028 idContainer.push_back( "LIGHT" );
00029 v0.push_back( CreateLight( 20 , 243 , 250 , 3 ) );
00030 imgContainer["LIGHT"] = v0;
00031
00032 idContainer.push_back( "DARK" );
00033 v1.push_back( CreateDark( 20 , 128 , 128 , 128 ) );
00034 imgContainer["DARK"] = v1;
00035 }
00036
00037 int LoadImg( const string &aSection , const string &aId , string aCfgFile )
00038 {
00039 if( aCfgFile.empty() )
00040 aCfgFile = Cfg::GetCfg().GetCfgFile( "Paths" , "Images" );
00041 Cfg::Handler &h = Cfg::GetCfg( aCfgFile );
00042
00043 return LoadImg( h.GetCfgFile( aSection , aId ) );
00044 }
00045
00046 int LoadImg( const string &aFilename )
00047 {
00048 if( aFilename.empty() )
00049 return -1;
00050
00051 if( imgContainer.empty() )
00052 ResetImage();
00053
00054 vector<string>::iterator it = idContainer.begin();
00055 for( int i = 0 ; i < (int)idContainer.size() ; i++ , ++it )
00056 if( *it == aFilename )
00057 return i;
00058 idContainer.push_back( aFilename );
00059
00060 SDL_Surface *s = IMG_Load( aFilename.c_str() );
00061 if( s )
00062 {
00063 SDL_SetColorKey( s , SDL_SRCCOLORKEY | SDL_RLEACCEL , 0x00ff00ff );
00064 return AddImage( s , aFilename );
00065 }
00066 return -1;
00067 }
00068
00069 int AddImage( SDL_Surface *aImage , string aFilename )
00070 {
00071 if( aFilename.empty() )
00072 {
00073 char tmp[20];
00074 int i = 0;
00075 do
00076 {
00077 sprintf( tmp , "unique %d" , i++ );
00078 aFilename = tmp;
00079 }while( imgContainer.find( aFilename ) != imgContainer.end() );
00080 }
00081
00082 vector<SDL_Surface *> vs;
00083 vs.push_back( SDL_DisplayFormat( aImage ) );
00084 SDL_FreeSurface( aImage );
00085 imgContainer[aFilename] = vs;
00086
00087 if( HasImage( aFilename ) == -1 )
00088 idContainer.push_back( aFilename );
00089 return (int)(idContainer.size() - 1);
00090 }
00091
00092 int HasImage( string aFilename )
00093 {
00094 int cnt = 0;
00095 for( vector<string>::iterator pos = idContainer.begin() ; pos != idContainer.end() ; ++pos , cnt++ )
00096 if( (*pos) == aFilename )
00097 return cnt;
00098 return -1;
00099 }
00100
00101 SDL_Surface *CreateDark( const int radius , const int r , const int g , const int b )
00102 {
00103 Uint8 trans, alphamask;
00104 int range, addition;
00105 int xdist, ydist;
00106 Uint16 x, y;
00107 Uint16 skip;
00108 Uint32 pixel;
00109 SDL_Surface *light;
00110
00111 Uint32 *buf;
00112
00113
00114 alphamask = 0x000000FF;
00115 light = SDL_CreateRGBSurface(SDL_SWSURFACE, 2*radius, 2*radius, 32,
00116 0xFF000000, 0x00FF0000, 0x0000FF00, alphamask);
00117 if ( light == NULL ) {
00118 fprintf(stderr, "Couldn't create light: %s\n", SDL_GetError());
00119 return(NULL);
00120 }
00121
00122
00123 skip = light->pitch-(light->w*light->format->BytesPerPixel);
00124 buf = (Uint32 *)light->pixels;
00125
00126 pixel = SDL_MapRGBA(light->format, r , g , b , 0 );
00127 for ( y=0; y<light->h; ++y ) {
00128 for ( x=0; x<light->w; ++x ) {
00129 *buf++ = pixel;
00130 }
00131 buf += skip;
00132 }
00133
00134 buf = (Uint32 *)light->pixels;
00135 for ( y=0; y<light->h; ++y ) {
00136 for ( x=0; x<light->w; ++x ) {
00137
00138 xdist = x-(light->w/2);
00139 ydist = y-(light->h/2);
00140 range = (int)sqrt((float)(xdist*xdist+ydist*ydist));
00141
00142
00143 if ( range > radius ) {
00144 trans = alphamask;
00145 } else {
00146
00147 trans = (Uint8)((range*alphamask)/radius);
00148
00149
00150 addition = (alphamask)/8;
00151 if ( (int)trans+addition > alphamask ) {
00152 trans = alphamask;
00153 } else {
00154 trans += addition;
00155 }
00156 }
00157
00158 *buf++ |= (255-trans);
00159 }
00160 buf += skip;
00161 }
00162
00163 SDL_SetAlpha(light, SDL_SRCALPHA|SDL_RLEACCEL, 0);
00164
00165
00166 return(light);
00167 }
00168
00169
00170 SDL_Surface *CreateLight( const int radius , const int r , const int g , const int b )
00171 {
00172 Uint8 trans, alphamask;
00173 int range, addition;
00174 int xdist, ydist;
00175 Uint16 x, y;
00176 Uint16 skip;
00177 Uint32 pixel;
00178 SDL_Surface *light;
00179
00180 Uint32 *buf;
00181
00182
00183 alphamask = 0x000000FF;
00184 light = SDL_CreateRGBSurface(SDL_SWSURFACE, 2*radius, 2*radius, 32,
00185 0xFF000000, 0x00FF0000, 0x0000FF00, alphamask);
00186 if ( light == NULL ) {
00187 fprintf(stderr, "Couldn't create light: %s\n", SDL_GetError());
00188 return(NULL);
00189 }
00190
00191
00192 skip = light->pitch-(light->w*light->format->BytesPerPixel);
00193 buf = (Uint32 *)light->pixels;
00194
00195 pixel = SDL_MapRGBA(light->format, r , g , b , 0 );
00196 for ( y=0; y<light->h; ++y ) {
00197 for ( x=0; x<light->w; ++x ) {
00198 *buf++ = pixel;
00199 }
00200 buf += skip;
00201 }
00202
00203
00204 buf = (Uint32 *)light->pixels;
00205 for ( y=0; y<light->h; ++y ) {
00206 for ( x=0; x<light->w; ++x ) {
00207
00208 xdist = x-(light->w/2);
00209 ydist = y-(light->h/2);
00210 range = (int)sqrt((float)(xdist*xdist+ydist*ydist));
00211
00212
00213 if ( range > radius ) {
00214 trans = alphamask;
00215 } else {
00216
00217 trans = (Uint8)((range*alphamask)/radius);
00218
00219
00220 addition = (alphamask+1)/8;
00221 if ( (int)trans+addition > alphamask ) {
00222 trans = alphamask;
00223 } else {
00224 trans += addition;
00225 }
00226 }
00227
00228 *buf++ |= (255-trans);
00229 }
00230 buf += skip;
00231 }
00232
00233 SDL_SetAlpha(light, SDL_SRCALPHA|SDL_RLEACCEL, 0);
00234
00235
00236 return(light);
00237 }
00238
00239 SDL_Surface *Img( const int id , XRect *r )
00240 {
00241 if( id == -1 )
00242 return 0;
00243 string ss = idContainer[id];
00244 map<string,vector<SDL_Surface *> >::iterator pos = imgContainer.find( idContainer[id] );
00245 if( pos != imgContainer.end() && !pos->second.empty() )
00246 {
00247 SDL_Surface *ans = pos->second[0];
00248 if( r && ans )
00249 {
00250 if( (short)r->w < 1 )
00251 r->w = ans->w;
00252 if( (short)r->h < 1 )
00253 r->h = ans->h;
00254 }
00255 return ans;
00256 }
00257 return 0;
00258 }
00259
00260 SDL_Surface *ButtonImg( const int id , XRect &r , const bool smooth )
00261 {
00262 if( id == -1 )
00263 return 0;
00264 string ss = idContainer[id];
00265 map<string,vector<SDL_Surface *> >::iterator pos = imgContainer.find( idContainer[id] );
00266 if( pos != imgContainer.end() && !pos->second.empty() )
00267 {
00268 if( r.Right() < r.x || r.Right() > 32767 )
00269 r.SetRight( r.x + pos->second[0]->w );
00270
00271 if( r.Bottom() < r.y || r.Bottom() > 32767 )
00272 r.SetBottom( r.y + pos->second[0]->h );
00273
00274 if( r.Width() == pos->second[0]->w && r.Height() == pos->second[0]->h )
00275 return pos->second[0];
00276 int w = r.Width() - 1;
00277 int h = r.Height() - 1;
00278 for( vector<SDL_Surface *>::iterator jt = pos->second.begin() ; jt != pos->second.end() ; ++jt )
00279 {
00280 if( id == Light || id == Dark )
00281 {
00282 if( (*jt)->w == r.Width() && (*jt)->h == r.Height() )
00283 return (*jt);
00284 }
00285 else if( (*jt)->w == w && (*jt)->h == h )
00286 return (*jt);
00287 }
00288 double rw = (double)w / (double)pos->second[0]->w;
00289 double rh = (double)h / (double)pos->second[0]->h;
00290 SDL_Surface *s = pos->second[0];
00291
00292 if( id == Light )
00293 {
00294 if( r.Width() == r.Height() )
00295 pos->second.push_back( s = CreateLight( min( r.Width() , r.Height() ) / 2 , 250 , 250 , 0 ) );
00296 else
00297 return 0;
00298 }
00299 else if( id == Dark )
00300 {
00301 if( r.Width() == r.Height() )
00302 pos->second.push_back( s = CreateDark( min( r.Width() , r.Height() ) / 2 , 64, 64 , 64 ) );
00303 else
00304 return 0;
00305 }
00306 else
00307 {
00308 SDL_Surface *dst = NewSurface( r.Width() , r.Height() );
00309 Graf::SDL_StretchBlt( s , 0 , dst , 0 , smooth );
00310
00311 dst->flags &= ~SDL_SRCALPHA;
00312 pos->second.push_back( dst );
00313 s = dst;
00314 }
00315 return s;
00316 }
00317
00318 return 0;
00319 }
00320
00321 static map<const int , SDL_Cursor *> CursorContainer;
00322
00323 void ShowMouse( const bool aShow )
00324 {
00325 SDL_ShowCursor( aShow ? SDL_ENABLE : SDL_DISABLE );
00326 }
00327
00328 void ResetCursors( void )
00329 {
00330 SDL_ShowCursor( SDL_DISABLE );
00331 for( map<const int , SDL_Cursor *>::iterator it = CursorContainer.begin() ; it != CursorContainer.end() ; ++it )
00332 if( it->first )
00333 SDL_FreeCursor( it->second );
00334 CursorContainer.clear();
00335 }
00336
00337
00338 enum ECursorDataMask {
00339 O,
00340 M,
00341 D,
00342 X
00343 };
00344
00345 static SDL_Cursor *CreateCursor(const char DataIn[], int iDataLength, int iWidth, int iHeight, int iXHotSpot, int iYHotSpot )
00346 {
00347 int iDataSize = iWidth * iHeight / 8;
00348 Uint8* pData = new Uint8[iDataSize];
00349 Uint8* pMask = new Uint8[iDataSize];
00350 int i = -1;
00351
00352 for (int iRow = 0; iRow < iHeight; ++iRow)
00353 {
00354 for (int iCol = 0; iCol < iWidth; ++iCol)
00355 {
00356 int iIndex = iCol + iRow * iWidth;
00357 if (iIndex < iDataLength)
00358 {
00359 if (iCol % 8)
00360 {
00361 pData[i] <<= 1;
00362 pMask[i] <<= 1;
00363 }
00364 else
00365 {
00366 ++i;
00367 pData[i] = 0;
00368 pMask[i] = 0;
00369 }
00370 switch (DataIn[iIndex])
00371 {
00372 case X:
00373 pData[i] |= 0x01;
00374 pMask[i] |= 0x01;
00375 break;
00376 case D:
00377 pData[i] |= 0x01;
00378 break;
00379 case M:
00380 pMask[i] |= 0x01;
00381 break;
00382 case O:
00383 break;
00384 }
00385 }
00386 }
00387 }
00388
00389 return SDL_CreateCursor(pData, pMask, iWidth, iHeight, iXHotSpot, iYHotSpot);
00390 }
00391
00392 static int CurCursor = -1;
00393 const int GetCursorId( void ) { return max( 0 , CurCursor ); }
00394
00395 void SetMouse( const int aCursorId )
00396 {
00397 if( CurCursor == -1 )
00398 {
00399 CursorContainer[0] = SDL_GetCursor();
00400 CurCursor = 0;
00401 }
00402
00403 map<const int , SDL_Cursor *>::iterator at = CursorContainer.find( aCursorId );
00404 if( at == CursorContainer.end() )
00405 {
00406 switch( aCursorId )
00407 {
00408 case WGRES_POINTER_CURSOR:
00409 {
00410 char buf[] = {X,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,
00411 X,X,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,
00412 X,M,X,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,
00413 X,M,M,X,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,
00414 X,M,M,M,X,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,
00415 X,M,M,M,M,X,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,
00416 X,M,M,M,M,M,X,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,
00417 X,M,M,M,M,M,M,X,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,
00418 X,M,M,M,M,M,M,M,X,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,
00419 X,M,M,M,M,M,M,M,M,X,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,
00420 X,M,M,M,M,M,X,X,X,X,X,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,
00421 X,M,M,X,M,M,X,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,
00422 X,M,X,O,X,M,M,X,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,
00423 X,X,O,O,X,M,M,X,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,
00424 X,O,O,O,O,X,M,M,X,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,
00425 O,O,O,O,O,X,M,M,X,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,
00426 O,O,O,O,O,O,X,M,M,X,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,
00427 O,O,O,O,O,O,X,M,M,X,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,
00428 O,O,O,O,O,O,O,X,X,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,
00429 O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,
00430 O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,
00431 O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,
00432 O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,
00433 O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,
00434 O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,
00435 O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,
00436 O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,
00437 O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,
00438 O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,
00439 O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,
00440 O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,
00441 O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O};
00442 at = CursorContainer.insert( make_pair( aCursorId , CreateCursor(buf, sizeof(buf) / sizeof(char), 32, 32, 0, 0) ) ).first;
00443 break;
00444 }
00445 case WGRES_IBEAM_CURSOR:
00446 {
00447 char buf[] = {D,D,D,O,D,D,D,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,
00448 O,O,O,D,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,
00449 O,O,O,D,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,
00450 O,O,O,D,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,
00451 O,O,O,D,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,
00452 O,O,O,D,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,
00453 O,O,O,D,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,
00454 O,O,O,D,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,
00455 O,O,O,D,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,
00456 O,O,O,D,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,
00457 O,O,O,D,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,
00458 O,O,O,D,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,
00459 O,O,O,D,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,
00460 O,O,O,D,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,
00461 O,O,O,D,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,
00462 O,O,O,D,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,
00463 O,O,O,D,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,
00464 D,D,D,O,D,D,D,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,
00465 O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,
00466 O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,
00467 O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,
00468 O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,
00469 O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,
00470 O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,
00471 O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,
00472 O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,
00473 O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,
00474 O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,
00475 O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,
00476 O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,
00477 O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,
00478 O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O};
00479 at = CursorContainer.insert( make_pair( aCursorId , CreateCursor(buf, sizeof(buf) / sizeof(char), 32, 32, 3, 8) ) ).first;
00480 break;
00481 }
00482 case WGRES_WAIT_CURSOR:
00483 {
00484 char buf[] = {X,X,X,X,X,X,X,X,X,X,X,X,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,
00485 X,M,M,M,M,M,M,M,M,M,M,X,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,
00486 X,M,M,M,M,M,M,M,M,M,M,X,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,
00487 X,M,M,M,M,M,M,M,M,M,M,X,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,
00488 O,X,X,M,X,M,X,M,X,M,X,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,
00489 O,O,X,X,M,X,M,X,M,X,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,
00490 O,O,O,X,X,M,X,M,X,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,
00491 O,O,O,O,X,X,M,X,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,
00492 O,O,O,O,X,M,M,X,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,
00493 O,O,O,X,M,X,M,M,X,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,
00494 O,O,X,M,M,M,X,M,M,X,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,
00495 O,X,M,M,M,X,M,M,M,M,X,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,
00496 X,M,M,M,M,M,M,M,M,M,M,X,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,
00497 X,M,M,M,M,X,M,X,M,M,M,X,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,
00498 X,M,X,M,X,M,X,M,X,M,M,X,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,
00499 X,X,X,X,X,X,X,X,X,X,X,X,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,
00500 O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,
00501 O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,
00502 O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,
00503 O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,
00504 O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,
00505 O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,
00506 O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,
00507 O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,
00508 O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,
00509 O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,
00510 O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,
00511 O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,
00512 O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,
00513 O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,
00514 O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,
00515 O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O};
00516 at = CursorContainer.insert( make_pair( aCursorId , CreateCursor( buf, sizeof(buf) / sizeof(char), 32, 32, 0, 0) ) ).first;
00517 break;
00518 }
00519 }
00520 if( at == CursorContainer.end() )
00521 SDL_SetCursor( CursorContainer[0] );
00522 }
00523 SDL_SetCursor( at->second );
00524 }
00525
00526 typedef struct tColorRGBA {
00527 Uint8 r;
00528 Uint8 g;
00529 Uint8 b;
00530 Uint8 a;
00531 } tColorRGBA;
00532
00533 int SDL_StretchBlt( SDL_Surface *src , SDL_Rect *aSrcRect , SDL_Surface *dst , SDL_Rect *aDstRect , const bool smooth )
00534 {
00535 XRect srcRect( 0 , 0 , src->w , src->h );
00536 XRect dstRect( 0 , 0 , dst->w , dst->h );
00537
00538 if( aSrcRect )
00539 srcRect = *aSrcRect;
00540 if( aDstRect )
00541 dstRect = *aDstRect;
00542
00543 if( srcRect.Width() == dstRect.Width() && srcRect.Height() == dstRect.Height() )
00544 return SDL_BlitSurface( src , &srcRect , dst , &dstRect );
00545
00546 SDL_LockSurface( src );
00547 SDL_LockSurface( dst );
00548 int sx = (int) (65536.0 * (float) srcRect.Width() / (float) dstRect.Width());
00549 int sy = (int) (65536.0 * (float) srcRect.Height() / (float) dstRect.Height());
00550
00551 int *sax = new int[ (dstRect.Width() + 1) ];
00552 memset( sax , 0 , (dstRect.Width() + 1) * sizeof(int) );
00553 int *say = new int[ (dstRect.Height() + 1) ];
00554 memset( say , 0 , (dstRect.Height() + 1) * sizeof(int) );
00555
00556
00557 int csx = 0;
00558 int *csax = sax;
00559 for( int x = 0 ; x <= dstRect.Width() ; x++ )
00560 {
00561 *csax = csx;
00562 csax++;
00563 csx &= 0xffff;
00564 csx += sx;
00565 }
00566 int csy = 0;
00567 int *csay = say;
00568 for( int y = 0 ; y <= dstRect.Height(); y++ )
00569 {
00570 *csay = csy;
00571 csay++;
00572 csy &= 0xffff;
00573 csy += sy;
00574 }
00575
00576
00577 tColorRGBA *csp = (tColorRGBA *) src->pixels;
00578 tColorRGBA *dp = (tColorRGBA *) dst->pixels;
00579 int dgap = dst->pitch - dstRect.Width() * 4;
00580 int sgap = src->pitch - srcRect.Width() * 4;
00581
00582 csp = (tColorRGBA *) ((Uint8 *) csp + src->pitch * srcRect.y);
00583 csp += srcRect.x;
00584 dp = (tColorRGBA *) ((Uint8 *)dp + dst->pitch * dstRect.y);
00585 dp += dstRect.x;
00586 csay = say;
00587
00588
00589 if( smooth )
00590 {
00591
00592 int ex, ey, t1, t2, sstep;
00593 tColorRGBA *c00, *c01, *c10, *c11;
00594 for( y = 0 ; y < dstRect.Height() ; y++ )
00595 {
00596
00597 c00 = csp;
00598 c01 = csp;
00599 c01++;
00600 c10 = (tColorRGBA *) ((Uint8 *) csp + src->pitch);
00601 c11 = c10;
00602 c11++;
00603 csax = sax;
00604 for( x = 0 ; x < dstRect.Width() ; x++ )
00605 {
00606
00607 ex = (*csax & 0xffff);
00608 ey = (*csay & 0xffff);
00609 t1 = ((((c01->r - c00->r) * ex) >> 16) + c00->r) & 0xff;
00610 t2 = ((((c11->r - c10->r) * ex) >> 16) + c10->r) & 0xff;
00611 dp->r = (((t2 - t1) * ey) >> 16) + t1;
00612 t1 = ((((c01->g - c00->g) * ex) >> 16) + c00->g) & 0xff;
00613 t2 = ((((c11->g - c10->g) * ex) >> 16) + c10->g) & 0xff;
00614 dp->g = (((t2 - t1) * ey) >> 16) + t1;
00615 t1 = ((((c01->b - c00->b) * ex) >> 16) + c00->b) & 0xff;
00616 t2 = ((((c11->b - c10->b) * ex) >> 16) + c10->b) & 0xff;
00617 dp->b = (((t2 - t1) * ey) >> 16) + t1;
00618 t1 = ((((c01->a - c00->a) * ex) >> 16) + c00->a) & 0xff;
00619 t2 = ((((c11->a - c10->a) * ex) >> 16) + c10->a) & 0xff;
00620 dp->a = (((t2 - t1) * ey) >> 16) + t1;
00621
00622
00623 csax++;
00624 sstep = (*csax >> 16);
00625 c00 += sstep;
00626 c01 += sstep;
00627 c10 += sstep;
00628 c11 += sstep;
00629
00630
00631 dp++;
00632 }
00633
00634 csay++;
00635 csp = (tColorRGBA *) ((Uint8 *) csp + (*csay >> 16) * src->pitch);
00636
00637
00638 dp = (tColorRGBA *) ((Uint8 *) dp + dgap);
00639 }
00640 }
00641 else
00642 {
00643
00644 for( y = 0 ; y < dstRect.Height() ; y++ )
00645 {
00646 tColorRGBA *sp = csp;
00647
00648 csax = sax;
00649 for( x = 0 ; x < dstRect.Width() ; x++ )
00650 {
00651
00652 *dp = *sp;
00653
00654
00655 csax++;
00656 sp += (*csax >> 16);
00657
00658
00659 dp++;
00660 }
00661
00662 csay++;
00663 csp = (tColorRGBA *) ((Uint8 *) csp + (*csay >> 16) * src->pitch);
00664
00665
00666 dp = (tColorRGBA *) ((Uint8 *) dp + dgap);
00667 }
00668 }
00669 delete [] sax;
00670 delete [] say;
00671
00672
00673
00674 SDL_UnlockSurface( src );
00675 SDL_UnlockSurface( dst );
00676
00677 return 0;
00678 }
00679
00680 SDL_Surface *NewSurface( const int w , const int h , SDL_Surface *sfc )
00681 {
00682 SDL_Surface *ans;
00683
00684 if( sfc )
00685 {
00686 SDL_Surface *d = SDL_CreateRGBSurface( SDL_SWSURFACE , w , h , sfc->format->BitsPerPixel , sfc->format->Rmask , sfc->format->Gmask , sfc->format->Bmask , sfc->format->Amask );
00687 ans = SDL_DisplayFormat( d );
00688 SDL_FreeSurface( d );
00689 SDL_SetColorKey( ans , SDL_SRCCOLORKEY | SDL_RLEACCEL , sfc->format->colorkey );
00690 }
00691 else
00692 {
00693 SDL_Surface *d = SDL_CreateRGBSurface( SDL_SWSURFACE , w , h , 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000 );
00694 ans = SDL_DisplayFormat( d );
00695 SDL_FreeSurface( d );
00696 SDL_SetColorKey( ans , SDL_SRCCOLORKEY | SDL_RLEACCEL , 0x00ff00ff );
00697 }
00698 SDL_SetAlpha( ans , SDL_SRCALPHA , 255 );
00699
00700 return ans;
00701 }
00702
00703 }
00704 }