home *** CD-ROM | disk | FTP | other *** search
/ Game.EXE 2002 April / Game.EXE_04_2002.iso / Alawar / SoftwareHardware2D.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2002-03-02  |  5.0 KB  |  222 lines

  1. #include "SoftwareHardware2D.h"
  2. #include "SoftwareHardwarePicture2D.h"
  3. #include "LogPtr.h"
  4. #include "String.h"
  5. #include "safe_new.h"
  6.  
  7. SoftwareHardware2D::SoftwareHardware2D(HWND wnd)
  8. :    wnd( wnd ),
  9.     width( 0 ),
  10.     height( 0 ),
  11.     picture_count( 0 )
  12. {}
  13.  
  14. SoftwareHardware2D::~SoftwareHardware2D()
  15. {
  16.     if( picture_count != 0 )
  17.     {
  18.         LogPtr()->error("in SoftwareHardware2D::~SoftwareHardware2D() picture_count != 0" );
  19.     }
  20. }
  21.  
  22. bool SoftwareHardware2D::set_mode(unsigned sx, unsigned sy)
  23. {
  24.     width = sx;
  25.     height = sy;
  26.     RECT win_rect;
  27.     GetWindowRect( wnd, &win_rect );
  28.     RECT rect;
  29.     GetClientRect( wnd, &rect );
  30.     int new_width = width +
  31.         (win_rect.right - win_rect.left) - (rect.right - rect.left);
  32.     int new_height = height +
  33.         (win_rect.bottom - win_rect.top) - (rect.bottom - rect.top);
  34.  
  35.     int scr_x = GetSystemMetrics( SM_CXSCREEN );
  36.     int scr_y = GetSystemMetrics( SM_CYSCREEN );
  37.  
  38.     int shi_x = (scr_x - new_width)/2;
  39.     int shi_y = (scr_y - new_height)/2;
  40.     if( shi_x < 0 )
  41.         shi_x = 0;
  42.     if( shi_y < 0 )
  43.         shi_y = 0;
  44.     
  45.     MoveWindow( wnd, shi_x, shi_y, new_width, new_height, true );
  46.  
  47.     start_viewport();
  48.     return true;
  49. }
  50.  
  51. unsigned SoftwareHardware2D::get_width()
  52. {
  53.     return width;
  54. }
  55.  
  56. unsigned SoftwareHardware2D::get_height()
  57. {
  58.     return height;
  59. }
  60.  
  61. void SoftwareHardware2D::stop_mode()
  62. {
  63.     width = height = 0;
  64. }
  65.  
  66. void SoftwareHardware2D::start_viewport()
  67. {
  68.     if( canvas.cx() != width ||
  69.         canvas.cy() != height )
  70.     {
  71.         canvas = Canvas( width, height );
  72.     }
  73. }
  74.  
  75. void SoftwareHardware2D::fill(int left, int top, int right, int bottom, const Color & color)
  76. {
  77.     if( left < 0 ) left = 0;
  78.     if( right > canvas.cx() ) right = canvas.cx();
  79.     if( left >= right )
  80.         return;
  81.     if( top < 0 ) top = 0;
  82.     if( bottom > canvas.cy() ) bottom = canvas.cy();
  83.     if( top >= bottom )
  84.         return;
  85.     Color * total_start = canvas.begin() + canvas.offset( left, top );
  86.     Color * total_end = canvas.begin() + canvas.offset( left, bottom );
  87.     do // We paint at least 1x1 - this helps optimizer very much
  88.     {
  89.         Color * line_start = total_start;
  90.         Color * line_end = line_start + right - left;
  91.         do
  92.         {
  93.             *line_start++ = color;
  94.         }while( line_start != line_end );
  95.         total_start += canvas.cx();
  96.     }while( total_start != total_end );
  97. }
  98.  
  99. void SoftwareHardware2D::flip()
  100. {
  101.     POINT client_p = { 0, 0 };
  102.     ClientToScreen( wnd, &client_p );
  103.     RECT rect;
  104.     GetWindowRect( wnd, &rect );
  105.     // Calculate the coordinates of client area relative to window area
  106.     int relative_x = client_p.x - rect.left;
  107.     int relative_y = client_p.y - rect.top;
  108.  
  109.     HDC dc = GetWindowDC( wnd );
  110.     int cx = canvas.cx();
  111.     int cy = canvas.cy();
  112.     BITMAPINFO bmpInfo;
  113.     BITMAPINFOHEADER BM_Info_Header = 
  114.     {
  115.         sizeof(BITMAPINFOHEADER),
  116.         cx, -cy,
  117.         1,
  118.         32,
  119.         BI_RGB,
  120.         cx * cy * 4,
  121.         0,
  122.         0,
  123.         0,
  124.         0
  125.     };
  126.     bmpInfo.bmiHeader = BM_Info_Header;
  127.  
  128.     StretchDIBits( dc,
  129.         relative_x, relative_y, cx, cy,
  130.         0, 0, cx, cy,
  131.         canvas.begin() + canvas.offset(0,0), &bmpInfo, DIB_RGB_COLORS, SRCCOPY );
  132.  
  133.     ReleaseDC( wnd, dc ); dc = NULL;
  134.  
  135.     start_viewport();
  136. }
  137.  
  138. HardwarePicture2D * SoftwareHardware2D::load_picture(const Color * colors, unsigned width, unsigned height, unsigned stride)
  139. {
  140.     if( !colors )
  141.         return 0;
  142.     SoftwareHardwarePicture2D * pic = new SoftwareHardwarePicture2D( this );
  143.     pic->canvas = Canvas( width, height );
  144.  
  145.     for( int y = 0; y < height; ++y, colors += stride - width )
  146.     for( int x = 0; x < width; ++x, ++colors )
  147.     {
  148.         Color src = *colors;
  149.         pic->canvas[ x ][ y ] = src;
  150.     }
  151.     return pic;
  152. }
  153.  
  154. void SoftwareHardware2D::blit(const SoftwareHardwarePicture2D & pic, int left, int top, int alpha)
  155. {
  156.     const int clip_x0 = 0;
  157.     const int clip_y0 = 0;
  158.     const int clip_x1 = width;
  159.     const int clip_y1 = height;
  160.  
  161.     int picture_x0 = 0;
  162.     int picture_y0 = 0;
  163.  
  164.     int picture_x1 = pic.canvas.cx();
  165.     int picture_y1 = pic.canvas.cy();
  166.  
  167.     int scr_x0 = left;
  168.     int scr_y0 = top;
  169.  
  170.     if( scr_x0 < clip_x0 )
  171.     {
  172.         picture_x0 -= scr_x0 - clip_x0;
  173.         scr_x0 = clip_x0;
  174.     }
  175.     if( scr_y0 < clip_y0 )
  176.     {
  177.         picture_y0 -= scr_y0 - clip_y0;
  178.         scr_y0 = clip_y0;
  179.     }
  180.     int delta = scr_x0 - clip_x1 + picture_x1 - picture_x0;
  181.     if( delta > 0 )
  182.     {
  183.         picture_x1 -= delta;
  184.     }
  185.     delta = scr_y0 - clip_y1 + picture_y1 - picture_y0;
  186.     if( delta > 0 )
  187.     {
  188.         picture_y1 -= delta;
  189.     }
  190.     if( picture_x1 <= picture_x0 ||
  191.         picture_y1 <= picture_y0 )
  192.         return; // Out of the screen
  193.     for( int py = picture_y0, y = scr_y0; py < picture_y1; ++py, ++y )
  194.     {
  195.         const Color * pic_start = pic.canvas.begin() + pic.canvas.offset( picture_x0, py );
  196.         const Color * pic_end = pic_start + picture_x1 - picture_x0;
  197.         Color * scr_start = canvas.begin() + canvas.offset( scr_x0, y );
  198.  
  199.         if( alpha == 255 )
  200.             do
  201.             {
  202.                 if( pic_start->a != 0 )
  203.                     *scr_start = *pic_start;
  204.                 ++scr_start;
  205.                 ++pic_start;
  206.             }while( pic_start != pic_end );
  207.         else
  208.             do
  209.             {
  210.                 if( pic_start->a != 0 )
  211.                     scr_start->bilinear( *pic_start, alpha );
  212.                 ++scr_start;
  213.                 ++pic_start;
  214.             }while( pic_start != pic_end );
  215.     }
  216. }
  217.  
  218. void SoftwareHardware2D::add_picture_count(int delta)
  219. {
  220.     picture_count += delta;
  221. }
  222.