home *** CD-ROM | disk | FTP | other *** search
- #include "SoftwareHardware2D.h"
- #include "SoftwareHardwarePicture2D.h"
- #include "LogPtr.h"
- #include "String.h"
- #include "safe_new.h"
-
- SoftwareHardware2D::SoftwareHardware2D(HWND wnd)
- : wnd( wnd ),
- width( 0 ),
- height( 0 ),
- picture_count( 0 )
- {}
-
- SoftwareHardware2D::~SoftwareHardware2D()
- {
- if( picture_count != 0 )
- {
- LogPtr()->error("in SoftwareHardware2D::~SoftwareHardware2D() picture_count != 0" );
- }
- }
-
- bool SoftwareHardware2D::set_mode(unsigned sx, unsigned sy)
- {
- width = sx;
- height = sy;
- RECT win_rect;
- GetWindowRect( wnd, &win_rect );
- RECT rect;
- GetClientRect( wnd, &rect );
- int new_width = width +
- (win_rect.right - win_rect.left) - (rect.right - rect.left);
- int new_height = height +
- (win_rect.bottom - win_rect.top) - (rect.bottom - rect.top);
-
- int scr_x = GetSystemMetrics( SM_CXSCREEN );
- int scr_y = GetSystemMetrics( SM_CYSCREEN );
-
- int shi_x = (scr_x - new_width)/2;
- int shi_y = (scr_y - new_height)/2;
- if( shi_x < 0 )
- shi_x = 0;
- if( shi_y < 0 )
- shi_y = 0;
-
- MoveWindow( wnd, shi_x, shi_y, new_width, new_height, true );
-
- start_viewport();
- return true;
- }
-
- unsigned SoftwareHardware2D::get_width()
- {
- return width;
- }
-
- unsigned SoftwareHardware2D::get_height()
- {
- return height;
- }
-
- void SoftwareHardware2D::stop_mode()
- {
- width = height = 0;
- }
-
- void SoftwareHardware2D::start_viewport()
- {
- if( canvas.cx() != width ||
- canvas.cy() != height )
- {
- canvas = Canvas( width, height );
- }
- }
-
- void SoftwareHardware2D::fill(int left, int top, int right, int bottom, const Color & color)
- {
- if( left < 0 ) left = 0;
- if( right > canvas.cx() ) right = canvas.cx();
- if( left >= right )
- return;
- if( top < 0 ) top = 0;
- if( bottom > canvas.cy() ) bottom = canvas.cy();
- if( top >= bottom )
- return;
- Color * total_start = canvas.begin() + canvas.offset( left, top );
- Color * total_end = canvas.begin() + canvas.offset( left, bottom );
- do // We paint at least 1x1 - this helps optimizer very much
- {
- Color * line_start = total_start;
- Color * line_end = line_start + right - left;
- do
- {
- *line_start++ = color;
- }while( line_start != line_end );
- total_start += canvas.cx();
- }while( total_start != total_end );
- }
-
- void SoftwareHardware2D::flip()
- {
- POINT client_p = { 0, 0 };
- ClientToScreen( wnd, &client_p );
- RECT rect;
- GetWindowRect( wnd, &rect );
- // Calculate the coordinates of client area relative to window area
- int relative_x = client_p.x - rect.left;
- int relative_y = client_p.y - rect.top;
-
- HDC dc = GetWindowDC( wnd );
- int cx = canvas.cx();
- int cy = canvas.cy();
- BITMAPINFO bmpInfo;
- BITMAPINFOHEADER BM_Info_Header =
- {
- sizeof(BITMAPINFOHEADER),
- cx, -cy,
- 1,
- 32,
- BI_RGB,
- cx * cy * 4,
- 0,
- 0,
- 0,
- 0
- };
- bmpInfo.bmiHeader = BM_Info_Header;
-
- StretchDIBits( dc,
- relative_x, relative_y, cx, cy,
- 0, 0, cx, cy,
- canvas.begin() + canvas.offset(0,0), &bmpInfo, DIB_RGB_COLORS, SRCCOPY );
-
- ReleaseDC( wnd, dc ); dc = NULL;
-
- start_viewport();
- }
-
- HardwarePicture2D * SoftwareHardware2D::load_picture(const Color * colors, unsigned width, unsigned height, unsigned stride)
- {
- if( !colors )
- return 0;
- SoftwareHardwarePicture2D * pic = new SoftwareHardwarePicture2D( this );
- pic->canvas = Canvas( width, height );
-
- for( int y = 0; y < height; ++y, colors += stride - width )
- for( int x = 0; x < width; ++x, ++colors )
- {
- Color src = *colors;
- pic->canvas[ x ][ y ] = src;
- }
- return pic;
- }
-
- void SoftwareHardware2D::blit(const SoftwareHardwarePicture2D & pic, int left, int top, int alpha)
- {
- const int clip_x0 = 0;
- const int clip_y0 = 0;
- const int clip_x1 = width;
- const int clip_y1 = height;
-
- int picture_x0 = 0;
- int picture_y0 = 0;
-
- int picture_x1 = pic.canvas.cx();
- int picture_y1 = pic.canvas.cy();
-
- int scr_x0 = left;
- int scr_y0 = top;
-
- if( scr_x0 < clip_x0 )
- {
- picture_x0 -= scr_x0 - clip_x0;
- scr_x0 = clip_x0;
- }
- if( scr_y0 < clip_y0 )
- {
- picture_y0 -= scr_y0 - clip_y0;
- scr_y0 = clip_y0;
- }
- int delta = scr_x0 - clip_x1 + picture_x1 - picture_x0;
- if( delta > 0 )
- {
- picture_x1 -= delta;
- }
- delta = scr_y0 - clip_y1 + picture_y1 - picture_y0;
- if( delta > 0 )
- {
- picture_y1 -= delta;
- }
- if( picture_x1 <= picture_x0 ||
- picture_y1 <= picture_y0 )
- return; // Out of the screen
- for( int py = picture_y0, y = scr_y0; py < picture_y1; ++py, ++y )
- {
- const Color * pic_start = pic.canvas.begin() + pic.canvas.offset( picture_x0, py );
- const Color * pic_end = pic_start + picture_x1 - picture_x0;
- Color * scr_start = canvas.begin() + canvas.offset( scr_x0, y );
-
- if( alpha == 255 )
- do
- {
- if( pic_start->a != 0 )
- *scr_start = *pic_start;
- ++scr_start;
- ++pic_start;
- }while( pic_start != pic_end );
- else
- do
- {
- if( pic_start->a != 0 )
- scr_start->bilinear( *pic_start, alpha );
- ++scr_start;
- ++pic_start;
- }while( pic_start != pic_end );
- }
- }
-
- void SoftwareHardware2D::add_picture_count(int delta)
- {
- picture_count += delta;
- }
-