2009-05-20 13:08:56 +03:00
# include "../stdafx.h"
2007-06-06 21:26:28 +03:00
# include "SDL_Extensions.h"
2008-08-02 18:08:03 +03:00
# include "SDL_ttf.h"
2007-07-14 18:24:42 +03:00
# include "CGameInfo.h"
2007-06-25 17:55:45 +03:00
# include <iostream>
2007-07-14 18:24:42 +03:00
# include <utility>
# include <algorithm>
2007-08-29 15:18:31 +03:00
# include "CMessage.h"
2007-09-14 16:11:10 +03:00
# include <boost/algorithm/string.hpp>
2009-05-20 13:08:56 +03:00
# include "../hch/CDefHandler.h"
2008-03-04 15:59:34 +02:00
# include <map>
2009-05-20 13:08:56 +03:00
# include "Graphics.h"
2008-02-22 19:47:14 +02:00
2009-04-15 17:03:31 +03:00
/*
* SDL_Extensions . cpp , part of VCMI engine
*
* Authors : listed in file AUTHORS in main folder
*
* License : GNU General Public License v2 .0 or later
* Full text of license available in license . txt file , in main folder
*
*/
2007-09-30 19:16:00 +03:00
SDL_Surface * CSDL_Ext : : newSurface ( int w , int h , SDL_Surface * mod ) //creates new surface, with flags/format same as in surface given
{
return SDL_CreateRGBSurface ( mod - > flags , w , h , mod - > format - > BitsPerPixel , mod - > format - > Rmask , mod - > format - > Gmask , mod - > format - > Bmask , mod - > format - > Amask ) ;
}
SDL_Surface * CSDL_Ext : : copySurface ( SDL_Surface * mod ) //returns copy of given surface
{
2008-02-09 16:44:32 +02:00
//return SDL_DisplayFormat(mod);
return SDL_ConvertSurface ( mod , mod - > format , mod - > flags ) ;
2007-09-30 19:16:00 +03:00
}
2007-06-19 18:25:42 +03:00
bool isItIn ( const SDL_Rect * rect , int x , int y )
{
if ( ( x > rect - > x & & x < rect - > x + rect - > w ) & & ( y > rect - > y & & y < rect - > y + rect - > h ) )
return true ;
else return false ;
}
2009-02-08 17:39:26 +02:00
2007-07-23 15:13:33 +03:00
void blitAtWR ( SDL_Surface * src , int x , int y , SDL_Surface * dst )
{
SDL_Rect pom = genRect ( src - > h , src - > w , x , y ) ;
SDL_BlitSurface ( src , NULL , dst , & pom ) ;
SDL_UpdateRect ( dst , x , y , src - > w , src - > h ) ;
}
void blitAt ( SDL_Surface * src , int x , int y , SDL_Surface * dst )
2007-06-19 18:25:42 +03:00
{
2008-08-13 03:44:31 +03:00
if ( ! dst ) dst = screen ;
2007-07-11 13:27:42 +03:00
SDL_Rect pom = genRect ( src - > h , src - > w , x , y ) ;
SDL_BlitSurface ( src , NULL , dst , & pom ) ;
2007-06-19 18:25:42 +03:00
}
2008-01-24 00:15:33 +02:00
void blitAtWR ( SDL_Surface * src , SDL_Rect pos , SDL_Surface * dst )
{
blitAtWR ( src , pos . x , pos . y , dst ) ;
}
void blitAt ( SDL_Surface * src , SDL_Rect pos , SDL_Surface * dst )
{
blitAt ( src , pos . x , pos . y , dst ) ;
}
2007-06-13 17:02:43 +03:00
SDL_Color genRGB ( int r , int g , int b , int a = 0 )
{
SDL_Color ret ;
ret . b = b ;
ret . g = g ;
ret . r = r ;
ret . unused = a ;
return ret ;
}
2007-07-28 12:44:10 +03:00
void updateRect ( SDL_Rect * rect , SDL_Surface * scr )
2007-06-13 17:02:43 +03:00
{
SDL_UpdateRect ( scr , rect - > x , rect - > y , rect - > w , rect - > h ) ;
}
2008-09-25 17:09:31 +03:00
void CSDL_Ext : : printAtMiddleWB ( const std : : string & text , int x , int y , TTF_Font * font , int charpr , SDL_Color kolor , SDL_Surface * dst )
2007-08-24 11:27:32 +03:00
{
std : : vector < std : : string > * ws = CMessage : : breakText ( text , charpr ) ;
std : : vector < SDL_Surface * > wesu ;
wesu . resize ( ws - > size ( ) ) ;
2008-12-23 15:59:03 +02:00
for ( size_t i = 0 ; i < wesu . size ( ) ; + + i )
{
2007-08-24 11:27:32 +03:00
wesu [ i ] = TTF_RenderText_Blended ( font , ( * ws ) [ i ] . c_str ( ) , kolor ) ;
2008-12-23 15:59:03 +02:00
}
2007-08-24 11:27:32 +03:00
int tox = 0 , toy = 0 ;
2008-12-21 21:17:35 +02:00
for ( size_t i = 0 ; i < wesu . size ( ) ; + + i )
2007-08-24 11:27:32 +03:00
{
toy + = wesu [ i ] - > h ;
if ( tox < wesu [ i ] - > w )
tox = wesu [ i ] - > w ;
}
int evx , evy = y - ( toy / 2 ) ;
2008-12-21 21:17:35 +02:00
for ( size_t i = 0 ; i < wesu . size ( ) ; + + i )
2007-08-24 11:27:32 +03:00
{
evx = ( x - ( tox / 2 ) ) + ( ( tox - wesu [ i ] - > w ) / 2 ) ;
2007-12-22 20:04:34 +02:00
blitAt ( wesu [ i ] , evx , evy , dst ) ;
2007-08-24 11:27:32 +03:00
evy + = wesu [ i ] - > h ;
}
2008-12-21 21:17:35 +02:00
for ( size_t i = 0 ; i < wesu . size ( ) ; + + i )
2008-05-23 22:50:11 +03:00
SDL_FreeSurface ( wesu [ i ] ) ;
delete ws ;
}
2008-09-25 17:09:31 +03:00
void CSDL_Ext : : printAtWB ( const std : : string & text , int x , int y , TTF_Font * font , int charpr , SDL_Color kolor , SDL_Surface * dst )
2008-05-23 22:50:11 +03:00
{
std : : vector < std : : string > * ws = CMessage : : breakText ( text , charpr ) ;
std : : vector < SDL_Surface * > wesu ;
wesu . resize ( ws - > size ( ) ) ;
2008-12-21 21:17:35 +02:00
for ( size_t i = 0 ; i < wesu . size ( ) ; + + i )
2008-05-23 22:50:11 +03:00
wesu [ i ] = TTF_RenderText_Blended ( font , ( * ws ) [ i ] . c_str ( ) , kolor ) ;
int evy = y ;
2008-12-21 21:17:35 +02:00
for ( size_t i = 0 ; i < wesu . size ( ) ; + + i )
2008-05-23 22:50:11 +03:00
{
blitAt ( wesu [ i ] , x , evy , dst ) ;
evy + = wesu [ i ] - > h ;
}
2008-12-21 21:17:35 +02:00
for ( size_t i = 0 ; i < wesu . size ( ) ; + + i )
2007-08-24 11:27:32 +03:00
SDL_FreeSurface ( wesu [ i ] ) ;
delete ws ;
}
2008-09-25 17:09:31 +03:00
void CSDL_Ext : : printAtMiddle ( const std : : string & text , int x , int y , TTF_Font * font , SDL_Color kolor , SDL_Surface * dst , unsigned char quality , bool refresh )
2007-07-10 11:40:09 +03:00
{
2007-08-07 14:54:50 +03:00
if ( text . length ( ) = = 0 ) return ;
2007-07-10 11:40:09 +03:00
SDL_Surface * temp ;
switch ( quality )
{
case 0 :
temp = TTF_RenderText_Solid ( font , text . c_str ( ) , kolor ) ;
break ;
case 1 :
SDL_Color tem ;
tem . b = 0xff - kolor . b ;
tem . g = 0xff - kolor . g ;
tem . r = 0xff - kolor . r ;
tem . unused = 0xff - kolor . unused ;
temp = TTF_RenderText_Shaded ( font , text . c_str ( ) , kolor , tem ) ;
break ;
case 2 :
temp = TTF_RenderText_Blended ( font , text . c_str ( ) , kolor ) ;
break ;
default :
temp = TTF_RenderText_Blended ( font , text . c_str ( ) , kolor ) ;
break ;
}
SDL_BlitSurface ( temp , NULL , dst , & genRect ( temp - > h , temp - > w , x - ( temp - > w / 2 ) , y - ( temp - > h / 2 ) ) ) ;
2008-09-16 18:23:44 +03:00
if ( refresh )
SDL_UpdateRect ( dst , x - ( temp - > w / 2 ) , y - ( temp - > h / 2 ) , temp - > w , temp - > h ) ;
2007-07-10 11:40:09 +03:00
SDL_FreeSurface ( temp ) ;
}
2009-04-14 15:47:09 +03:00
void CSDL_Ext : : printAt ( const std : : string & text , int x , int y , TTF_Font * font , SDL_Color kolor , SDL_Surface * dst , unsigned char quality , bool refresh )
2009-04-03 18:55:26 +03:00
{
if ( text . length ( ) = = 0 )
return ;
SDL_Surface * temp ;
switch ( quality )
{
case 0 :
temp = TTF_RenderText_Solid ( font , text . c_str ( ) , kolor ) ;
break ;
case 1 :
SDL_Color tem ;
tem . b = 0xff - kolor . b ;
tem . g = 0xff - kolor . g ;
tem . r = 0xff - kolor . r ;
tem . unused = 0xff - kolor . unused ;
temp = TTF_RenderText_Shaded ( font , text . c_str ( ) , kolor , tem ) ;
break ;
case 2 :
temp = TTF_RenderText_Blended ( font , text . c_str ( ) , kolor ) ;
break ;
default :
temp = TTF_RenderText_Blended ( font , text . c_str ( ) , kolor ) ;
break ;
}
SDL_BlitSurface ( temp , NULL , dst , & genRect ( temp - > h , temp - > w , x , y ) ) ;
2009-04-14 15:47:09 +03:00
if ( refresh )
SDL_UpdateRect ( dst , x , y , temp - > w , temp - > h ) ;
2009-04-03 18:55:26 +03:00
SDL_FreeSurface ( temp ) ;
}
2009-04-14 15:47:09 +03:00
void CSDL_Ext : : printAtWR ( const std : : string & text , int x , int y , TTF_Font * font , SDL_Color kolor , SDL_Surface * dst , unsigned char quality )
2007-06-19 18:25:42 +03:00
{
2009-04-14 15:47:09 +03:00
printAt ( text , x , y , font , kolor , dst , quality , true ) ;
2008-01-12 13:32:40 +02:00
}
2009-04-14 15:47:09 +03:00
2008-09-25 17:09:31 +03:00
void CSDL_Ext : : printTo ( const std : : string & text , int x , int y , TTF_Font * font , SDL_Color kolor , SDL_Surface * dst , unsigned char quality )
2008-01-12 13:32:40 +02:00
{
if ( text . length ( ) = = 0 )
return ;
SDL_Surface * temp ;
switch ( quality )
{
case 0 :
temp = TTF_RenderText_Solid ( font , text . c_str ( ) , kolor ) ;
break ;
case 1 :
SDL_Color tem ;
tem . b = 0xff - kolor . b ;
tem . g = 0xff - kolor . g ;
tem . r = 0xff - kolor . r ;
tem . unused = 0xff - kolor . unused ;
temp = TTF_RenderText_Shaded ( font , text . c_str ( ) , kolor , tem ) ;
break ;
case 2 :
temp = TTF_RenderText_Blended ( font , text . c_str ( ) , kolor ) ;
break ;
default :
temp = TTF_RenderText_Blended ( font , text . c_str ( ) , kolor ) ;
break ;
}
SDL_BlitSurface ( temp , NULL , dst , & genRect ( temp - > h , temp - > w , x - temp - > w , y - temp - > h ) ) ;
2008-09-16 18:23:44 +03:00
SDL_UpdateRect ( dst , x - temp - > w , y - temp - > h , temp - > w , temp - > h ) ;
2008-01-12 13:32:40 +02:00
SDL_FreeSurface ( temp ) ;
2007-06-19 18:25:42 +03:00
}
2008-05-27 16:16:35 +03:00
2008-09-25 17:09:31 +03:00
void CSDL_Ext : : printToWR ( const std : : string & text , int x , int y , TTF_Font * font , SDL_Color kolor , SDL_Surface * dst , unsigned char quality )
2008-05-27 16:16:35 +03:00
{
if ( text . length ( ) = = 0 )
return ;
SDL_Surface * temp ;
switch ( quality )
{
case 0 :
temp = TTF_RenderText_Solid ( font , text . c_str ( ) , kolor ) ;
break ;
case 1 :
SDL_Color tem ;
tem . b = 0xff - kolor . b ;
tem . g = 0xff - kolor . g ;
tem . r = 0xff - kolor . r ;
tem . unused = 0xff - kolor . unused ;
temp = TTF_RenderText_Shaded ( font , text . c_str ( ) , kolor , tem ) ;
break ;
case 2 :
temp = TTF_RenderText_Blended ( font , text . c_str ( ) , kolor ) ;
break ;
default :
temp = TTF_RenderText_Blended ( font , text . c_str ( ) , kolor ) ;
break ;
}
SDL_BlitSurface ( temp , NULL , dst , & genRect ( temp - > h , temp - > w , x - temp - > w , y - temp - > h ) ) ;
SDL_FreeSurface ( temp ) ;
}
2008-11-28 14:11:31 +02:00
inline void CSDL_Ext : : SDL_PutPixel ( SDL_Surface * ekran , const int & x , const int & y , const Uint8 & R , const Uint8 & G , const Uint8 & B , Uint8 A )
2007-06-06 21:26:28 +03:00
{
2008-11-28 14:11:31 +02:00
Uint8 * p = ( Uint8 * ) ekran - > pixels + y * ekran - > pitch + x * ekran - > format - > BytesPerPixel ;
2007-11-20 19:52:22 +02:00
p [ 0 ] = B ;
p [ 1 ] = G ;
p [ 2 ] = R ;
2007-12-06 21:54:31 +02:00
if ( ekran - > format - > BytesPerPixel = = 4 )
p [ 3 ] = A ;
2008-11-28 14:11:31 +02:00
2007-11-20 19:52:22 +02:00
SDL_UpdateRect ( ekran , x , y , 1 , 1 ) ;
2007-06-06 21:26:28 +03:00
}
2009-05-17 05:43:36 +03:00
// Vertical flip
2008-11-28 14:11:31 +02:00
SDL_Surface * CSDL_Ext : : rotate01 ( SDL_Surface * toRot )
2007-06-06 21:26:28 +03:00
{
2008-02-06 15:50:40 +02:00
SDL_Surface * ret = SDL_ConvertSurface ( toRot , toRot - > format , toRot - > flags ) ;
2009-05-17 05:43:36 +03:00
const int bpl = ret - > pitch ;
const int bpp = ret - > format - > BytesPerPixel ;
for ( int i = 0 ; i < ret - > h ; i + + ) {
char * src = ( char * ) toRot - > pixels + i * bpl ;
char * dst = ( char * ) ret - > pixels + i * bpl ;
for ( int j = 0 ; j < ret - > w ; j + + ) {
for ( int k = 0 ; k < bpp ; k + + ) {
dst [ j * bpp + k ] = src [ ( ret - > w - j - 1 ) * bpp + k ] ;
2007-06-06 21:26:28 +03:00
}
}
}
2009-05-17 05:43:36 +03:00
2007-06-06 21:26:28 +03:00
return ret ;
}
2009-05-17 05:43:36 +03:00
// Horizontal flip
2007-06-07 04:22:06 +03:00
SDL_Surface * CSDL_Ext : : hFlip ( SDL_Surface * toRot )
{
2008-02-06 15:50:40 +02:00
SDL_Surface * ret = SDL_ConvertSurface ( toRot , toRot - > format , toRot - > flags ) ;
2009-05-17 05:43:36 +03:00
int bpl = ret - > pitch ;
for ( int i = 0 ; i < ret - > h ; i + + ) {
memcpy ( ( char * ) ret - > pixels + i * bpl , ( char * ) toRot - > pixels + ( ret - > h - i - 1 ) * bpl , bpl ) ;
2007-06-07 04:22:06 +03:00
}
2009-05-17 05:43:36 +03:00
2007-06-07 04:22:06 +03:00
return ret ;
} ;
2007-06-06 21:26:28 +03:00
///**************/
///Rotates toRot surface by 90 degrees left
///**************/
SDL_Surface * CSDL_Ext : : rotate02 ( SDL_Surface * toRot )
{
2008-02-06 15:50:40 +02:00
SDL_Surface * ret = SDL_ConvertSurface ( toRot , toRot - > format , toRot - > flags ) ;
2007-06-25 17:55:45 +03:00
//SDL_SetColorKey(ret, SDL_SRCCOLORKEY, toRot->format->colorkey);
2007-06-06 21:26:28 +03:00
for ( int i = 0 ; i < ret - > w ; + + i )
{
for ( int j = 0 ; j < ret - > h ; + + j )
{
{
Uint8 * p = ( Uint8 * ) toRot - > pixels + i * toRot - > pitch + j * toRot - > format - > BytesPerPixel ;
2008-08-02 18:08:03 +03:00
/*
2007-11-20 19:52:22 +02:00
# if(SDL_BYTEORDER == SDL_BIG_ENDIAN)
2008-11-28 14:11:31 +02:00
SDL_PutPixelWithoutRefresh ( ret , i , j , p [ 0 ] , p [ 1 ] , p [ 2 ] ) ;
2007-11-20 19:52:22 +02:00
# else
2008-08-02 18:08:03 +03:00
*/
2008-11-28 14:11:31 +02:00
SDL_PutPixelWithoutRefresh ( ret , i , j , p [ 2 ] , p [ 1 ] , p [ 0 ] ) ;
2008-08-02 18:08:03 +03:00
//#endif
2007-06-06 21:26:28 +03:00
}
}
}
return ret ;
}
///*************/
///Rotates toRot surface by 180 degrees
///*************/
SDL_Surface * CSDL_Ext : : rotate03 ( SDL_Surface * toRot )
{
2008-02-06 15:50:40 +02:00
SDL_Surface * ret = SDL_ConvertSurface ( toRot , toRot - > format , toRot - > flags ) ;
2007-06-25 17:55:45 +03:00
//SDL_SetColorKey(ret, SDL_SRCCOLORKEY, toRot->format->colorkey);
2007-06-26 15:38:58 +03:00
if ( ret - > format - > BytesPerPixel ! = 1 )
2007-06-06 21:26:28 +03:00
{
2007-06-26 15:38:58 +03:00
for ( int i = 0 ; i < ret - > w ; + + i )
2007-06-06 21:26:28 +03:00
{
2007-06-26 15:38:58 +03:00
for ( int j = 0 ; j < ret - > h ; + + j )
2007-06-06 21:26:28 +03:00
{
{
2007-06-26 15:38:58 +03:00
Uint8 * p = ( Uint8 * ) toRot - > pixels + ( ret - > h - j - 1 ) * toRot - > pitch + ( ret - > w - i - 1 ) * toRot - > format - > BytesPerPixel + 2 ;
2008-08-02 18:08:03 +03:00
/*
2007-11-20 19:52:22 +02:00
# if(SDL_BYTEORDER == SDL_BIG_ENDIAN)
2008-11-28 14:11:31 +02:00
SDL_PutPixelWithoutRefresh ( ret , i , j , p [ 0 ] , p [ 1 ] , p [ 2 ] , 0 ) ;
2007-11-20 19:52:22 +02:00
# else
2008-08-02 18:08:03 +03:00
*/
2008-11-28 14:11:31 +02:00
SDL_PutPixelWithoutRefresh ( ret , i , j , p [ 2 ] , p [ 1 ] , p [ 0 ] , 0 ) ;
2008-08-02 18:08:03 +03:00
//#endif
2007-06-06 21:26:28 +03:00
}
}
}
}
2007-06-26 15:38:58 +03:00
else
{
for ( int i = 0 ; i < ret - > w ; + + i )
{
for ( int j = 0 ; j < ret - > h ; + + j )
{
Uint8 * p = ( Uint8 * ) toRot - > pixels + ( ret - > h - j - 1 ) * toRot - > pitch + ( ret - > w - i - 1 ) * toRot - > format - > BytesPerPixel ;
( * ( ( Uint8 * ) ret - > pixels + j * ret - > pitch + i * ret - > format - > BytesPerPixel ) ) = * p ;
}
}
}
2007-06-06 21:26:28 +03:00
return ret ;
}
2008-02-06 15:50:40 +02:00
Uint32 CSDL_Ext : : SDL_GetPixel ( SDL_Surface * surface , const int & x , const int & y , bool colorByte )
2007-06-19 17:41:03 +03:00
{
int bpp = surface - > format - > BytesPerPixel ;
/* Here p is the address to the pixel we want to retrieve */
Uint8 * p = ( Uint8 * ) surface - > pixels + y * surface - > pitch + x * bpp ;
2008-12-23 15:59:03 +02:00
switch ( bpp )
{
2007-06-19 17:41:03 +03:00
case 1 :
2007-06-25 17:55:45 +03:00
if ( colorByte )
{
return colorToUint32 ( surface - > format - > palette - > colors + ( * p ) ) ;
}
else
return * p ;
2007-06-19 17:41:03 +03:00
case 2 :
return * ( Uint16 * ) p ;
case 3 :
2008-08-02 18:08:03 +03:00
/*
2007-11-20 19:52:22 +02:00
# if (SDL_BYTEORDER == SDL_BIG_ENDIAN)
2007-06-19 17:41:03 +03:00
return p [ 0 ] < < 16 | p [ 1 ] < < 8 | p [ 2 ] ;
2007-11-20 19:52:22 +02:00
# else
2008-08-02 18:08:03 +03:00
*/
2007-06-19 17:41:03 +03:00
return p [ 0 ] | p [ 1 ] < < 8 | p [ 2 ] < < 16 ;
2008-08-02 18:08:03 +03:00
//#endif
2007-06-19 17:41:03 +03:00
case 4 :
return * ( Uint32 * ) p ;
default :
2009-02-08 17:39:26 +02:00
return 0 ; // shouldn't happen, but avoids warnings
2007-06-19 17:41:03 +03:00
}
2007-06-25 17:55:45 +03:00
}
SDL_Surface * CSDL_Ext : : alphaTransform ( SDL_Surface * src )
{
Uint32 trans = SDL_MapRGBA ( src - > format , 0 , 255 , 255 , 255 ) ;
SDL_SetColorKey ( src , 0 , trans ) ;
src - > flags | = SDL_SRCALPHA ;
2008-08-02 18:08:03 +03:00
2007-10-24 22:54:35 +03:00
SDL_Color transp ;
transp . b = transp . g = transp . r = 0 ;
transp . unused = 255 ;
2008-08-02 18:08:03 +03:00
2007-06-25 17:55:45 +03:00
if ( src - > format - > BitsPerPixel = = 8 )
{
for ( int yy = 0 ; yy < src - > format - > palette - > ncolors ; + + yy )
{
SDL_Color cur = * ( src - > format - > palette - > colors + yy ) ;
2007-07-13 14:27:58 +03:00
//if(cur.r == 255 && cur.b == 255)
2008-02-12 19:40:01 +02:00
if ( yy = = 1 | | yy = = 2 | | yy = = 3 | | yy = = 4 | | yy = = 8 | | yy = = 9 )
2007-06-25 17:55:45 +03:00
{
SDL_Color shadow ;
shadow . b = shadow . g = shadow . r = 0 ;
2007-06-27 23:17:58 +03:00
switch ( cur . g ) //change this values; make diffrerent for objects and shadows (?)
{
case 0 :
2007-07-17 23:51:49 +03:00
shadow . unused = 128 ;
2007-06-27 23:17:58 +03:00
break ;
case 50 :
shadow . unused = 50 + 32 ;
break ;
case 100 :
shadow . unused = 100 + 64 ;
break ;
2008-02-07 20:45:22 +02:00
case 125 :
shadow . unused = 125 + 64 ;
break ;
2007-06-27 23:17:58 +03:00
case 128 :
shadow . unused = 128 + 64 ;
break ;
case 150 :
shadow . unused = 150 + 64 ;
break ;
default :
shadow . unused = 255 ;
break ;
}
2007-06-25 17:55:45 +03:00
SDL_SetColors ( src , & shadow , yy , 1 ) ;
}
2007-07-13 14:27:58 +03:00
if ( yy = = 0 | | ( cur . r = = 255 & & cur . g = = 0 & & cur . b = = 0 ) )
2007-06-25 17:55:45 +03:00
{
SDL_SetColors ( src , & transp , yy , 1 ) ;
}
}
}
return src ;
}
2008-11-30 02:15:38 +02:00
// <=>
2009-03-26 19:55:10 +02:00
void prepareOutRect ( SDL_Rect & dst , const SDL_Rect * dstRect , const SDL_Rect * clip_rect )
{
dst . x = std : : max ( dstRect - > x , clip_rect - > x ) ;
dst . y = std : : max ( dstRect - > y , clip_rect - > y ) ;
dst . w = std : : max ( 0 , std : : min ( dstRect - > w - ( dst . x - dstRect - > x ) , clip_rect - > x + clip_rect - > w - dst . x ) ) ;
dst . h = std : : max ( 0 , std : : min ( dstRect - > h - ( dst . y - dstRect - > y ) , clip_rect - > y + clip_rect - > h - dst . y ) ) ;
}
2008-11-30 02:15:38 +02:00
void CSDL_Ext : : blitWithRotate1 ( SDL_Surface * src , SDL_Rect * srcRect , SDL_Surface * dst , SDL_Rect * dstRect ) //srcRect is not used, works with 8bpp sources and 24bpp dests
{
Uint8 * dp , * sp = ( Uint8 * ) src - > pixels ;
for ( int i = 0 ; i < dstRect - > h ; i + + )
{
2009-01-09 15:03:47 +02:00
sp + = src - > w - dstRect - > w ;
2008-11-30 02:15:38 +02:00
dp = ( Uint8 * ) dst - > pixels + ( i + dstRect - > y ) * dst - > pitch + ( dstRect - > x + dstRect - > w ) * dst - > format - > BytesPerPixel ;
for ( int j = 0 ; j < dstRect - > w ; j + + , sp + + )
{
const SDL_Color * const color = src - > format - > palette - > colors + ( * sp ) ;
2009-05-17 05:35:28 +03:00
if ( dst - > format - > BytesPerPixel = = 4 )
* ( - - dp ) = 0 ;
2008-11-30 02:15:38 +02:00
* ( - - dp ) = color - > r ;
* ( - - dp ) = color - > g ;
* ( - - dp ) = color - > b ;
}
}
}
2009-01-09 15:03:47 +02:00
void CSDL_Ext : : blitWithRotate1clip ( SDL_Surface * src , SDL_Rect * srcRect , SDL_Surface * dst , SDL_Rect * dstRect ) //srcRect is not used, works with 8bpp sources and 24bpp dests
{
2009-03-26 19:55:10 +02:00
SDL_Rect realDest ;
prepareOutRect ( realDest , dstRect , & dst - > clip_rect ) ;
blitWithRotate1 ( src , srcRect , dst , & realDest ) ;
2009-01-09 15:03:47 +02:00
}
2008-11-30 02:15:38 +02:00
void CSDL_Ext : : blitWithRotate2 ( SDL_Surface * src , SDL_Rect * srcRect , SDL_Surface * dst , SDL_Rect * dstRect ) //srcRect is not used, works with 8bpp sources and 24bpp dests
{
Uint8 * dp , * sp = ( Uint8 * ) src - > pixels ;
for ( int i = 0 ; i < dstRect - > h ; i + + )
{
dp = ( Uint8 * ) dst - > pixels + ( dstRect - > y + dstRect - > h - 1 - i ) * dst - > pitch + dstRect - > x * dst - > format - > BytesPerPixel ;
for ( int j = 0 ; j < dstRect - > w ; j + + , sp + + )
{
const SDL_Color * const color = src - > format - > palette - > colors + ( * sp ) ;
* ( dp + + ) = color - > b ;
* ( dp + + ) = color - > g ;
* ( dp + + ) = color - > r ;
2009-05-17 05:35:28 +03:00
if ( dst - > format - > BytesPerPixel = = 4 )
* ( dp + + ) = 0 ;
2008-11-30 02:15:38 +02:00
}
2009-01-09 15:03:47 +02:00
sp + = src - > w - dstRect - > w ;
}
}
void CSDL_Ext : : blitWithRotate2clip ( SDL_Surface * src , SDL_Rect * srcRect , SDL_Surface * dst , SDL_Rect * dstRect ) //srcRect is not used, works with 8bpp sources and 24bpp dests
{
2009-03-26 19:55:10 +02:00
SDL_Rect realDest ;
prepareOutRect ( realDest , dstRect , & dst - > clip_rect ) ;
blitWithRotate2 ( src , srcRect , dst , & realDest ) ;
2008-11-30 02:15:38 +02:00
}
void CSDL_Ext : : blitWithRotate3 ( SDL_Surface * src , SDL_Rect * srcRect , SDL_Surface * dst , SDL_Rect * dstRect ) //srcRect is not used, works with 8bpp sources and 24bpp dests
{
Uint8 * dp , * sp = ( Uint8 * ) src - > pixels ;
for ( int i = 0 ; i < dstRect - > h ; i + + )
{
2009-01-09 15:03:47 +02:00
sp + = src - > w - dstRect - > w ;
2008-11-30 02:15:38 +02:00
dp = ( Uint8 * ) dst - > pixels + ( dstRect - > y + dstRect - > h - 1 - i ) * dst - > pitch + ( dstRect - > x + dstRect - > w ) * dst - > format - > BytesPerPixel ;
for ( int j = 0 ; j < dstRect - > w ; j + + , sp + + )
{
const SDL_Color * const color = src - > format - > palette - > colors + ( * sp ) ;
2009-05-17 05:35:28 +03:00
if ( dst - > format - > BytesPerPixel = = 4 )
* ( - - dp ) = 0 ;
2008-11-30 02:15:38 +02:00
* ( - - dp ) = color - > r ;
* ( - - dp ) = color - > g ;
* ( - - dp ) = color - > b ;
}
}
}
2007-06-25 17:55:45 +03:00
2009-01-09 15:03:47 +02:00
void CSDL_Ext : : blitWithRotate3clip ( SDL_Surface * src , SDL_Rect * srcRect , SDL_Surface * dst , SDL_Rect * dstRect ) //srcRect is not used, works with 8bpp sources and 24bpp dests
{
2009-03-26 19:55:10 +02:00
SDL_Rect realDest ;
prepareOutRect ( realDest , dstRect , & dst - > clip_rect ) ;
blitWithRotate3 ( src , srcRect , dst , & realDest ) ;
2009-01-09 15:03:47 +02:00
}
2008-02-10 19:44:51 +02:00
int CSDL_Ext : : blit8bppAlphaTo24bpp ( SDL_Surface * src , SDL_Rect * srcRect , SDL_Surface * dst , SDL_Rect * dstRect )
2008-02-09 16:44:32 +02:00
{
if ( src & & src - > format - > BytesPerPixel = = 1 & & dst & & ( dst - > format - > BytesPerPixel = = 3 | | dst - > format - > BytesPerPixel = = 4 ) ) //everything's ok
{
2008-02-10 19:44:51 +02:00
SDL_Rect fulldst ;
int srcx , srcy , w , h ;
2008-02-09 16:44:32 +02:00
2008-02-10 19:44:51 +02:00
/* Make sure the surfaces aren't locked */
2008-12-23 15:59:03 +02:00
if ( ! src | | ! dst )
{
2008-02-10 19:44:51 +02:00
SDL_SetError ( " SDL_UpperBlit: passed a NULL surface " ) ;
return ( - 1 ) ;
}
2008-12-23 15:59:03 +02:00
if ( src - > locked | | dst - > locked )
{
2008-02-10 19:44:51 +02:00
SDL_SetError ( " Surfaces must not be locked during blit " ) ;
return ( - 1 ) ;
}
2008-02-09 16:44:32 +02:00
2008-02-10 19:44:51 +02:00
/* If the destination rectangle is NULL, use the entire dest surface */
2008-12-23 15:59:03 +02:00
if ( dstRect = = NULL )
{
fulldst . x = fulldst . y = 0 ;
2008-02-10 19:44:51 +02:00
dstRect = & fulldst ;
2008-02-09 16:44:32 +02:00
}
2008-02-10 19:44:51 +02:00
/* clip the source rectangle to the source surface */
2009-02-08 17:39:26 +02:00
if ( srcRect )
2008-11-30 02:15:38 +02:00
{
int maxw , maxh ;
2008-08-02 18:08:03 +03:00
2008-02-10 19:44:51 +02:00
srcx = srcRect - > x ;
w = srcRect - > w ;
2008-12-23 15:59:03 +02:00
if ( srcx < 0 )
{
2008-02-10 19:44:51 +02:00
w + = srcx ;
dstRect - > x - = srcx ;
srcx = 0 ;
2008-02-09 16:44:32 +02:00
}
2008-02-10 19:44:51 +02:00
maxw = src - > w - srcx ;
if ( maxw < w )
w = maxw ;
srcy = srcRect - > y ;
h = srcRect - > h ;
2008-12-23 15:59:03 +02:00
if ( srcy < 0 )
{
2008-02-10 19:44:51 +02:00
h + = srcy ;
dstRect - > y - = srcy ;
srcy = 0 ;
2008-02-09 16:44:32 +02:00
}
2008-02-10 19:44:51 +02:00
maxh = src - > h - srcy ;
if ( maxh < h )
h = maxh ;
2008-08-02 18:08:03 +03:00
2009-02-08 17:39:26 +02:00
}
else
2008-11-30 02:15:38 +02:00
{
2008-02-10 19:44:51 +02:00
srcx = srcy = 0 ;
w = src - > w ;
h = src - > h ;
2008-02-09 16:44:32 +02:00
}
2008-02-10 19:44:51 +02:00
/* clip the destination rectangle against the clip rectangle */
2008-02-09 16:44:32 +02:00
{
2008-02-10 19:44:51 +02:00
SDL_Rect * clip = & dst - > clip_rect ;
int dx , dy ;
dx = clip - > x - dstRect - > x ;
2008-12-23 15:59:03 +02:00
if ( dx > 0 )
{
2008-02-10 19:44:51 +02:00
w - = dx ;
dstRect - > x + = dx ;
srcx + = dx ;
}
dx = dstRect - > x + w - clip - > x - clip - > w ;
if ( dx > 0 )
w - = dx ;
dy = clip - > y - dstRect - > y ;
2008-12-23 15:59:03 +02:00
if ( dy > 0 )
{
2008-02-10 19:44:51 +02:00
h - = dy ;
dstRect - > y + = dy ;
srcy + = dy ;
}
dy = dstRect - > y + h - clip - > y - clip - > h ;
if ( dy > 0 )
h - = dy ;
2008-02-09 16:44:32 +02:00
}
2008-02-10 19:44:51 +02:00
if ( w > 0 & & h > 0 )
2008-02-09 16:44:32 +02:00
{
2009-05-23 23:13:09 +03:00
dstRect - > w = w ;
dstRect - > h = h ;
2008-02-09 16:44:32 +02:00
2008-08-07 15:29:53 +03:00
if ( SDL_LockSurface ( dst ) )
return - 1 ; //if we cannot lock the surface
2009-05-23 23:13:09 +03:00
const int bpp = dst - > format - > BytesPerPixel ;
const SDL_Color * colors = src - > format - > palette - > colors ;
Uint8 * colory = ( Uint8 * ) src - > pixels + srcy * src - > pitch + srcx ;
Uint8 * py = ( Uint8 * ) dst - > pixels + dstRect - > y * dst - > pitch + dstRect - > x * bpp ;
2008-02-10 19:44:51 +02:00
if ( dst - > format - > Rshift = = 0 ) //like in most surfaces
{
2009-05-23 23:13:09 +03:00
for ( int y = 0 ; y < h ; y + + , colory + = src - > pitch , py + = dst - > pitch )
2008-02-10 19:44:51 +02:00
{
2009-05-23 23:13:09 +03:00
Uint8 * color = colory ;
Uint8 * p = py ;
for ( int x = 0 ; x < w ; + + x , color + + , p + = bpp )
2008-02-10 19:44:51 +02:00
{
2009-05-23 23:13:09 +03:00
const SDL_Color tbc = colors [ * color ] ; //color to blit
2008-03-04 15:59:34 +02:00
2008-08-02 18:08:03 +03:00
// According analyze, the values of tbc.unused are fixed,
2008-03-04 15:59:34 +02:00
// and the approximate ratios are as following:
//
// tbc.unused numbers
2008-08-02 18:08:03 +03:00
// 192 2679
2008-03-04 15:59:34 +02:00
// 164 326907
// 82 705590
// 214 1292625
// 128 4842923
// 0 72138078
// 255 77547326
//
// By making use of such characteristic, we may implement a
// very fast algorithm for heroes3 without loose much quality.
2009-05-23 23:13:09 +03:00
switch ( tbc . unused )
2008-03-04 15:59:34 +02:00
{
case 255 :
break ;
2008-03-03 12:52:32 +02:00
case 0 :
2008-09-03 13:52:07 +03:00
p [ 0 ] = tbc . r ;
p [ 1 ] = tbc . g ;
p [ 2 ] = tbc . b ;
2008-03-03 12:52:32 +02:00
break ;
case 128 : // optimized
2008-09-03 13:52:07 +03:00
p [ 0 ] = ( ( Uint16 ) tbc . r + ( Uint16 ) p [ 0 ] ) > > 1 ;
p [ 1 ] = ( ( Uint16 ) tbc . g + ( Uint16 ) p [ 1 ] ) > > 1 ;
p [ 2 ] = ( ( Uint16 ) tbc . b + ( Uint16 ) p [ 2 ] ) > > 1 ;
2008-03-03 12:52:32 +02:00
break ;
default :
2009-05-23 23:13:09 +03:00
p [ 0 ] = ( ( ( ( Uint32 ) p [ 0 ] - ( Uint32 ) tbc . r ) * ( Uint32 ) tbc . unused ) > > 8 + ( Uint32 ) tbc . r ) ;
p [ 1 ] = ( ( ( ( Uint32 ) p [ 1 ] - ( Uint32 ) tbc . g ) * ( Uint32 ) tbc . unused ) > > 8 + ( Uint32 ) tbc . g ) ;
p [ 2 ] = ( ( ( ( Uint32 ) p [ 2 ] - ( Uint32 ) tbc . b ) * ( Uint32 ) tbc . unused ) > > 8 + ( Uint32 ) tbc . b ) ;
2008-08-02 18:08:03 +03:00
//p[0] = ((Uint32)tbc.unused*(Uint32)p[0] + (Uint32)tbc.r*(Uint32)(255-tbc.unused))>>8; //red
//p[1] = ((Uint32)tbc.unused*(Uint32)p[1] + (Uint32)tbc.g*(Uint32)(255-tbc.unused))>>8; //green
//p[2] = ((Uint32)tbc.unused*(Uint32)p[2] + (Uint32)tbc.b*(Uint32)(255-tbc.unused))>>8; //blue
2008-03-03 12:52:32 +02:00
break ;
}
2008-02-10 19:44:51 +02:00
}
}
}
else if ( dst - > format - > Rshift = = 16 ) //such as screen
2008-02-09 16:44:32 +02:00
{
2009-05-23 23:13:09 +03:00
for ( int y = 0 ; y < h ; y + + , colory + = src - > pitch , py + = dst - > pitch )
2008-02-10 19:44:51 +02:00
{
2009-05-23 23:13:09 +03:00
Uint8 * color = colory ;
Uint8 * p = py ;
for ( int x = 0 ; x < w ; x + + , color + + , p + = bpp )
2008-02-10 19:44:51 +02:00
{
2009-05-23 23:13:09 +03:00
const SDL_Color tbc = colors [ * color ] ; //color to blit
2008-08-02 18:08:03 +03:00
2009-05-23 23:13:09 +03:00
switch ( tbc . unused )
2008-03-04 15:59:34 +02:00
{
case 255 :
break ;
2008-03-03 12:52:32 +02:00
case 0 :
2008-09-03 13:52:07 +03:00
p [ 0 ] = tbc . b ;
2009-05-23 23:13:09 +03:00
p [ 1 ] = tbc . g ;
p [ 2 ] = tbc . r ;
2008-03-03 12:52:32 +02:00
break ;
case 128 : // optimized
2008-09-03 13:52:07 +03:00
p [ 0 ] = ( ( Uint16 ) tbc . b + ( Uint16 ) p [ 0 ] ) > > 1 ;
2009-05-23 23:13:09 +03:00
p [ 1 ] = ( ( Uint16 ) tbc . g + ( Uint16 ) p [ 1 ] ) > > 1 ;
p [ 2 ] = ( ( Uint16 ) tbc . r + ( Uint16 ) p [ 2 ] ) > > 1 ;
2008-03-03 12:52:32 +02:00
break ;
default :
2009-05-23 23:13:09 +03:00
p [ 0 ] = ( ( ( ( Uint32 ) p [ 0 ] - ( Uint32 ) tbc . b ) * ( Uint32 ) tbc . unused ) > > 8 + ( Uint32 ) tbc . b ) ;
p [ 1 ] = ( ( ( ( Uint32 ) p [ 1 ] - ( Uint32 ) tbc . g ) * ( Uint32 ) tbc . unused ) > > 8 + ( Uint32 ) tbc . g ) ;
p [ 2 ] = ( ( ( ( Uint32 ) p [ 2 ] - ( Uint32 ) tbc . r ) * ( Uint32 ) tbc . unused ) > > 8 + ( Uint32 ) tbc . r ) ;
2008-08-02 18:08:03 +03:00
//p[2] = ((Uint32)tbc.unused*(Uint32)p[2] + (Uint32)tbc.r*(Uint32)(255-tbc.unused))>>8; //red
//p[1] = ((Uint32)tbc.unused*(Uint32)p[1] + (Uint32)tbc.g*(Uint32)(255-tbc.unused))>>8; //green
//p[0] = ((Uint32)tbc.unused*(Uint32)p[0] + (Uint32)tbc.b*(Uint32)(255-tbc.unused))>>8; //blue
2008-03-03 12:52:32 +02:00
break ;
}
2008-02-10 19:44:51 +02:00
}
}
2008-02-09 16:44:32 +02:00
}
2008-08-07 15:29:53 +03:00
SDL_UnlockSurface ( dst ) ;
2008-02-09 16:44:32 +02:00
}
}
2008-02-10 19:44:51 +02:00
return 0 ;
2007-06-27 23:17:58 +03:00
}
2007-06-25 17:55:45 +03:00
Uint32 CSDL_Ext : : colorToUint32 ( const SDL_Color * color )
{
Uint32 ret = 0 ;
ret + = color - > unused ;
2008-01-30 16:19:35 +02:00
ret < < = 8 ; //*=256
2007-06-25 17:55:45 +03:00
ret + = color - > b ;
2008-01-30 16:19:35 +02:00
ret < < = 8 ; //*=256
2007-06-25 17:55:45 +03:00
ret + = color - > g ;
2008-01-30 16:19:35 +02:00
ret < < = 8 ; //*=256
2007-06-25 17:55:45 +03:00
ret + = color - > r ;
return ret ;
}
2007-07-12 14:41:31 +03:00
void CSDL_Ext : : update ( SDL_Surface * what )
{
2007-08-21 16:48:18 +03:00
if ( what )
SDL_UpdateRect ( what , 0 , 0 , what - > w , what - > h ) ;
2007-07-12 14:41:31 +03:00
}
2008-04-04 20:30:53 +03:00
void CSDL_Ext : : drawBorder ( SDL_Surface * sur , int x , int y , int w , int h , int3 color )
{
for ( int i = 0 ; i < w ; i + + )
{
2008-11-28 14:11:31 +02:00
SDL_PutPixelWithoutRefresh ( sur , x + i , y , color . x , color . y , color . z ) ;
SDL_PutPixelWithoutRefresh ( sur , x + i , y + h - 1 , color . x , color . y , color . z ) ;
2008-04-04 20:30:53 +03:00
}
for ( int i = 0 ; i < h ; i + + )
{
2008-11-28 14:11:31 +02:00
SDL_PutPixelWithoutRefresh ( sur , x , y + i , color . x , color . y , color . z ) ;
SDL_PutPixelWithoutRefresh ( sur , x + w - 1 , y + i , color . x , color . y , color . z ) ;
2008-04-04 20:30:53 +03:00
}
}
2007-10-07 19:01:53 +03:00
void CSDL_Ext : : setPlayerColor ( SDL_Surface * sur , unsigned char player )
2007-07-16 13:03:54 +03:00
{
2007-10-07 19:01:53 +03:00
if ( player = = 254 )
return ;
2007-07-16 13:03:54 +03:00
if ( sur - > format - > BitsPerPixel = = 8 )
{
2008-08-02 18:08:03 +03:00
if ( player ! = 255 )
2008-06-30 03:06:41 +03:00
* ( sur - > format - > palette - > colors + 5 ) = graphics - > playerColors [ player ] ;
2007-07-16 13:03:54 +03:00
else
2008-06-30 03:06:41 +03:00
* ( sur - > format - > palette - > colors + 5 ) = * graphics - > neutralColor ;
2007-07-16 13:03:54 +03:00
}
2007-08-06 07:03:34 +03:00
}
int readNormalNr ( std : : istream & in , int bytCon )
{
int ret = 0 ;
int amp = 1 ;
unsigned char byte ;
if ( in . good ( ) )
{
for ( int i = 0 ; i < bytCon ; i + + )
{
in . read ( ( char * ) & byte , 1 ) ;
ret + = byte * amp ;
2008-01-30 16:19:35 +02:00
amp < < = 8 ;
2007-08-06 07:03:34 +03:00
}
}
else return - 1 ;
return ret ;
}
2007-08-17 20:42:21 +03:00
2007-09-14 16:11:10 +03:00
std : : string CSDL_Ext : : processStr ( std : : string str , std : : vector < std : : string > & tor )
{
2008-12-21 21:17:35 +02:00
for ( size_t i = 0 ; ( i < tor . size ( ) ) & & ( boost : : find_first ( str , " %s " ) ) ; + + i )
2007-09-14 16:11:10 +03:00
{
boost : : replace_first ( str , " %s " , tor [ i ] ) ;
}
return str ;
2008-02-06 15:50:40 +02:00
}
SDL_Surface * CSDL_Ext : : std32bppSurface = NULL ;