00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #define STRICT
00011
#include <tchar.h>
00012
#include <windows.h>
00013
#include <windowsx.h>
00014
#include <ddraw.h>
00015
#include "ddutil.h"
00016
#include "dxutil.h"
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 CDisplay::CDisplay()
00028 {
00029
m_pDD = NULL;
00030
m_pddsFrontBuffer = NULL;
00031
m_pddsBackBuffer = NULL;
00032
m_pddsBackBufferLeft = NULL;
00033 }
00034
00035
00036
00037
00038
00039
00040
00041
00042 CDisplay::~CDisplay()
00043 {
00044
DestroyObjects();
00045 }
00046
00047
00048
00049
00050
00051
00052
00053
00054 HRESULT
CDisplay::DestroyObjects()
00055 {
00056
SAFE_RELEASE(
m_pddsBackBufferLeft );
00057
SAFE_RELEASE(
m_pddsBackBuffer );
00058
SAFE_RELEASE(
m_pddsFrontBuffer );
00059
00060
if(
m_pDD )
00061
m_pDD->SetCooperativeLevel(
m_hWnd, DDSCL_NORMAL );
00062
00063
SAFE_RELEASE(
m_pDD );
00064
00065
return S_OK;
00066 }
00067
00068
00069
00070
00071
00072
00073
00074
00075 HRESULT
CDisplay::CreateFullScreenDisplay( HWND hWnd, DWORD dwWidth,
00076 DWORD dwHeight, DWORD dwBPP )
00077 {
00078 HRESULT hr;
00079
00080
00081
DestroyObjects();
00082
00083
00084
if( FAILED( hr = DirectDrawCreateEx( NULL, (VOID**)&
m_pDD,
00085 IID_IDirectDraw7, NULL ) ) )
00086
return E_FAIL;
00087
00088
00089 hr = m_pDD->SetCooperativeLevel(
hWnd, DDSCL_EXCLUSIVE|DDSCL_FULLSCREEN );
00090
if( FAILED(hr) )
00091
return E_FAIL;
00092
00093
00094
if( FAILED( m_pDD->SetDisplayMode( dwWidth, dwHeight, dwBPP, 0, 0 ) ) )
00095
return E_FAIL;
00096
00097
00098 DDSURFACEDESC2 ddsd;
00099 ZeroMemory( &ddsd,
sizeof( ddsd ) );
00100 ddsd.dwSize =
sizeof( ddsd );
00101 ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;
00102 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_FLIP |
00103 DDSCAPS_COMPLEX | DDSCAPS_3DDEVICE;
00104 ddsd.dwBackBufferCount = 1;
00105
00106
if( FAILED( hr = m_pDD->CreateSurface( &ddsd, &
m_pddsFrontBuffer,
00107 NULL ) ) )
00108
return E_FAIL;
00109
00110
00111 DDSCAPS2 ddscaps;
00112 ZeroMemory( &ddscaps,
sizeof( ddscaps ) );
00113 ddscaps.dwCaps = DDSCAPS_BACKBUFFER;
00114
00115
if( FAILED( hr =
m_pddsFrontBuffer->GetAttachedSurface( &ddscaps,
00116 &
m_pddsBackBuffer ) ) )
00117
return E_FAIL;
00118
00119
m_pddsBackBuffer->AddRef();
00120
00121
m_hWnd =
hWnd;
00122
m_bWindowed = FALSE;
00123
UpdateBounds();
00124
00125
return S_OK;
00126 }
00127
00128
00129
00130
00131
00132
00133
00134
00135 HRESULT
CDisplay::CreateWindowedDisplay( HWND hWnd, DWORD dwWidth, DWORD dwHeight )
00136 {
00137 HRESULT hr;
00138
00139
00140
DestroyObjects();
00141
00142
00143
if( FAILED( hr = DirectDrawCreateEx( NULL, (VOID**)&
m_pDD,
00144 IID_IDirectDraw7, NULL ) ) )
00145
return E_FAIL;
00146
00147
00148 hr = m_pDD->SetCooperativeLevel(
hWnd, DDSCL_NORMAL );
00149
if( FAILED(hr) )
00150
return E_FAIL;
00151
00152 RECT rcWork;
00153 RECT rc;
00154 DWORD dwStyle;
00155
00156
00157
00158 dwStyle = GetWindowStyle(
hWnd );
00159 dwStyle &= ~WS_POPUP;
00160 dwStyle |= WS_OVERLAPPED | WS_CAPTION | WS_THICKFRAME | WS_MINIMIZEBOX;
00161 SetWindowLong(
hWnd, GWL_STYLE, dwStyle );
00162
00163
00164 SetRect( &rc, 0, 0, dwWidth, dwHeight );
00165
00166 AdjustWindowRectEx( &rc, GetWindowStyle(
hWnd), GetMenu(
hWnd) != NULL,
00167 GetWindowExStyle(
hWnd) );
00168
00169 SetWindowPos(
hWnd, NULL, 0, 0, rc.right-rc.left, rc.bottom-rc.top,
00170 SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE );
00171
00172 SetWindowPos(
hWnd, HWND_NOTOPMOST, 0, 0, 0, 0,
00173 SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE );
00174
00175
00176 SystemParametersInfo( SPI_GETWORKAREA, 0, &rcWork, 0 );
00177 GetWindowRect(
hWnd, &rc );
00178
if( rc.left < rcWork.left ) rc.left = rcWork.left;
00179
if( rc.top < rcWork.top ) rc.top = rcWork.top;
00180 SetWindowPos(
hWnd, NULL, rc.left, rc.top, 0, 0,
00181 SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE );
00182
00183 LPDIRECTDRAWCLIPPER pcClipper;
00184
00185
00186 DDSURFACEDESC2 ddsd;
00187 ZeroMemory( &ddsd,
sizeof( ddsd ) );
00188 ddsd.dwSize =
sizeof( ddsd );
00189 ddsd.dwFlags = DDSD_CAPS;
00190 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
00191
00192
if( FAILED( m_pDD->CreateSurface( &ddsd, &
m_pddsFrontBuffer, NULL ) ) )
00193
return E_FAIL;
00194
00195
00196 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
00197 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE;
00198 ddsd.dwWidth = dwWidth;
00199 ddsd.dwHeight = dwHeight;
00200
00201
if( FAILED( hr = m_pDD->CreateSurface( &ddsd, &
m_pddsBackBuffer, NULL ) ) )
00202
return E_FAIL;
00203
00204
if( FAILED( hr = m_pDD->CreateClipper( 0, &pcClipper, NULL ) ) )
00205
return E_FAIL;
00206
00207
if( FAILED( hr = pcClipper->SetHWnd( 0,
hWnd ) ) )
00208 {
00209 pcClipper->Release();
00210
return E_FAIL;
00211 }
00212
00213
if( FAILED( hr =
m_pddsFrontBuffer->SetClipper( pcClipper ) ) )
00214 {
00215 pcClipper->Release();
00216
return E_FAIL;
00217 }
00218
00219
00220 pcClipper->Release();
00221
00222
m_hWnd =
hWnd;
00223
m_bWindowed = TRUE;
00224
UpdateBounds();
00225
00226
return S_OK;
00227 }
00228
00229
00230
00231
00232
00233
00234
00235
00236 HRESULT
CDisplay::CreateSurface(
CSurface** ppSurface,
00237 DWORD dwWidth, DWORD dwHeight )
00238 {
00239
if( NULL ==
m_pDD )
00240
return E_POINTER;
00241
if( NULL == ppSurface )
00242
return E_INVALIDARG;
00243
00244 HRESULT hr;
00245 DDSURFACEDESC2 ddsd;
00246 ZeroMemory( &ddsd,
sizeof( ddsd ) );
00247 ddsd.dwSize =
sizeof( ddsd );
00248 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
00249 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
00250 ddsd.dwWidth = dwWidth;
00251 ddsd.dwHeight = dwHeight;
00252
00253 (*ppSurface) =
new CSurface();
00254
if( FAILED( hr = (*ppSurface)->Create(
m_pDD, &ddsd ) ) )
00255 {
00256
delete (*ppSurface);
00257
return hr;
00258 }
00259
00260
return S_OK;
00261 }
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271 HRESULT
CDisplay::CreateSurfaceFromBitmap(
CSurface** ppSurface,
00272 TCHAR* strBMP,
00273 DWORD dwDesiredWidth,
00274 DWORD dwDesiredHeight )
00275 {
00276 HRESULT hr;
00277 HBITMAP hBMP = NULL;
00278 BITMAP bmp;
00279 DDSURFACEDESC2 ddsd;
00280
00281
if(
m_pDD == NULL || strBMP == NULL || ppSurface == NULL )
00282
return E_INVALIDARG;
00283
00284 *ppSurface = NULL;
00285
00286
00287 hBMP = (HBITMAP) LoadImage( GetModuleHandle(NULL), strBMP,
00288 IMAGE_BITMAP, dwDesiredWidth, dwDesiredHeight,
00289 LR_CREATEDIBSECTION );
00290
if( hBMP == NULL )
00291 {
00292 hBMP = (HBITMAP) LoadImage( NULL, strBMP,
00293 IMAGE_BITMAP, dwDesiredWidth, dwDesiredHeight,
00294 LR_LOADFROMFILE | LR_CREATEDIBSECTION );
00295
if( hBMP == NULL )
00296
return E_FAIL;
00297 }
00298
00299
00300 GetObject( hBMP,
sizeof(bmp), &bmp );
00301
00302
00303 ZeroMemory( &ddsd,
sizeof(ddsd) );
00304 ddsd.dwSize =
sizeof(ddsd);
00305 ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
00306 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
00307 ddsd.dwWidth = bmp.bmWidth;
00308 ddsd.dwHeight = bmp.bmHeight;
00309
00310 (*ppSurface) =
new CSurface();
00311
if( FAILED( hr = (*ppSurface)->Create(
m_pDD, &ddsd ) ) )
00312 {
00313
delete (*ppSurface);
00314
return hr;
00315 }
00316
00317
00318
if( FAILED( hr = (*ppSurface)->DrawBitmap( hBMP, 0, 0, 0, 0 ) ) )
00319 {
00320 DeleteObject( hBMP );
00321
return hr;
00322 }
00323
00324 DeleteObject( hBMP );
00325
00326
return S_OK;
00327 }
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337 HRESULT
CDisplay::CreateSurfaceFromText(
CSurface** ppSurface,
00338 HFONT hFont, TCHAR* strText,
00339 COLORREF crBackground, COLORREF crForeground )
00340 {
00341 HDC hDC = NULL;
00342 LPDIRECTDRAWSURFACE7 pDDS = NULL;
00343 HRESULT hr;
00344 DDSURFACEDESC2 ddsd;
00345 SIZE sizeText;
00346
00347
if(
m_pDD == NULL || strText == NULL || ppSurface == NULL )
00348
return E_INVALIDARG;
00349
00350 *ppSurface = NULL;
00351
00352 hDC = GetDC( NULL );
00353
00354
if( hFont )
00355 SelectObject( hDC, hFont );
00356
00357 GetTextExtentPoint32( hDC, strText, _tcslen(strText), &sizeText );
00358 ReleaseDC( NULL, hDC );
00359
00360
00361 ZeroMemory( &ddsd,
sizeof(ddsd) );
00362 ddsd.dwSize =
sizeof(ddsd);
00363 ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
00364 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
00365 ddsd.dwWidth = sizeText.cx;
00366 ddsd.dwHeight = sizeText.cy;
00367
00368 (*ppSurface) =
new CSurface();
00369
if( FAILED( hr = (*ppSurface)->Create(
m_pDD, &ddsd ) ) )
00370 {
00371
delete (*ppSurface);
00372
return hr;
00373 }
00374
00375
if( FAILED( hr = (*ppSurface)->DrawText( hFont, strText, 0, 0,
00376 crBackground, crForeground ) ) )
00377
return hr;
00378
00379
return S_OK;
00380 }
00381
00382
00383
00384
00385
00386
00387
00388
00389 HRESULT
CDisplay::Present()
00390 {
00391 HRESULT hr;
00392
00393
if( NULL ==
m_pddsFrontBuffer && NULL ==
m_pddsBackBuffer )
00394
return E_POINTER;
00395
00396
while( 1 )
00397 {
00398
if(
m_bWindowed )
00399 hr =
m_pddsFrontBuffer->Blt( &
m_rcWindow,
m_pddsBackBuffer,
00400 NULL, DDBLT_WAIT, NULL );
00401
else
00402 hr =
m_pddsFrontBuffer->Flip( NULL, 0 );
00403
00404
if( hr == DDERR_SURFACELOST )
00405 {
00406
m_pddsFrontBuffer->Restore();
00407
m_pddsBackBuffer->Restore();
00408 }
00409
00410
if( hr != DDERR_WASSTILLDRAWING )
00411
return hr;
00412 }
00413 }
00414
00415
00416
00417
00418
00419
00420
00421
00422 HRESULT
CDisplay::ShowBitmap( HBITMAP hbm, LPDIRECTDRAWPALETTE pPalette )
00423 {
00424
if( NULL ==
m_pddsFrontBuffer || NULL ==
m_pddsBackBuffer )
00425
return E_POINTER;
00426
00427
00428
if( pPalette )
00429
m_pddsFrontBuffer->SetPalette( pPalette );
00430
00431
CSurface backBuffer;
00432 backBuffer.
Create(
m_pddsBackBuffer );
00433
00434
if( FAILED( backBuffer.
DrawBitmap( hbm, 0, 0, 0, 0 ) ) )
00435
return E_FAIL;
00436
00437
return Present();
00438 }
00439
00440
00441
00442
00443
00444
00445
00446
00447 HRESULT
CDisplay::ColorKeyBlt( DWORD x, DWORD y, LPDIRECTDRAWSURFACE7 pdds,
00448 RECT* prc )
00449 {
00450
if( NULL ==
m_pddsBackBuffer )
00451
return E_POINTER;
00452
00453
return m_pddsBackBuffer->BltFast( x, y, pdds, prc, DDBLTFAST_SRCCOLORKEY );
00454 }
00455
00456
00457
00458
00459
00460
00461
00462
00463 HRESULT
CDisplay::Blt( DWORD x, DWORD y, LPDIRECTDRAWSURFACE7 pdds, RECT* prc,
00464 DWORD dwFlags )
00465 {
00466
if( NULL ==
m_pddsBackBuffer )
00467
return E_POINTER;
00468
00469
return m_pddsBackBuffer->BltFast( x, y, pdds, prc, dwFlags );
00470 }
00471
00472
00473
00474
00475
00476
00477
00478
00479 HRESULT
CDisplay::Blt( DWORD x, DWORD y,
CSurface* pSurface, RECT* prc )
00480 {
00481
if( NULL == pSurface )
00482
return E_INVALIDARG;
00483
00484
if( pSurface->
IsColorKeyed() )
00485
return Blt( x, y, pSurface->
GetDDrawSurface(), prc, DDBLTFAST_SRCCOLORKEY );
00486
else
00487
return Blt( x, y, pSurface->
GetDDrawSurface(), prc, 0L );
00488 }
00489
00490
00491
00492
00493
00494
00495
00496
00497 HRESULT
CDisplay::Clear( DWORD dwColor )
00498 {
00499
if( NULL ==
m_pddsBackBuffer )
00500
return E_POINTER;
00501
00502
00503 DDBLTFX ddbltfx;
00504 ZeroMemory( &ddbltfx,
sizeof(ddbltfx) );
00505 ddbltfx.dwSize =
sizeof(ddbltfx);
00506 ddbltfx.dwFillColor = dwColor;
00507
00508
return m_pddsBackBuffer->Blt( NULL, NULL, NULL, DDBLT_COLORFILL, &ddbltfx );
00509 }
00510
00511
00512
00513
00514
00515
00516
00517
00518 HRESULT
CDisplay::SetPalette( LPDIRECTDRAWPALETTE pPalette )
00519 {
00520
if( NULL ==
m_pddsFrontBuffer )
00521
return E_POINTER;
00522
00523
return m_pddsFrontBuffer->SetPalette( pPalette );
00524 }
00525
00526
00527
00528
00529
00530
00531
00532
00533 HRESULT
CDisplay::CreatePaletteFromBitmap( LPDIRECTDRAWPALETTE* ppPalette,
00534
const TCHAR* strBMP )
00535 {
00536 HRSRC hResource = NULL;
00537 RGBQUAD* pRGB = NULL;
00538 BITMAPINFOHEADER* pbi = NULL;
00539 PALETTEENTRY aPalette[256];
00540 HANDLE hFile = NULL;
00541 DWORD iColor;
00542 DWORD dwColors;
00543 BITMAPFILEHEADER bf;
00544 BITMAPINFOHEADER bi;
00545 DWORD dwBytesRead;
00546
00547
if(
m_pDD == NULL || strBMP == NULL || ppPalette == NULL )
00548
return E_INVALIDARG;
00549
00550 *ppPalette = NULL;
00551
00552
00553 hResource = FindResource( NULL, strBMP, RT_BITMAP );
00554
if( hResource )
00555 {
00556 pbi = (LPBITMAPINFOHEADER) LockResource( LoadResource( NULL, hResource ) );
00557
if( NULL == pbi )
00558
return E_FAIL;
00559
00560 pRGB = (RGBQUAD*) ( (BYTE*) pbi + pbi->biSize );
00561
00562
00563
if( pbi == NULL || pbi->biSize <
sizeof(BITMAPINFOHEADER) )
00564 dwColors = 0;
00565
else if( pbi->biBitCount > 8 )
00566 dwColors = 0;
00567
else if( pbi->biClrUsed == 0 )
00568 dwColors = 1 << pbi->biBitCount;
00569
else
00570 dwColors = pbi->biClrUsed;
00571
00572
00573
00574
for( iColor = 0; iColor < dwColors; iColor++ )
00575 {
00576 aPalette[iColor].peRed = pRGB[iColor].rgbRed;
00577 aPalette[iColor].peGreen = pRGB[iColor].rgbGreen;
00578 aPalette[iColor].peBlue = pRGB[iColor].rgbBlue;
00579 aPalette[iColor].peFlags = 0;
00580 }
00581
00582
return m_pDD->CreatePalette( DDPCAPS_8BIT, aPalette, ppPalette, NULL );
00583 }
00584
00585
00586 hFile = CreateFile( strBMP, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL );
00587
if( NULL == hFile )
00588
return E_FAIL;
00589
00590
00591 ReadFile( hFile, &bf,
sizeof(bf), &dwBytesRead, NULL );
00592
if( dwBytesRead !=
sizeof(bf) )
00593 {
00594 CloseHandle( hFile );
00595
return E_FAIL;
00596 }
00597
00598
00599 ReadFile( hFile, &bi,
sizeof(bi), &dwBytesRead, NULL );
00600
if( dwBytesRead !=
sizeof(bi) )
00601 {
00602 CloseHandle( hFile );
00603
return E_FAIL;
00604 }
00605
00606
00607 ReadFile( hFile, aPalette,
sizeof(aPalette), &dwBytesRead, NULL );
00608
if( dwBytesRead !=
sizeof(aPalette) )
00609 {
00610 CloseHandle( hFile );
00611
return E_FAIL;
00612 }
00613
00614 CloseHandle( hFile );
00615
00616
00617
if( bi.biSize !=
sizeof(BITMAPINFOHEADER) )
00618 dwColors = 0;
00619
else if (bi.biBitCount > 8)
00620 dwColors = 0;
00621
else if (bi.biClrUsed == 0)
00622 dwColors = 1 << bi.biBitCount;
00623
else
00624 dwColors = bi.biClrUsed;
00625
00626
00627
00628
for( iColor = 0; iColor < dwColors; iColor++ )
00629 {
00630 BYTE r = aPalette[iColor].peRed;
00631 aPalette[iColor].peRed = aPalette[iColor].peBlue;
00632 aPalette[iColor].peBlue = r;
00633 }
00634
00635
return m_pDD->CreatePalette( DDPCAPS_8BIT, aPalette, ppPalette, NULL );
00636 }
00637
00638
00639
00640
00641
00642
00643
00644
00645 HRESULT
CDisplay::UpdateBounds()
00646 {
00647
if(
m_bWindowed )
00648 {
00649 GetClientRect(
m_hWnd, &
m_rcWindow );
00650 ClientToScreen(
m_hWnd, (POINT*)&
m_rcWindow );
00651 ClientToScreen(
m_hWnd, (POINT*)&m_rcWindow+1 );
00652 }
00653
else
00654 {
00655 SetRect( &
m_rcWindow, 0, 0, GetSystemMetrics(SM_CXSCREEN),
00656 GetSystemMetrics(SM_CYSCREEN) );
00657 }
00658
00659
return S_OK;
00660 }
00661
00662
00663
00664
00665
00666
00667
00668
00669
00670 HRESULT
CDisplay::InitClipper()
00671 {
00672 LPDIRECTDRAWCLIPPER pClipper;
00673 HRESULT hr;
00674
00675
00676
if( FAILED( hr =
m_pDD->CreateClipper( 0, &pClipper, NULL ) ) )
00677
return hr;
00678
00679 pClipper->SetHWnd( 0,
m_hWnd );
00680
00681
if( FAILED( hr =
m_pddsFrontBuffer->SetClipper( pClipper ) ) )
00682
return hr;
00683
00684
00685
00686
SAFE_RELEASE( pClipper );
00687
00688
return S_OK;
00689 }
00690
00691
00692
00693
00694
00695
00696
00697
00698
00699 CSurface::CSurface()
00700 {
00701
m_pdds = NULL;
00702
m_bColorKeyed = NULL;
00703 }
00704
00705
00706
00707
00708
00709
00710
00711
00712 CSurface::~CSurface()
00713 {
00714
SAFE_RELEASE(
m_pdds );
00715 }
00716
00717
00718
00719
00720
00721
00722
00723
00724 HRESULT
CSurface::Create( LPDIRECTDRAWSURFACE7 pdds )
00725 {
00726
m_pdds = pdds;
00727
00728
if(
m_pdds )
00729 {
00730
m_pdds->AddRef();
00731
00732
00733
m_ddsd.dwSize =
sizeof(
m_ddsd);
00734
m_pdds->GetSurfaceDesc( &
m_ddsd );
00735 }
00736
00737
return S_OK;
00738 }
00739
00740
00741
00742
00743
00744
00745
00746
00747 HRESULT
CSurface::Create( LPDIRECTDRAW7 pDD, DDSURFACEDESC2* pddsd )
00748 {
00749 HRESULT hr;
00750
00751
00752
if( FAILED( hr = pDD->CreateSurface( pddsd, &
m_pdds, NULL ) ) )
00753
return hr;
00754
00755
00756
m_ddsd.dwSize =
sizeof(
m_ddsd);
00757
00758
00759
m_pdds->GetSurfaceDesc( &
m_ddsd );
00760
00761
return S_OK;
00762 }
00763
00764
00765
00766
00767
00768
00769
00770
00771 HRESULT
CSurface::Destroy()
00772 {
00773
SAFE_RELEASE(
m_pdds );
00774
return S_OK;
00775 }
00776
00777
00778
00779
00780
00781
00782
00783
00784
00785 HRESULT
CSurface::DrawBitmap( HBITMAP hBMP,
00786 DWORD dwBMPOriginX, DWORD dwBMPOriginY,
00787 DWORD dwBMPWidth, DWORD dwBMPHeight )
00788 {
00789 HDC hDCImage;
00790 HDC hDC;
00791 BITMAP bmp;
00792 DDSURFACEDESC2 ddsd;
00793 HRESULT hr;
00794
00795
if( hBMP == NULL ||
m_pdds == NULL )
00796
return E_INVALIDARG;
00797
00798
00799
if( FAILED( hr =
m_pdds->Restore() ) )
00800
return hr;
00801
00802
00803 ddsd.dwSize =
sizeof(ddsd);
00804
m_pdds->GetSurfaceDesc( &ddsd );
00805
00806
if( ddsd.ddpfPixelFormat.dwFlags == DDPF_FOURCC )
00807
return E_NOTIMPL;
00808
00809
00810 hDCImage = CreateCompatibleDC( NULL );
00811
if( NULL == hDCImage )
00812
return E_FAIL;
00813
00814 SelectObject( hDCImage, hBMP );
00815
00816
00817 GetObject( hBMP,
sizeof(bmp), &bmp );
00818
00819
00820 dwBMPWidth = ( dwBMPWidth == 0 ) ? bmp.bmWidth : dwBMPWidth;
00821 dwBMPHeight = ( dwBMPHeight == 0 ) ? bmp.bmHeight : dwBMPHeight;
00822
00823
00824
if( FAILED( hr =
m_pdds->GetDC( &hDC ) ) )
00825
return hr;
00826
00827 StretchBlt( hDC, 0, 0,
00828 ddsd.dwWidth, ddsd.dwHeight,
00829 hDCImage, dwBMPOriginX, dwBMPOriginY,
00830 dwBMPWidth, dwBMPHeight, SRCCOPY );
00831
00832
if( FAILED( hr =
m_pdds->ReleaseDC( hDC ) ) )
00833
return hr;
00834
00835 DeleteDC( hDCImage );
00836
00837
return S_OK;
00838 }
00839
00840
00841
00842
00843
00844
00845
00846
00847
00848 HRESULT
CSurface::DrawText( HFONT hFont, TCHAR* strText,
00849 DWORD dwOriginX, DWORD dwOriginY,
00850 COLORREF crBackground, COLORREF crForeground )
00851 {
00852 HDC hDC = NULL;
00853 HRESULT hr;
00854
00855
if(
m_pdds == NULL || strText == NULL )
00856
return E_INVALIDARG;
00857
00858
00859
if( FAILED( hr =
m_pdds->Restore() ) )
00860
return hr;
00861
00862
if( FAILED( hr =
m_pdds->GetDC( &hDC ) ) )
00863
return hr;
00864
00865
00866 SetBkColor( hDC, crBackground );
00867 SetTextColor( hDC, crForeground );
00868
00869
if( hFont )
00870 SelectObject( hDC, hFont );
00871
00872
00873 TextOut( hDC, dwOriginX, dwOriginY, strText, _tcslen(strText) );
00874
00875
if( FAILED( hr =
m_pdds->ReleaseDC( hDC ) ) )
00876
return hr;
00877
00878
return S_OK;
00879 }
00880
00881
00882
00883
00884
00885
00886
00887
00888
00889 HRESULT
CSurface::DrawBitmap( TCHAR* strBMP,
00890 DWORD dwDesiredWidth, DWORD dwDesiredHeight )
00891 {
00892 HBITMAP hBMP;
00893 HRESULT hr;
00894
00895
if(
m_pdds == NULL || strBMP == NULL )
00896
return E_INVALIDARG;
00897
00898
00899 hBMP = (HBITMAP) LoadImage( GetModuleHandle(NULL), strBMP,
00900 IMAGE_BITMAP, dwDesiredWidth, dwDesiredHeight,
00901 LR_CREATEDIBSECTION );
00902
if( hBMP == NULL )
00903 {
00904 hBMP = (HBITMAP) LoadImage( NULL, strBMP, IMAGE_BITMAP,
00905 dwDesiredWidth, dwDesiredHeight,
00906 LR_LOADFROMFILE | LR_CREATEDIBSECTION );
00907
if( hBMP == NULL )
00908
return E_FAIL;
00909 }
00910
00911
00912
if( FAILED( hr =
DrawBitmap( hBMP, 0, 0, 0, 0 ) ) )
00913 {
00914 DeleteObject( hBMP );
00915
return hr;
00916 }
00917
00918 DeleteObject( hBMP );
00919
00920
return S_OK;
00921 }
00922
00923
00924
00925
00926
00927
00928
00929
00930 HRESULT
CSurface::SetColorKey( DWORD dwColorKey )
00931 {
00932
if( NULL ==
m_pdds )
00933
return E_POINTER;
00934
00935
m_bColorKeyed = TRUE;
00936
00937 DDCOLORKEY ddck;
00938 ddck.dwColorSpaceLowValue =
ConvertGDIColor( dwColorKey );
00939 ddck.dwColorSpaceHighValue =
ConvertGDIColor( dwColorKey );
00940
00941
return m_pdds->SetColorKey( DDCKEY_SRCBLT, &ddck );
00942 }
00943
00944
00945
00946
00947
00948
00949
00950
00951
00952
00953 DWORD
CSurface::ConvertGDIColor( COLORREF dwGDIColor )
00954 {
00955
if(
m_pdds == NULL )
00956
return 0x00000000;
00957
00958 COLORREF rgbT;
00959 HDC hdc;
00960 DWORD dw = CLR_INVALID;
00961 DDSURFACEDESC2 ddsd;
00962 HRESULT hr;
00963
00964
00965
if( dwGDIColor != CLR_INVALID &&
m_pdds->GetDC(&hdc) == DD_OK)
00966 {
00967 rgbT = GetPixel(hdc, 0, 0);
00968 SetPixel(hdc, 0, 0, dwGDIColor);
00969
m_pdds->ReleaseDC(hdc);
00970 }
00971
00972
00973 ddsd.dwSize =
sizeof(ddsd);
00974 hr =
m_pdds->Lock( NULL, &ddsd, DDLOCK_WAIT, NULL );
00975
if( hr == DD_OK)
00976 {
00977 dw = *(DWORD *) ddsd.lpSurface;
00978
if( ddsd.ddpfPixelFormat.dwRGBBitCount < 32 )
00979 dw &= ( 1 << ddsd.ddpfPixelFormat.dwRGBBitCount ) - 1;
00980
m_pdds->Unlock(NULL);
00981 }
00982
00983
00984
if( dwGDIColor != CLR_INVALID &&
m_pdds->GetDC(&hdc) == DD_OK )
00985 {
00986 SetPixel( hdc, 0, 0, rgbT );
00987
m_pdds->ReleaseDC(hdc);
00988 }
00989
00990
return dw;
00991 }
00992
00993
00994
00995
00996
00997
00998
00999
01000 HRESULT
CSurface::GetBitMaskInfo( DWORD dwBitMask, DWORD* pdwShift, DWORD* pdwBits )
01001 {
01002 DWORD dwShift = 0;
01003 DWORD dwBits = 0;
01004
01005
if( pdwShift == NULL || pdwBits == NULL )
01006
return E_INVALIDARG;
01007
01008
if( dwBitMask )
01009 {
01010
while( (dwBitMask & 1) == 0 )
01011 {
01012 dwShift++;
01013 dwBitMask >>= 1;
01014 }
01015 }
01016
01017
while( (dwBitMask & 1) != 0 )
01018 {
01019 dwBits++;
01020 dwBitMask >>= 1;
01021 }
01022
01023 *pdwShift = dwShift;
01024 *pdwBits = dwBits;
01025
01026
return S_OK;
01027 }
01028
01029
01030
01031