SurfaceClass

SurfaceClass

Widows version:

// UVi Soft ( 2008 )
// Long Fei ( lf426 ), E-mail: [email protected]
// Laboratory of ZaiBieLiunNian
// http://www.cppblog.com/lf426/

// FileName: SurfaceClass.hpp
// For Windows only

#ifndef SURFACE_CLASS_HPP
#define  SURFACE_CLASS_HPP

#include 
< iostream >
#include 
< string >
#include 
" SDL/SDL.h "
#include 
" SDL/SDL_image.h "
#include 
" SDL/SDL_ttf.h "
// Windows only
#include  " SDL_render_Chinese.h "

class  ScreenSurface
{
private :
    
// number of screen, make sure there is only ONE screen
     static   int  screenNum;
    
// size & bpp  of screen
     int  width;
    
int  height;
    
int  bpp;
    
// common flags:SDL_SWSURFACE, SDL_HWSURFACE, SDL_DOUBLEBUF, SDL_FULLSCREEN
    
// more:  http://www.libsdl.org/cgi/docwiki.cgi/SDL_5fSetVideoMode
    Uint32 flags;
    
// other attribute
    SDL_Surface *  pScreen;
    std::
string  windowName;
public :
    
// construct & deconstruct
    ScreenSurface();
    ScreenSurface(
int  w,  int  h,  const  std:: string &  window_name  =   " NULL " int  b  =   0 , Uint32 f  =   0 );
    
~ ScreenSurface();
    
// screen's point
    SDL_Surface *  point()  const ;
    
// flip the screen
     void  flip()  const ;
    
// fill the screen with some color, default is black.
     void  fillColor(Uint8 r  =   0 , Uint8 g  =   0 , Uint8 b  =   0 const ;
};

class  BaseSurface
{
private :
    
//
protected :
    SDL_Surface
*  pScreen;
    SDL_Surface
*  pSurface;
    BaseSurface();
public :
    BaseSurface(
const  BaseSurface &  copy);
    
virtual   ~ BaseSurface();
    BaseSurface
&   operator = ( const  BaseSurface &  copy);
    
// surface's point
    SDL_Surface *  point()  const ;
    
// blit surface to screen
     void  blit()  const ;
    
void  blit( int  any_num)  const ;
    
void  blit( int  at_x,  int  at_y)  const ;
    
void  blit( int  at_x,  int  at_y,
                
int  from_x,  int  from_y,  int  w,  int  h,
                
int  delta_x  =   0 int  delta_y  =   0 const ;
    
// blit surface to another surface
     void  blit( const  BaseSurface &  dst_surface)  const ;
    
void  blit( const  BaseSurface &  dst_surface,  int  any_num)  const ;
    
void  blit( const  BaseSurface &  dst_surface,
                        
int  at_x,  int  at_y)  const ;
    
void  blit( const  BaseSurface &  dst_surface,
                        
int  at_x,  int  at_y,
                        
int  from_x,  int  from_y,  int  w,  int  h,
                        
int  delta_x  =   0 int  delta_y  =   0 const ;
    
// color keying
     void  colorKey(Uint8 r  =   0 , Uint8 g  =   0xFF , Uint8 b  =   0xFF , Uint32 flag  =  SDL_SRCCOLORKEY);
};

class  PictureSurface:  public  BaseSurface
{
private :
    std::
string  fileName;
public :
    PictureSurface(
const  std:: string &  file_name,  const  ScreenSurface &  screen);
};

class  TextSurface:  public  BaseSurface
{
private :
    
static   int  textNum;
    std::
string  message;
    std::
string  TTF_fileName;
    
int  TTF_size;
    Uint8 r, g, b;
public :
    TextSurface(
const  std:: string &  _message,  const  ScreenSurface &  screen,
        Uint8 _r 
=   0xFF , Uint8 _g  =   0xFF , Uint8 _b  =   0xFF
        
int  ttf_size  =   28 const  std:: string &  ttf_fileName  =   " ./fonts/gkai00mp.ttf " );
    TextSurface(
const  TextSurface &  copy);
    
~ TextSurface();
    
// text tools
     void  toBlended();
    
void  toSolid();
    
void  toShaded(Uint8 _r, Uint8 _g, Uint8 _b);
    
void  setColor(Uint8 _r, Uint8 _g, Uint8 _b);
    
void  setSize( int  ttf_size);
    
void  setFont( const  std:: string &  ttf_fileName);
};

class  ErrorInfo
{
private :
    std::
string  info;
public :
    ErrorInfo():info(
" Unknown ERROR! " )
    {}
    ErrorInfo(
const   char *  c_str)
    {
        info 
=  std:: string (c_str);
    }
    ErrorInfo(
const  std:: string &  str):info(str)
    {}
    
void  show()  const
    {
        std::cerr 
<<  info  <<  std::endl;
    }
};

#endif

 

// UVi Soft ( 2008 )
// Long Fei ( lf426 ), E-mail: [email protected]
// Laboratory of ZaiBieLiunNian
// http://www.cppblog.com/lf426/

// FileName: SurfaceClass.cpp
// For Windows only

#include 
" SurfaceClass.hpp "

// *****************************************
// class ScreenSurface

int  ScreenSurface::screenNum  =   0 ;

ScreenSurface::ScreenSurface():
width(
640 ), height( 480 ), bpp( 32 ), flags( 0 ), windowName( " NULL " )
{
    
if  ( screenNum  >   0  )
        
throw  ErrorInfo( " DONOT create more than ONE screen! " );
    
if  ( SDL_Init(SDL_INIT_VIDEO)  <   0  )
        
throw  ErrorInfo(SDL_GetError());
    pScreen 
=  SDL_SetVideoMode(width, height, bpp, flags);
    screenNum
++ ;
}

ScreenSurface::ScreenSurface(
int  w,  int  h,  const  std:: string &  window_name,  int  b, Uint32 f):
width(w), height(h), bpp(b), flags(f)
{
    
if  ( screenNum  >   0  )
        
throw  ErrorInfo( " DONOT create more than ONE screen! " );
    
if  ( SDL_Init(SDL_INIT_VIDEO)  <   0  )
        
throw  ErrorInfo(SDL_GetError());
    pScreen 
=  SDL_SetVideoMode(width, height, bpp, flags);
    screenNum
++ ;
    
if  ( window_name  !=   " NULL "  ) {
        windowName 
=  window_name;
        SDL_WM_SetCaption(windowName.c_str(), 
0 );
    }
    
else
        windowName 
=   " NULL " ;
}

ScreenSurface::
~ ScreenSurface()
{
    SDL_Quit();
}

// ***

SDL_Surface
*  ScreenSurface::point()  const
{
    
return  pScreen;
}

void  ScreenSurface::flip()  const
{
    
if  ( SDL_Flip(pScreen)  <   0  )
        
throw  ErrorInfo(SDL_GetError());
}


void  ScreenSurface::fillColor(Uint8 r, Uint8 g, Uint8 b)  const
{
     
if  ( SDL_FillRect(pScreen,  0 , SDL_MapRGB(pScreen -> format, r, g, b))  <   0  )
         
throw  ErrorInfo(SDL_GetError());
}

// ************************************



// ************************************
// class BaseSurface

// protected
BaseSurface::BaseSurface():
pScreen(
0 ), pSurface( 0 )
{}

// public
BaseSurface::BaseSurface( const  BaseSurface &  copy):
pScreen(copy.pScreen)
{
    pSurface 
=  SDL_ConvertSurface(copy.pSurface, copy.pSurface -> format, SDL_SWSURFACE);
    
if  ( pSurface  ==   0  )
        
throw  ErrorInfo(SDL_GetError());
}

BaseSurface::
~ BaseSurface()
{
    SDL_FreeSurface(pSurface);
}

BaseSurface
&  BaseSurface:: operator = ( const  BaseSurface &  copy)
{
    SDL_FreeSurface(pSurface);
    pSurface 
=  SDL_ConvertSurface(copy.pSurface, copy.pSurface -> format, SDL_SWSURFACE);
    
if  ( pSurface  ==   0  )
        
throw  ErrorInfo(SDL_GetError());
    
return   * this ;
}

// ***

SDL_Surface
*  BaseSurface::point()  const
{
    
return  pSurface;
}

// ***

void  BaseSurface::blit()  const
{
    
const   int  SRC_W  =  pSurface -> w;
    
const   int  SRC_H  =  pSurface -> h;
    
const   int  DST_W  =  pScreen -> w;
    
const   int  DST_H  =  pScreen -> h;

    SDL_Rect offset;
    offset.x 
=  ( DST_W  -  SRC_W )  /   2 ;
    offset.y 
=  ( DST_H  -  SRC_H )  /   2 ;
    
if  ( SDL_BlitSurface(pSurface,  0 , pScreen,  & offset)  <   0  )
        
throw  ErrorInfo(SDL_GetError());
}

void  BaseSurface::blit( int  any_num)  const
{
    
if  ( SDL_BlitSurface(pSurface,  0 , pScreen,  0 <   0  )
        
throw  ErrorInfo(SDL_GetError());
}

void  BaseSurface::blit( int  at_x,  int  at_y)  const
{
    SDL_Rect offset;
    offset.x 
=  at_x;
    offset.y 
=  at_y;

    
if  ( SDL_BlitSurface(pSurface,  0 , pScreen,  & offset)  <   0  )
        
throw  ErrorInfo(SDL_GetError());
}

void  BaseSurface::blit( int  at_x,  int  at_y,
                       
int  from_x,  int  from_y,  int  w,  int  h,
                       
int  delta_x,  int  delta_y)  const
{
    SDL_Rect offset;
    offset.x 
=  at_x  -  delta_x;
    offset.y 
=  at_y  -  delta_y;

    SDL_Rect dest;
    dest.x 
=  from_x  -  delta_x;
    dest.y 
=  from_y  -  delta_y;
    dest.w 
=  w  +  delta_x * 2 ;
    dest.h 
=  h  +  delta_y * 2 ;

    
if  ( SDL_BlitSurface(pSurface,  & dest, pScreen,  & offset)  <   0  )
        
throw  ErrorInfo(SDL_GetError());
}

// ***

void  BaseSurface::blit( const  BaseSurface &  dst_surface)  const
{
    
const   int  SRC_W  =  pSurface -> w;
    
const   int  SRC_H  =  pSurface -> h;
    
const   int  DST_W  =  dst_surface.point() -> w;
    
const   int  DST_H  =  dst_surface.point() -> h;

    SDL_Rect offset;
    offset.x 
=  ( DST_W  -  SRC_W )  /   2 ;
    offset.y 
=  ( DST_H  -  SRC_H )  /   2 ;

    
if  (  & dst_surface  ==   this  )
        
throw  ErrorInfo( " Cannot blit surface to itself! " );

    
if  ( SDL_BlitSurface(pSurface,  0 , dst_surface.point(),  & offset)  <   0  )
        
throw  ErrorInfo(SDL_GetError());
}

void  BaseSurface::blit( const  BaseSurface &  dst_surface,  int  any_num)  const
{
    
if  (  & dst_surface  ==   this  )
        
throw  ErrorInfo( " Cannot blit surface to itself! " );

    
if  ( SDL_BlitSurface(pSurface,  0 , dst_surface.point(),  0 <   0  )
        
throw  ErrorInfo(SDL_GetError());
}

void  BaseSurface::blit( const  BaseSurface &  dst_surface,  int  at_x,  int  at_y)  const
{
    SDL_Rect offset;
    offset.x 
=  at_x;
    offset.y 
=  at_y;

    
if  (  & dst_surface  ==   this  )
        
throw  ErrorInfo( " Cannot blit surface to itself! " );

    
if  ( SDL_BlitSurface(pSurface,  0 , dst_surface.point(),  & offset)  <   0  )
        
throw  ErrorInfo(SDL_GetError());
}

void  BaseSurface::blit( const  BaseSurface &  dst_surface,
                       
int  at_x,  int  at_y,
                       
int  from_x,  int  from_y,  int  w,  int  h,
                       
int  delta_x,  int  delta_y)  const
{
    SDL_Rect offset;
    offset.x 
=  at_x  -  delta_x;
    offset.y 
=  at_y  -  delta_y;

    SDL_Rect dest;
    dest.x 
=  from_x  -  delta_x;
    dest.y 
=  from_y  -  delta_y;
    dest.w 
=  w  +  delta_x * 2 ;
    dest.h 
=  h  +  delta_y * 2 ;

    
if  (  & dst_surface  ==   this  )
        
throw  ErrorInfo( " Cannot blit surface to itself! " );

    
if  ( SDL_BlitSurface(pSurface,  & dest, dst_surface.point(),  & offset)  <   0  )
        
throw  ErrorInfo(SDL_GetError());
}

// ***

void  BaseSurface::colorKey(Uint8 r, Uint8 g, Uint8 b, Uint32 flag)
{
    Uint32 colorkey 
=  SDL_MapRGB(pSurface -> format, r, g, b);
    
if  ( SDL_SetColorKey(pSurface, flag, colorkey )  <   0  )
        
throw  ErrorInfo(SDL_GetError());
}

// ************************************


// ************************************
// class PictureSurface

PictureSurface::PictureSurface(
const  std:: string &  file_name,  const  ScreenSurface &  screen):
BaseSurface(),
fileName(file_name)
{
    SDL_Surface
*  pSurfaceTemp  =  IMG_Load(fileName.c_str());
    
if  ( pSurfaceTemp  ==   0  )
        
throw  ErrorInfo(IMG_GetError());
    pSurface 
=  SDL_DisplayFormat(pSurfaceTemp);
    
if  ( pSurface  ==   0  )
        
throw  ErrorInfo(SDL_GetError());
    SDL_FreeSurface(pSurfaceTemp);

    pScreen 
=  screen.point();
}

// ************************************



// ************************************
// class TextSurface

int  TextSurface::textNum  =   0 ;

TextSurface::TextSurface(
const  std:: string &  _message,  const  ScreenSurface &  screen,
        Uint8 _r, Uint8 _g, Uint8 _b, 
        
int  ttf_size,  const  std:: string &  ttf_fileName):
BaseSurface(),
message(_message), TTF_fileName(ttf_fileName), TTF_size(ttf_size), 
r(_r), g(_g), b(_b)
{
    
if  ( textNum  ==   0  ){
        
if  ( TTF_Init()  <   0  ){
            
throw  ErrorInfo(TTF_GetError());
        }
    }

    SDL_Color textColor;
    textColor.r 
=  r;
    textColor.g 
=  g;
    textColor.b 
=  b;

    TTF_Font
*  pFont  =  TTF_OpenFont(TTF_fileName.c_str(), TTF_size);
    
if  ( pFont  ==   0  )
        
throw  ErrorInfo(TTF_GetError());
    pSurface 
=  myTTF_RenderString_Blended(pFont, message, textColor);
    
if  ( pSurface  ==   0  )
        
throw  ErrorInfo(TTF_GetError());
    TTF_CloseFont(pFont);

    pScreen 
=  screen.point();

    textNum
++ ;
}


TextSurface::TextSurface(
const  TextSurface &  copy):
BaseSurface(copy),
message(copy.message), TTF_fileName(copy.TTF_fileName), TTF_size(copy.TTF_size), 
r(copy.r), g(copy.g), b(copy.b)
{
    textNum
++ ;
}


TextSurface::
~ TextSurface()
{
    textNum
-- ;
    
if  ( textNum  ==   0  ){
        TTF_Quit();
    }
}

// ***

void  TextSurface::toBlended()
{
    SDL_FreeSurface(pSurface);

    SDL_Color textColor;
    textColor.r 
=  r;
    textColor.g 
=  g;
    textColor.b 
=  b;

    TTF_Font
*  pFont  =  TTF_OpenFont(TTF_fileName.c_str(), TTF_size);
    
if  ( pFont  ==   0  )
        
throw  ErrorInfo(TTF_GetError());
    pSurface 
=  myTTF_RenderString_Blended(pFont, message, textColor);
    
if  ( pSurface  ==   0  )
        
throw  ErrorInfo(TTF_GetError());
    TTF_CloseFont(pFont);
}

void  TextSurface::toSolid()
{
    SDL_FreeSurface(pSurface);

    SDL_Color textColor;
    textColor.r 
=  r;
    textColor.g 
=  g;
    textColor.b 
=  b;

    TTF_Font
*  pFont  =  TTF_OpenFont(TTF_fileName.c_str(), TTF_size);
    
if  ( pFont  ==   0  )
        
throw  ErrorInfo(TTF_GetError());
    pSurface 
=  myTTF_RenderString_Solid(pFont, message, textColor);
    
if  ( pSurface  ==   0  )
        
throw  ErrorInfo(TTF_GetError());
    TTF_CloseFont(pFont);
}

void  TextSurface::toShaded(Uint8 _r, Uint8 _g, Uint8 _b)
{
    SDL_Color textColor;
    textColor.r 
=  r;
    textColor.g 
=  g;
    textColor.b 
=  b;
    
    SDL_Color bgColor;
    bgColor.r 
=  _r;
    bgColor.g 
=  _g;
    bgColor.b 
=  _b;

    SDL_FreeSurface(pSurface);

    TTF_Font
*  pFont  =  TTF_OpenFont(TTF_fileName.c_str(), TTF_size);
    
if  ( pFont  ==   0  )
        
throw  ErrorInfo(TTF_GetError());
    pSurface 
=  myTTF_RenderString_Shaded(pFont, message, textColor, bgColor);
    
if  ( pSurface  ==   0  )
        
throw  ErrorInfo(TTF_GetError());
    TTF_CloseFont(pFont);
}

void  TextSurface::setColor(Uint8 _r, Uint8 _g, Uint8 _b)
{
    SDL_FreeSurface(pSurface);

    SDL_Color textColor;
    textColor.r 
=  r  =  _r;
    textColor.g 
=  g  =  _g;
    textColor.b 
=  b  =  _b;

    TTF_Font
*  pFont  =  TTF_OpenFont(TTF_fileName.c_str(), TTF_size);
    
if  ( pFont  ==   0  )
        
throw  ErrorInfo(TTF_GetError());
    pSurface 
=  myTTF_RenderString_Blended(pFont, message, textColor);
    
if  ( pSurface  ==   0  )
        
throw  ErrorInfo(TTF_GetError());
    TTF_CloseFont(pFont);
}

void  TextSurface::setSize( int  ttf_size)
{
    SDL_FreeSurface(pSurface);

    SDL_Color textColor;
    textColor.r 
=  r;
    textColor.g 
=  g;
    textColor.b 
=  b;
    
    TTF_size 
=  ttf_size;
    TTF_Font
*  pFont  =  TTF_OpenFont(TTF_fileName.c_str(), TTF_size);
    
if  ( pFont  ==   0  )
        
throw  ErrorInfo(TTF_GetError());
    pSurface 
=  myTTF_RenderString_Blended(pFont, message, textColor);
    
if  ( pSurface  ==   0  )
        
throw  ErrorInfo(TTF_GetError());
    TTF_CloseFont(pFont);
}

void  TextSurface::setFont( const  std:: string &  ttf_fileName)
{
    SDL_FreeSurface(pSurface);

    SDL_Color textColor;
    textColor.r 
=  r;
    textColor.g 
=  g;
    textColor.b 
=  b;
    
    TTF_fileName 
=  ttf_fileName;
    TTF_Font
*  pFont  =  TTF_OpenFont(TTF_fileName.c_str(), TTF_size);
    
if  ( pFont  ==   0  )
        
throw  ErrorInfo(TTF_GetError());

    pSurface 
=  myTTF_RenderString_Blended(pFont, message, textColor);
    
if  ( pSurface  ==   0  )
        
throw  ErrorInfo(TTF_GetError());
    TTF_CloseFont(pFont);
}
// *************************************

Linux version:


// UVi Soft ( 2008 ) 
// Long Fei ( lf426 ), E-mail: [email protected] 
// Laboratory of ZaiBieLiunNian 
// http://www.cppblog.com/lf426/  
 
// FileName: SurfaceClass.hpp
// For Linux and other UTF-8 OS 
 
#ifndef SURFACE_CLASS_HPP 
#define  SURFACE_CLASS_HPP 
 
#include 
< iostream >  
#include 
< string >  
#include 
" SDL/SDL.h "  
#include 
" SDL/SDL_image.h "  
#include 
" SDL/SDL_ttf.h "
// Linux can render UTF-8 Chinese directly
// For Windows (simple Chinese), include below 
// #include "SDL_render_Chinese.h" 
 
class  ScreenSurface 

private
    
// number of screen, make sure there is only ONE screen 
     static   int  screenNum; 
    
// size & bpp  of screen 
     int  width; 
    
int  height; 
    
int  bpp; 
    
// common flags:SDL_SWSURFACE, SDL_HWSURFACE, SDL_DOUBLEBUF, SDL_FULLSCREEN 
    
// more:  http://www.libsdl.org/cgi/docwiki.cgi/SDL_5fSetVideoMode  
    Uint32 flags; 
    
// other attribute 
    SDL_Surface *  pScreen; 
    std::
string  windowName; 
public
    
// construct & deconstruct 
    ScreenSurface(); 
    ScreenSurface(
int  w,  int  h,  const  std:: string &  window_name  =   " NULL " int  b  =   0 , Uint32 f  =   0 ); 
    
~ ScreenSurface(); 
    
// screen's point 
    SDL_Surface *  point()  const
    
// flip the screen 
     void  flip()  const
    
// fill the screen with some color, default is black. 
     void  fillColor(Uint8 r  =   0 , Uint8 g  =   0 , Uint8 b  =   0 const
}; 
 
class  BaseSurface 

private
    
//  
protected
    SDL_Surface
*  pScreen; 
    SDL_Surface
*  pSurface; 
    BaseSurface(); 
public
    BaseSurface(
const  BaseSurface &  copy); 
    
virtual   ~ BaseSurface(); 
    BaseSurface
&   operator = ( const  BaseSurface &  copy); 
    
// surface's point 
    SDL_Surface *  point()  const
    
// blit surface to screen 
     void  blit()  const
    
void  blit( int  any_num)  const
    
void  blit( int  at_x,  int  at_y)  const
    
void  blit( int  at_x,  int  at_y, 
                
int  from_x,  int  from_y,  int  w,  int  h, 
                
int  delta_x  =   0 int  delta_y  =   0 const
    
// blit surface to another surface 
     void  blit( const  BaseSurface &  dst_surface)  const
    
void  blit( const  BaseSurface &  dst_surface,  int  any_num)  const
    
void  blit( const  BaseSurface &  dst_surface, 
                        
int  at_x,  int  at_y)  const
    
void  blit( const  BaseSurface &  dst_surface, 
                        
int  at_x,  int  at_y, 
                        
int  from_x,  int  from_y,  int  w,  int  h, 
                        
int  delta_x  =   0 int  delta_y  =   0 const
    
// color keying 
     void  colorKey(Uint8 r  =   0 , Uint8 g  =   0xFF , Uint8 b  =   0xFF , Uint32 flag  =  SDL_SRCCOLORKEY); 
}; 
 
class  PictureSurface:  public  BaseSurface 

private
    std::
string  fileName; 
public
    PictureSurface(
const  std:: string &  file_name,  const  ScreenSurface &  screen); 
}; 
 
class  TextSurface:  public  BaseSurface 

private
    
static   int  textNum; 
    std::
string  message; 
    std::
string  TTF_fileName; 
    
int  TTF_size; 
    Uint8 r, g, b; 
public
    TextSurface(
const  std:: string &  _message,  const  ScreenSurface &  screen, 
        Uint8 _r 
=   0xFF , Uint8 _g  =   0xFF , Uint8 _b  =   0xFF ,  
        
int  ttf_size  =   28 const  std:: string &  ttf_fileName  =   " ./fonts/gkai00mp.ttf " ); 
    TextSurface(
const  TextSurface &  copy); 
    
~ TextSurface(); 
    
// text tools 
     void  toBlended(); 
    
void  toSolid(); 
    
void  toShaded(Uint8 _r, Uint8 _g, Uint8 _b); 
    
void  setColor(Uint8 _r, Uint8 _g, Uint8 _b); 
    
void  setSize( int  ttf_size); 
    
void  setFont( const  std:: string &  ttf_fileName); 
}; 
 
class  ErrorInfo 

private
    std::
string  info; 
public
    ErrorInfo():info(
" Unknown ERROR! "
    {} 
    ErrorInfo(
const   char *  c_str) 
    { 
        info 
=  std:: string (c_str); 
    } 
    ErrorInfo(
const  std:: string &  str):info(str) 
    {} 
    
void  show()  const  
    { 
        std::cerr 
<<  info  <<  std::endl; 
    } 
}; 
 
#endif  

// UVi Soft ( 2008 ) 
// Long Fei ( lf426 ), E-mail: [email protected] 
// Laboratory of ZaiBieLiunNian 
// http://www.cppblog.com/lf426/

// FileName: SurfaceClass.cpp
// For Linux and other UTF-8 OS 
 
#include 
" SurfaceClass.hpp "  
 
// ***************************************** 
// class ScreenSurface 
 
int  ScreenSurface::screenNum  =   0
 
ScreenSurface::ScreenSurface(): 
width(
640 ), height( 480 ), bpp( 32 ), flags( 0 ), windowName( " NULL "

    
if  ( screenNum  >   0  ) 
        
throw  ErrorInfo( " DONOT create more than ONE screen! " ); 
    
if  ( SDL_Init(SDL_INIT_VIDEO)  <   0  ) 
        
throw  ErrorInfo(SDL_GetError()); 
    pScreen 
=  SDL_SetVideoMode(width, height, bpp, flags); 
    screenNum
++

 
ScreenSurface::ScreenSurface(
int  w,  int  h,  const  std:: string &  window_name,  int  b, Uint32 f):
width(w), height(h), bpp(b), flags(f)

    
if  ( screenNum  >   0  )
        
throw  ErrorInfo( " DONOT create more than ONE screen! " );
    
if  ( SDL_Init(SDL_INIT_VIDEO)  <   0  ) 
        
throw  ErrorInfo(SDL_GetError());
    pScreen 
=  SDL_SetVideoMode(width, height, bpp, flags);
    screenNum
++
    
if  ( window_name  !=   " NULL "  ) {
        windowName 
=  window_name;
        SDL_WM_SetCaption(windowName.c_str(), 
0 );
    } 
    
else  
        windowName 
=   " NULL " ;

 
ScreenSurface::
~ ScreenSurface()

    SDL_Quit();

 
// ***
 
SDL_Surface
*  ScreenSurface::point()  const

    
return  pScreen;

 
void  ScreenSurface::flip()  const

    
if  ( SDL_Flip(pScreen)  <   0  )
        
throw  ErrorInfo(SDL_GetError());


void  ScreenSurface::fillColor(Uint8 r, Uint8 g, Uint8 b)  const

     
if  ( SDL_FillRect(pScreen,  0 , SDL_MapRGB(pScreen -> format, r, g, b))  <   0  )
         
throw  ErrorInfo(SDL_GetError()); 

 
// ************************************
 
 
 
// ************************************
// class BaseSurface 
 
// protected
BaseSurface::BaseSurface(): 
pScreen(
0 ), pSurface( 0
{} 
 
// public
BaseSurface::BaseSurface( const  BaseSurface &  copy):
pScreen(copy.pScreen) 

    pSurface 
=  SDL_ConvertSurface(copy.pSurface, copy.pSurface -> format, SDL_SWSURFACE);
    
if  ( pSurface  ==   0  )
        
throw  ErrorInfo(SDL_GetError()); 

 
BaseSurface::
~ BaseSurface()

    SDL_FreeSurface(pSurface);

 
BaseSurface
&  BaseSurface:: operator = ( const  BaseSurface &  copy)

    SDL_FreeSurface(pSurface);
    pSurface 
=  SDL_ConvertSurface(copy.pSurface, copy.pSurface -> format, SDL_SWSURFACE);
    
if  ( pSurface  ==   0  )
        
throw  ErrorInfo(SDL_GetError());
    
return   * this

 
// ***
 
SDL_Surface
*  BaseSurface::point()  const

    
return  pSurface;

 
// ***
 
void  BaseSurface::blit()  const

    
const   int  SRC_W  =  pSurface -> w;
    
const   int  SRC_H  =  pSurface -> h; 
    
const   int  DST_W  =  pScreen -> w; 
    
const   int  DST_H  =  pScreen -> h; 
 
    SDL_Rect offset;
    offset.x 
=  ( DST_W  -  SRC_W )  /   2 ;
    offset.y 
=  ( DST_H  -  SRC_H )  /   2 ;
    
if  ( SDL_BlitSurface(pSurface,  0 , pScreen,  & offset)  <   0  )
        
throw  ErrorInfo(SDL_GetError()); 

 
void  BaseSurface::blit( int  any_num)  const
{
    
if  ( SDL_BlitSurface(pSurface,  0 , pScreen,  0 <   0  )
        
throw  ErrorInfo(SDL_GetError()); 

 
void  BaseSurface::blit( int  at_x,  int  at_y)  const

    SDL_Rect offset;
    offset.x 
=  at_x; 
    offset.y 
=  at_y; 
 
    
if  ( SDL_BlitSurface(pSurface,  0 , pScreen,  & offset)  <   0  )
        
throw  ErrorInfo(SDL_GetError());

 
void  BaseSurface::blit( int  at_x,  int  at_y,
                       
int  from_x,  int  from_y,  int  w,  int  h,
                       
int  delta_x,  int  delta_y)  const  

    SDL_Rect offset;
    offset.x 
=  at_x  -  delta_x; 
    offset.y 
=  at_y  -  delta_y; 
 
    SDL_Rect dest; 
    dest.x 
=  from_x  -  delta_x;
    dest.y 
=  from_y  -  delta_y;
    dest.w 
=  w  +  delta_x * 2 ;
    dest.h 
=  h  +  delta_y * 2 ;
 
    
if  ( SDL_BlitSurface(pSurface,  & dest, pScreen,  & offset)  <   0  )
        
throw  ErrorInfo(SDL_GetError()); 

 
// ***
 
void  BaseSurface::blit( const  BaseSurface &  dst_surface)  const

    
const   int  SRC_W  =  pSurface -> w;
    
const   int  SRC_H  =  pSurface -> h; 
    
const   int  DST_W  =  dst_surface.point() -> w;
    
const   int  DST_H  =  dst_surface.point() -> h; 
 
    SDL_Rect offset;
    offset.x 
=  ( DST_W  -  SRC_W )  /   2 ;
    offset.y 
=  ( DST_H  -  SRC_H )  /   2 ;
 
    
if  (  & dst_surface  ==   this  )
        
throw  ErrorInfo( " Cannot blit surface to itself! " );
 
    
if  ( SDL_BlitSurface(pSurface,  0 , dst_surface.point(),  & offset)  <   0  )
        
throw  ErrorInfo(SDL_GetError()); 

 
void  BaseSurface::blit( const  BaseSurface &  dst_surface,  int  any_num)  const

    
if  (  & dst_surface  ==   this  )
        
throw  ErrorInfo( " Cannot blit surface to itself! " );
 
    
if  ( SDL_BlitSurface(pSurface,  0 , dst_surface.point(),  0 <   0  )
        
throw  ErrorInfo(SDL_GetError()); 

 
void  BaseSurface::blit( const  BaseSurface &  dst_surface,  int  at_x,  int  at_y)  const

    SDL_Rect offset;
    offset.x 
=  at_x;
    offset.y 
=  at_y; 
 
    
if  (  & dst_surface  ==   this  )
        
throw  ErrorInfo( " Cannot blit surface to itself! " );
 
    
if  ( SDL_BlitSurface(pSurface,  0 , dst_surface.point(),  & offset)  <   0  )
        
throw  ErrorInfo(SDL_GetError()); 

 
void  BaseSurface::blit( const  BaseSurface &  dst_surface,
                       
int  at_x,  int  at_y,
                       
int  from_x,  int  from_y,  int  w,  int  h,
                       
int  delta_x,  int  delta_y)  const  

    SDL_Rect offset;
    offset.x 
=  at_x  -  delta_x;
    offset.y 
=  at_y  -  delta_y;
 
    SDL_Rect dest;
    dest.x 
=  from_x  -  delta_x;
    dest.y 
=  from_y  -  delta_y;
    dest.w 
=  w  +  delta_x * 2
    dest.h 
=  h  +  delta_y * 2
 
    
if  (  & dst_surface  ==   this  )
        
throw  ErrorInfo( " Cannot blit surface to itself! " );
 
    
if  ( SDL_BlitSurface(pSurface,  & dest, dst_surface.point(),  & offset)  <   0  )
        
throw  ErrorInfo(SDL_GetError()); 

 
// *** 
 
void  BaseSurface::colorKey(Uint8 r, Uint8 g, Uint8 b, Uint32 flag)

    Uint32 colorkey 
=  SDL_MapRGB(pSurface -> format, r, g, b);
    
if  ( SDL_SetColorKey(pSurface, flag, colorkey )  <   0  )
        
throw  ErrorInfo(SDL_GetError()); 

 
// ************************************
 
 
// ************************************
// class PictureSurface 
 
PictureSurface::PictureSurface(
const  std:: string &  file_name,  const  ScreenSurface &  screen):
BaseSurface(), 
fileName(file_name)
{
    SDL_Surface
*  pSurfaceTemp  =  IMG_Load(fileName.c_str());
    
if  ( pSurfaceTemp  ==   0  )
        
throw  ErrorInfo(IMG_GetError());
    pSurface 
=  SDL_DisplayFormat(pSurfaceTemp);
    
if  ( pSurface  ==   0  )
        
throw  ErrorInfo(SDL_GetError());
    SDL_FreeSurface(pSurfaceTemp);

    pScreen 
=  screen.point();
}

// ************************************



// ************************************
// class TextSurface

int  TextSurface::textNum  =   0 ;

TextSurface::TextSurface(
const  std:: string &  _message,  const  ScreenSurface &  screen,
        Uint8 _r, Uint8 _g, Uint8 _b, 
        
int  ttf_size,  const  std:: string &  ttf_fileName):
BaseSurface(),
message(_message), TTF_fileName(ttf_fileName), TTF_size(ttf_size), 
r(_r), g(_g), b(_b)
{
    
if  ( textNum  ==   0  ){
        
if  ( TTF_Init()  <   0  ){
            
throw  ErrorInfo(TTF_GetError());
        }
    }

    SDL_Color textColor;
    textColor.r 
=  r;
    textColor.g 
=  g;
    textColor.b 
=  b;

    TTF_Font
*  pFont  =  TTF_OpenFont(TTF_fileName.c_str(), TTF_size);
    
if  ( pFont  ==   0  )
        
throw  ErrorInfo(TTF_GetError());
    pSurface 
=  TTF_RenderUTF8_Blended(pFont, message.c_str(), textColor);
    
if  ( pSurface  ==   0  )
        
throw  ErrorInfo(TTF_GetError());
    TTF_CloseFont(pFont);

    pScreen 
=  screen.point();

    textNum
++ ;
}


TextSurface::TextSurface(
const  TextSurface &  copy):
BaseSurface(copy),
message(copy.message), TTF_fileName(copy.TTF_fileName), TTF_size(copy.TTF_size), 
r(copy.r), g(copy.g), b(copy.b)
{
    textNum
++ ;
}


TextSurface::
~ TextSurface()
{
    textNum
-- ;
    
if  ( textNum  ==   0  ){
        TTF_Quit();
    }
}

// ***

void  TextSurface::toBlended()
{
    SDL_FreeSurface(pSurface);

    SDL_Color textColor;
    textColor.r 
=  r;
    textColor.g 
=  g;
    textColor.b 
=  b;

    TTF_Font
*  pFont  =  TTF_OpenFont(TTF_fileName.c_str(), TTF_size);
    
if  ( pFont  ==   0  )
        
throw  ErrorInfo(TTF_GetError());
    pSurface 
=  TTF_RenderUTF8_Blended(pFont, message.c_str(), textColor);
    
if  ( pSurface  ==   0  )
        
throw  ErrorInfo(TTF_GetError());
    TTF_CloseFont(pFont);
}

void  TextSurface::toSolid()
{
    SDL_FreeSurface(pSurface);

    SDL_Color textColor;
    textColor.r 
=  r;
    textColor.g 
=  g;
    textColor.b 
=  b;

    TTF_Font
*  pFont  =  TTF_OpenFont(TTF_fileName.c_str(), TTF_size);
    
if  ( pFont  ==   0  )
        
throw  ErrorInfo(TTF_GetError());
    pSurface 
=  TTF_RenderUTF8_Solid(pFont, message.c_str(), textColor);
    
if  ( pSurface  ==   0  )
        
throw  ErrorInfo(TTF_GetError());
    TTF_CloseFont(pFont);
}

void  TextSurface::toShaded(Uint8 _r, Uint8 _g, Uint8 _b)
{
    SDL_Color textColor;
    textColor.r 
=  r;
    textColor.g 
=  g;
    textColor.b 
=  b;
    
    SDL_Color bgColor;
    bgColor.r 
=  _r;
    bgColor.g 
=  _g;
    bgColor.b 
=  _b;

    SDL_FreeSurface(pSurface);

    TTF_Font
*  pFont  =  TTF_OpenFont(TTF_fileName.c_str(), TTF_size);
    
if  ( pFont  ==   0  )
        
throw  ErrorInfo(TTF_GetError());
    pSurface 
=  TTF_RenderUTF8_Shaded(pFont, message.c_str(), textColor, bgColor);
    
if  ( pSurface  ==   0  )
        
throw  ErrorInfo(TTF_GetError());
    TTF_CloseFont(pFont);
}

void  TextSurface::setColor(Uint8 _r, Uint8 _g, Uint8 _b)
{
    SDL_FreeSurface(pSurface);

    SDL_Color textColor;
    textColor.r 
=  r  =  _r;
    textColor.g 
=  g  =  _g;
    textColor.b 
=  b  =  _b;

    TTF_Font
*  pFont  =  TTF_OpenFont(TTF_fileName.c_str(), TTF_size);
    
if  ( pFont  ==   0  )
        
throw  ErrorInfo(TTF_GetError());
    pSurface 
=  TTF_RenderUTF8_Blended(pFont, message.c_str(), textColor);
    
if  ( pSurface  ==   0  )
        
throw  ErrorInfo(TTF_GetError());
    TTF_CloseFont(pFont);
}

void  TextSurface::setSize( int  ttf_size)
{
    SDL_FreeSurface(pSurface);

    SDL_Color textColor;
    textColor.r 
=  r;
    textColor.g 
=  g;
    textColor.b 
=  b;
    
    TTF_size 
=  ttf_size;
    TTF_Font
*  pFont  =  TTF_OpenFont(TTF_fileName.c_str(), TTF_size);
    
if  ( pFont  ==   0  )
        
throw  ErrorInfo(TTF_GetError());
    pSurface 
=  TTF_RenderUTF8_Blended(pFont, message.c_str(), textColor);
    
if  ( pSurface  ==   0  )
        
throw  ErrorInfo(TTF_GetError());
    TTF_CloseFont(pFont);
}

void  TextSurface::setFont( const  std:: string &  ttf_fileName)
{
    SDL_FreeSurface(pSurface);

    SDL_Color textColor;
    textColor.r 
=  r;
    textColor.g 
=  g;
    textColor.b 
=  b;
    
    TTF_fileName 
=  ttf_fileName;
    TTF_Font
*  pFont  =  TTF_OpenFont(TTF_fileName.c_str(), TTF_size);
    
if  ( pFont  ==   0  )
        
throw  ErrorInfo(TTF_GetError());

    pSurface 
=  TTF_RenderUTF8_Blended(pFont, message.c_str(), textColor);
    
if  ( pSurface  ==   0  )
        
throw  ErrorInfo(TTF_GetError());
    TTF_CloseFont(pFont);
}
// *************************************

lib: iconv.lib
     SDL_ttf.lib
     SDL.lib, SDLmain.lib
     SDL_image.lib

dll: iconv.dll
     SDL_ttf.dll, libfreetype-6.dll, zlib1.dll
     SDL.dll
     jpeg.dll, libpng12-0.dll, libtiff-3.dll, SDL_image.dll, zlib1.dll

gkai00mp.ttf为Debian楷体,文泉驿字库。

last update: 2008-05-12

你可能感兴趣的:(SurfaceClass)