21#pragma comment(lib,"ddraw.lib")
22#pragma comment(lib,"dxguid.lib")
35struct TPhReleaseSurface
37 void operator()(LPDIRECTDRAWSURFACE7 P) { P->Release(); }
82 int Pos(
int x,
int y)
const
111 CSurface(
void) : m_isRentBuffer(false), m_hDC(NULL)
121 CSurface(LPDIRECTDRAWSURFACE7 pSurface) : m_hpSurface(pSurface)
144 other.m_ReleaseRent();
145 m_hpSurface = other.m_hpSurface;
146 m_primarySize = other.m_primarySize;
147 m_bitsPixel = other.m_bitsPixel;
148 m_isRentBuffer =
false;
159 void Attach(LPDIRECTDRAWSURFACE7 pSurface)
162 m_hpSurface = pSurface;
174 HRESULT
Create(IDirectDraw7* pDraw, LPDDSURFACEDESC2 pDdsd)
177 LPDIRECTDRAWSURFACE7 P;
178 HRESULT r = pDraw->CreateSurface(pDdsd, &P, NULL);
205 return ! m_hpSurface.IsNull();
215 return m_primarySize;
223 operator LPDIRECTDRAWSURFACE7(
void)
225 DEBUG_ONLY( m_ReleaseRent() );
236 DEBUG_ONLY( m_ReleaseRent() );
250 HRESULT
BltFast(
int x,
int y, LPDIRECTDRAWSURFACE7 lpDdsSrc,
const RECT& srcRect, DWORD dwTrans = 0)
253 HRESULT hr = m_hpSurface->BltFast(x, y, lpDdsSrc, &rc, DDBLTFAST_WAIT | dwTrans);
254 if ( hr == DDERR_SURFACELOST )
256 m_hpSurface->Restore();
257 hr = m_hpSurface->BltFast(x, y, lpDdsSrc, &rc, DDBLTFAST_WAIT | dwTrans);
273 HRESULT
BltFastClip(
int x,
int y, LPDIRECTDRAWSURFACE7 lpDdsSrc,
const RECT& srcRect, DWORD dwTrans = 0)
276 int width = rc.right - rc.left;
277 int height = rc.bottom - rc.top;
284 else if ( m_primarySize.cx < x + width )
286 rc.right -= (x + width - m_primarySize.cx);
293 else if ( m_primarySize.cy < y + height)
295 rc.bottom -= (y + height - m_primarySize.cy);
298 return BltFast(x, y, lpDdsSrc, rc, dwTrans);
310 HRESULT
Blt(
const RECT& dstRect, LPDIRECTDRAWSURFACE7 lpDdsSrc,
const RECT& srcRect, DWORD dwTrans = 0)
314 HRESULT hr = m_hpSurface->Blt(&rc1, lpDdsSrc, &rc2, DDBLT_WAIT | dwTrans, NULL);
315 if ( hr == DDERR_SURFACELOST )
317 m_hpSurface->Restore();
318 hr = m_hpSurface->Blt(&rc1, lpDdsSrc, &rc2, DDBLT_WAIT | dwTrans, NULL);
333 HRESULT
BltClip(
const RECT& dstRect, LPDIRECTDRAWSURFACE7 lpDdsSrc,
const RECT& srcRect, DWORD dwTrans = 0)
335 RECT dstRc = dstRect;
336 RECT srcRc = srcRect;
337 SIZE dstSz = { dstRc.right - dstRc.left, dstRc.bottom - dstRc.top };
338 SIZE srcSz = { srcRc.right - srcRc.left, srcRc.bottom - srcRc.top };
339 const LONG par = 1024;
340 LONG parHeight = dstSz.cx * par / srcSz.cx;
341 LONG parWidth = dstSz.cy * par / srcSz.cy;
343 int w1 = dstRc.right - m_clipRect.right;
346 srcRc.right -= w1 * par / parWidth;
349 int w2 = dstRc.left - m_clipRect.left;
352 srcRc.left -= w2 * par / parWidth;
355 int h1 = dstRc.bottom - m_clipRect.bottom;
358 srcRc.bottom -= h1 * par / parHeight;
361 int h2 = dstRc.top - m_clipRect.top;
364 srcRc.top -= h2 * par / parHeight;
368 return Blt(dstRc, lpDdsSrc, srcRc, dwTrans);
381 if (
IsValid() && m_hDC == NULL )
384 if ( m_hpSurface->GetDC(&m_hDC) == DD_OK )
398 if (
IsValid() && m_hDC != NULL )
400 m_hpSurface->ReleaseDC(m_hDC);
415 if (
IsValid() && ! m_isRentBuffer )
418 DDSURFACEDESC2 ddsd = {
sizeof(DDSURFACEDESC2) };
419 if ( m_hpSurface->Lock(NULL, &ddsd, DDLOCK_WAIT, NULL) == DD_OK )
421 m_buffer.
size = m_primarySize;
422 m_buffer.
pitch = ddsd.lPitch / m_bitsPixel * 8;
424 m_buffer.
pB8 =
static_cast<BYTE*
>(ddsd.lpSurface);
425 m_isRentBuffer =
true;
438 if (
IsValid() && m_isRentBuffer )
440 m_hpSurface->Unlock(NULL);
441 m_isRentBuffer =
false;
459 void m_CheckSpec(
void)
463 DDSURFACEDESC2 ddsd = {
sizeof(DDSURFACEDESC2) };
464 DDPIXELFORMAT ddpf = {
sizeof(DDPIXELFORMAT) };
465 if ( m_hpSurface->GetSurfaceDesc(&ddsd) == DD_OK && m_hpSurface->GetPixelFormat(&ddpf) == DD_OK )
467 DWORD f = DDSD_WIDTH | DDSD_HEIGHT;
468 if ( (ddsd.dwFlags & f) == f )
470 m_primarySize.cx = ddsd.dwWidth;
471 m_primarySize.cy = ddsd.dwHeight;
472 ::SetRect(&m_clipRect, 0, 0, m_primarySize.cx, m_primarySize.cy);
473 m_bitsPixel = ddpf.dwRGBBitCount;
478 m_primarySize.cx = 0;
479 m_primarySize.cy = 0;
480 ::SetRectEmpty(&m_clipRect);
484 void m_ReleaseRent(
void)
490 CSurfaceHandle m_hpSurface;
506 CDirectDraw(
void) : m_pDraw(NULL), m_isFull(false), m_pClip(NULL), m_hDC(NULL), m_pGetBuffSurface(NULL)
508 m_primarySize.cx = 0;
509 m_primarySize.cy = 0;
535 if ( m_isFull != isFull )
537 if ( m_pDraw != NULL )
541 return m_CreateSurface();
570 bool SetSize(
const SIZE& primarySize,
const SIZE& backSize)
572 m_primarySize = primarySize;
573 m_backSize = backSize;
574 if ( m_pDraw != NULL )
577 return m_CreateSurface();
591 bool Create(HWND hWnd,
int bitsPixel = -1)
597 DEVMODE dm = {
sizeof(DEVMODE) };
598 if ( ! ::EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &dm) )
602 bitsPixel = dm.dmBitsPerPel;
604 m_bitsPixel = bitsPixel;
605 C_ASSERT( DD_OK == 0 );
606 if ( ::DirectDrawCreateEx(NULL,
reinterpret_cast<void**
>(&m_pDraw), IID_IDirectDraw7, NULL) != DD_OK )
610 if ( ! m_CreateSurface() )
625 if ( m_backbufferSurface.
IsValid() && m_hDC != NULL )
640 return m_primarySize;
660 if ( m_pDraw != NULL )
662 DDSURFACEDESC2 ddsd = {
sizeof(DDSURFACEDESC2) };
663 if ( m_pDraw->GetDisplayMode(&ddsd) == DD_OK )
665 return (ddsd.lPitch / ddsd.dwWidth) * 8;
670 DEVMODE dm = {
sizeof(DEVMODE) };
671 if ( ::EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &dm) )
673 return dm.dmBitsPerPel;
688 void SetOffset(
int x,
int y,
int magnificX,
int magnificY)
692 m_magnific.x = magnificX;
693 if ( m_magnific.x < 1 )
697 m_magnific.y = magnificY;
698 if ( m_magnific.y < 1 )
721 m_magnific.x = magnific;
722 m_magnific.y = magnific;
736 if ( m_primarySurface.
IsValid() && ! m_isFull )
739 ::ClientToScreen(m_hWnd, &po);
740 RECT r2 = { 0, 0, m_primarySize.cx, m_primarySize.cy };
742 ::OffsetRect(&r1, po.x, po.y);
743 r2.right /= m_magnific.x;
744 r2.bottom /= m_magnific.y;
745 ::OffsetRect(&r2, m_offset.x, m_offset.y);
746 m_pDraw->WaitForVerticalBlank(DDWAITVB_BLOCKBEGIN, 0);
748 return m_primarySurface.
BltClip(r1, m_benchSurface, r2) == DD_OK;
764 if ( m_primarySurface.
IsValid() )
769 r = m_primarySurface->Flip(0, DDFLIP_WAIT) == DD_OK;
774 r = m_benchSurface->
BltFast(0, 0, m_backbufferSurface, NULL, DDBLTFAST_WAIT) == DD_OK;
790 if ( m_pDraw != NULL )
792 m_pDraw->WaitForVerticalBlank(DDWAITVB_BLOCKBEGIN, 0);
804 if ( m_primarySurface.
IsValid() )
806 return m_backbufferSurface->
BltFast(0, 0, m_baseSurface, NULL, DDBLTFAST_WAIT) == DD_OK;
817 return m_backbufferSurface;
820 CSurface CreateWorkSurfase(
int height,
int width)
823 DDSURFACEDESC2 ddsd = {
sizeof(DDSURFACEDESC2) };
824 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT ;
825 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY;
826 ddsd.dwWidth = (height > 0) ? height : m_backSize.cx;
827 ddsd.dwHeight = (width > 0) ? width : m_backSize.cy;
828 surf.Create(m_pDraw, &ddsd);
835 void m_DestroySurface(
void)
837 m_Release(m_baseSurface);
838 m_Release(m_backbufferSurface);
839 m_Release(m_benchSurface);
840 m_Release(m_primarySurface);
845 bool m_CreateSurface(
void)
848 ASSERT( m_pDraw != NULL );
849 DDSURFACEDESC2 ddsd = {
sizeof(DDSURFACEDESC2) };
855 res |= m_pDraw->SetCooperativeLevel(m_hWnd, DDSCL_FULLSCREEN | DDSCL_EXCLUSIVE);
857 res |= m_pDraw->SetDisplayMode(m_primarySize.cx, m_primarySize.cy, m_bitsPixel, 0, 0);
859 ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;
860 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_FLIP | DDSCAPS_COMPLEX;
861 ddsd.dwBackBufferCount = 1;
862 res |= m_primarySurface.
Create(m_pDraw, &ddsd);
866 DDSCAPS2 ddscaps = { 0 };
867 ddscaps.dwCaps=DDSCAPS_BACKBUFFER;
868 LPDIRECTDRAWSURFACE7 pSur = NULL;
869 res |= m_primarySurface->GetAttachedSurface(&ddscaps, &pSur);
870 m_backbufferSurface.
Attach(pSur);
872 ddsd.dwWidth = m_primarySize.cx;
873 ddsd.dwHeight = m_primarySize.cy;
879 m_pDraw->SetCooperativeLevel(m_hWnd, DDSCL_NORMAL);
881 DEVMODE dm = {
sizeof(DEVMODE) };
882 if ( ::EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &dm) )
884 dm.dmBitsPerPel = m_bitsPixel;
885 dm.dmFields = DM_BITSPERPEL;
886 if ( ::ChangeDisplaySettings(&dm, CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL )
896 res |= m_pDraw->CreateClipper(0, &m_pClip, NULL);
899 res |= m_pClip->SetHWnd(0, m_hWnd);
901 ddsd.dwFlags = DDSD_CAPS;
902 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
903 res |= m_primarySurface.
Create(m_pDraw, &ddsd);
907 res |= m_primarySurface->SetClipper(m_pClip);
910 ::GetClipCursor(&nowClipRect);
913 ::GetClipCursor(&allClipRect);
914 ::ClipCursor(&nowClipRect);
917 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
918 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY;
919 ddsd.dwWidth = m_backSize.cx;
920 ddsd.dwHeight = m_backSize.cy;
921 res |= m_backbufferSurface.
Create(m_pDraw, &ddsd);
923 res |= m_benchSurface.
Create(m_pDraw, &ddsd);
930 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
931 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY;
932 res |= m_baseSurface.
Create(m_pDraw, &ddsd);
944 template<
typename TYP>
945 void m_Release(TYP*& P)
955 void m_Release(CSurface& P)
967 LPDIRECTDRAW7 m_pDraw;
968 CSurface m_primarySurface;
969 CSurface m_backbufferSurface;
970 CSurface m_benchSurface;
973 CSurface m_baseSurface;
976 LPDIRECTDRAWCLIPPER m_pClip;
980 LPDIRECTDRAWSURFACE7 m_pGetBuffSurface;
HRESULT BltClip(const RECT &dstRect, LPDIRECTDRAWSURFACE7 lpDdsSrc, const RECT &srcRect, DWORD dwTrans=0)
[描画] クリッピング Blt.
void Attach(LPDIRECTDRAWSURFACE7 pSurface)
[登録] アタッチ.
HRESULT BltFast(int x, int y, LPDIRECTDRAWSURFACE7 lpDdsSrc, const RECT &srcRect, DWORD dwTrans=0)
[描画] BltFast.
CSurface & operator=(CSurface &other)
コピーオペレータ.
void ReleaseBuffer(void)
[取得] バッファ返却.
HRESULT Create(IDirectDraw7 *pDraw, LPDDSURFACEDESC2 pDdsd)
[作成] 作成.
void ReleaseDC(void)
[取得] HDC 返却.
HRESULT BltFastClip(int x, int y, LPDIRECTDRAWSURFACE7 lpDdsSrc, const RECT &srcRect, DWORD dwTrans=0)
[描画] クリッピング BltFast.
bool IsValid(void) const
[確認] 有効確認.
LPDIRECTDRAWSURFACE7 operator->(void)
[参照] 参照.
HDC GetDC(void)
[取得] HDC 取得.
void Destroy(void)
[破棄] 破棄.
const SIZE & GetSize(void) const
[取得] サイズ取得.
HRESULT Blt(const RECT &dstRect, LPDIRECTDRAWSURFACE7 lpDdsSrc, const RECT &srcRect, DWORD dwTrans=0)
[描画] Blt.
CSurface(CSurface &other)
コピーコンストラクタ.
const TBuffer * GetBuffer(void)
[取得] バッファ取得.
CSurface(LPDIRECTDRAWSURFACE7 pSurface)
コンストラクタ.
void SetClipRect(const RECT &rect)
[設定] クリッピング範囲設定.
const SIZE & GetBackbufferSize(void) const
[取得] バックバッファサーフェスのサイズ取得.
bool SetFullScreenMode(bool isFull)
[設定] フルスクリーンモード設定.
bool Flip(void)
[処理] フィリップ.
bool ClearBackbufferSurface(void)
[描画] バックバッファクリア
bool Redraw(void)
[表示] 再表示.
bool SetSize(const SIZE &size)
[設定] サイズ設定.
void SetOffset(int x, int y, int magnificX, int magnificY)
[設定] オフセット設定.
bool SetSize(const SIZE &primarySize, const SIZE &backSize)
[設定] サイズ設定.
void Destroy(void)
[破棄] 破棄.
CSurface & GetBackbufferSurface(void)
[取得] バックバッファ取得.
void SetOffset(int x=0, int y=0, int magnific=1)
[設定] オフセット設定.
const SIZE & GetPrimarySize(void) const
[取得] プライマリサーフェスのサイズ取得.
void WaitForVerticalBlank(void)
[処理] 垂直同期待ち.
int GetBitsPixel(void) const
[取得] ピクセル BIT 数取得.
bool Create(HWND hWnd, int bitsPixel=-1)
[作成] 作成.
RGBTRIPLE * pB24
bitsPixel が24の時
int Pos(int x, int y) const
[取得] ポジション計算.
RGBQUAD * pB32
bitsPixel が32の時
int bitsPixel
一ピクセルの bit数。 8, 16, 32。
WORD * pB16
bitsPixel が16の時