/* DDSurface.h ****************************************************************
Author: Paul Watt, Copyright (c) 2002
Date: 9/29/2001
Purpose:
******************************************************************************/
#if !defined(AFX_DDSURFACE_H__C4C1824D_3173_4021_8C39_FE1706277249__INCLUDED_)
#define AFX_DDSURFACE_H__C4C1824D_3173_4021_8C39_FE1706277249__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include <windows.h>
#include <ddraw.h>
#include <MEMORY>
using std::auto_ptr;
/* Class **********************************************************************
Author: Paul Watt
Date: 9/29/2001
Purpose: This class will represent a basic Direct Draw surface for use with
drawing DriectDraw.
******************************************************************************/
class DDSurface
{
friend DDSurface* CreateSurface(IDirectDraw7 *pDirectDraw, UINT nBufferCount);
protected:
IDirectDrawSurface7 *m_pSurface;
DDSURFACEDESC2 m_ddsd;
HWND m_hWnd;
HDC m_hDC;
DDSurface();
// HRESULT GetDC(void);
// HRESULT ReleaseDC(void);
public:
HRESULT GetDC(void);
HRESULT ReleaseDC(void);
HDC GetH ()
{
GetDC();
return m_hDC;
}
/* Constructor / Destructor **************************************************/
virtual ~DDSurface();
virtual bool Attach(IDirectDrawSurface7 *pSurface);
virtual bool Detach(IDirectDrawSurface7 **ppSurface);
virtual HRESULT Initialize(IDirectDraw7 *pDirectDraw, UINT nBufferCount);
virtual void Release(void);
BYTE * Lock (RECT * pRect=NULL);
HRESULT Unlock(RECT * pRect=NULL);
HRESULT Restore();
/* Cast operators ************************************************************/
operator IDirectDrawSurface7* &()
{
return m_pSurface;
}
operator HDC()
{
return m_hDC;
}
/* Member access functions ***************************************************/
int GetWidth(void) const;
int GetHeight(void) const;
int GetPitch(void) const;
void GetOrigin (POINT &ptOrigin) const;
HWND GetWindow();
HWND SetWindow(HWND hNewWindow);
void GetSurfaceDesc(DDSURFACEDESC2 &ddsd);
/* Surface maintenence functions *********************************************/
HRESULT CreatePrimarySurface(IDirectDraw7 * pDD, int nBackBuffer);
virtual HRESULT RestoreSurface(void); // restore surface if lost
HRESULT SetClipper(LPDIRECTDRAWCLIPPER lpDDClipper);
HRESULT DrawBitmap(const BITMAPINFO * pDIB, int x, int y, int width, int height);
HRESULT FillColor (RECT *pDest, DWORD dwFillColor);
HRESULT GetSourceColorKey(DWORD &color);
HRESULT SetSourceColorKey(DWORD color);
HRESULT Blt (LPRECT lpDestRect, DDSurface *pddSurface, LPRECT lpSrcRect, DWORD dwFlags, LPDDBLTFX lpDDBltFx);
HRESULT BltFast(DWORD dwX, DWORD dwY, DDSurface *pddSurface, LPRECT lpSrcRect, DWORD dwTrans);
HRESULT Flip (DDSurface *pddSurface, DWORD dwFlags);
HRESULT GetAttachedSurface(DDSCAPS2 &DDSCaps, DDSurface **ppddAttachedSurface);
};
typedef auto_ptr<DDSurface> auto_DDSurface;
/* Class **********************************************************************
Author: Paul Watt
Date: 11/9/2001
Purpose: The offscreen surface class is useful for general purpose drawing
and creation of bitmaps.
******************************************************************************/
class DDOffScreenSurface : public DDSurface
{
friend DDOffScreenSurface* CreateOffScreenSurface(IDirectDraw7 *pDirectDraw, DWORD dwWidth, DWORD dwHeight);
friend DDOffScreenSurface* CreateOffScreenSurface(IDirectDraw7 *pDirectDraw, const BITMAPINFO * pDIB);
friend DDOffScreenSurface* CreateOffScreenSurface(IDirectDraw7 *pDirectDraw, const TCHAR *pszFileName);
protected:
DDOffScreenSurface();
public:
virtual ~DDOffScreenSurface();
virtual HRESULT Initialize(IDirectDraw7 *pDirectDraw, UINT nBufferCount);
virtual HRESULT Initialize(IDirectDraw7 *pDirectDraw, DWORD dwWidth, DWORD dwHeight);
virtual HRESULT Initialize(IDirectDraw7 *pDirectDraw, const BITMAPINFO * pDIB);
};
typedef auto_ptr<DDOffScreenSurface> auto_DDOffScreenSurface;
/* DDSurface implementation **************************************************/
/* Public *********************************************************************
Author: Paul Watt
Date: 5/4/2002
Purpose: Restores memory allocation for a lost video surface.
Parameters: NONE
Return: HRESULT indicates the status of this function.
******************************************************************************/
inline HRESULT DDSurface::Restore()
{
return m_pSurface->Restore();
}
/* Public *********************************************************************
Author: Paul Watt
Date: 9/29/2001
Purpose: Returns the width of this surface.
Parameters: NONE
Return: -
******************************************************************************/
inline int DDSurface::GetWidth(void) const
{
return m_ddsd.dwWidth;
}
/* Public *********************************************************************
Author: Paul Watt
Date: 9/29/2001
Purpose: Returns the height of this surface.
Parameters: NONE
Return: -
******************************************************************************/
inline int DDSurface::GetHeight(void) const
{
return m_ddsd.dwHeight;
}
/* Global *********************************************************************
Author: Paul Watt
Date: 9/29/2001
Purpose:
Parameters:
Return:
******************************************************************************/
inline int DDSurface::GetPitch(void) const
{
return m_ddsd.lPitch;
}
/* Public *********************************************************************
Author: Paul Watt
Date: 10/6/2001
Purpose: Returns the origin of this surface. If this surface represents a
window, then the surface will be the origin of the client area,
otherwise the origin will be (0,0);
Parameters: ptOrigin[in/out]: a reference to the point that will accept the
origin position.
Return: -
******************************************************************************/
inline void DDSurface::GetOrigin (POINT &ptOrigin) const
{
//C: Test which type of surface this is.
if (NULL == m_hWnd)
{
ptOrigin.x = 0;
ptOrigin.y = 0;
}
else
{
RECT rClient;
::GetClientRect(m_hWnd, &rClient);
ptOrigin.x = rClient.left;
ptOrigin.y = rClient.top;
::ClientToScreen(m_hWnd, &ptOrigin);
}
}
/* Public *********************************************************************
Author: Paul Watt
Date: 4/20/2002
Purpose: Returns the handle of the window that this surface is associated with.
Parameters: NONE
Return: -
******************************************************************************/
inline HWND DDSurface::GetWindow()
{
}
/* Public *********************************************************************
Author: Paul Watt
Date: 4/20/2002
Purpose: Sets the handle of the window that this surface is associated with.
This is inportant because the surface will automatically provide
surface offset support relating to the window.
Parameters: hNewWindow[in]: Handle to the new window. This value may be NULL.
Return: Returns the previous window handle associated with this surface.
******************************************************************************/
inline HWND DDSurface::SetWindow(HWND hNewWindow)
{
HWND hWndOld = m_hWnd;
m_hWnd = hNewWindow;
return hWndOld;
}
/* Public *********************************************************************
Author: Paul Watt
Date: 5/19/2002
Purpose: Returns the surface description for this surface.
Parameters: ddsd[out]: A reference to a DDSURFACEDESC2 structure that will
accept the result.
Return: -
******************************************************************************/
inline void DDSurface::GetSurfaceDesc(DDSURFACEDESC2 &ddsd)
{
ddsd = m_ddsd;
}
/* Protected ******************************************************************
Author: Paul Watt
Date: 9/29/2001
Purpose: Retreives a DC for use with this surface.
Parameters: NONE
Return: HRESULT indicating the status fo this function.
******************************************************************************/
inline HRESULT DDSurface::GetDC(void)
{
if (m_hDC)
{
return S_OK;
}
return m_pSurface->GetDC(&m_hDC);
}
/* Protected ******************************************************************
Author: Paul Watt
Date: 9/29/2001
Purpose: Releases any DC that was received from the window that this surface
represents.
Parameters: NONE
Return: HRESULT indicating the status of this function.
******************************************************************************/
inline HRESULT DDSurface::ReleaseDC(void)
{
if (!m_hDC)
{
return S_OK;
}
HRESULT hr = m_pSurface->ReleaseDC(m_hDC);
m_hDC = NULL;
return hr;
}
/* Public *********************************************************************
Author: Paul Watt
Date: 4/6/2002
Purpose: Draws a bitmap onto this surface. This method works through the
GDI, therefore it is slow, and it is only recommended to use this
function for initializing the surface.
Parameters: pDIB[in]: The bitmap databits.
x[in]:
y[in]:
width[in]:
height[in]:
Return: HRESULT indicating the status of this function.
******************************************************************************/
inline HRESULT DDSurface::DrawBitmap(const BITMAPINFO * pDIB, int x, int y, int width, int height)
{
//C: Verify input parameters.
if (!pDIB)
{
return E_INVALIDARG;
}
//C: Insure that the DC has been allocated for this object.
if (SUCCEEDED(GetDC()))
{
#pragma message( REMIND( "PMW: Turn this into a function" ) )
const BITMAPINFOHEADER *bmih = &pDIB->bmiHeader;
DWORD dwCount;
if ( bmih->biBitCount <= 8 )
{
if ( bmih->biClrUsed )
{
dwCount = bmih->biClrUsed;
}
else
{
dwCount = 1 << bmih->biBitCount;
}
}
else if ( bmih->biCompression==BI_BITFIELDS )
{
dwCount = 3 + bmih->biClrUsed;
}
else
{
dwCount = bmih->biClrUsed;
}
//C: Blt the bitmap to the surface.
StretchDIBits (
m_hDC,
x, y,
width, height,
0, 0,
pDIB->bmiHeader.biWidth, pDIB->bmiHeader.biHeight,
& pDIB->bmiColors[dwCount],
pDIB,
DIB_RGB_COLORS,
SRCCOPY
);
//C: Release the DC.
return ReleaseDC();
}
else
{
return E_FAIL;
}
}
/* Public *********************************************************************
Author: Paul Watt
Date: 4/6/2002
Purpose: Sets the source color key for blt operations.
Parameters: color[in]: The color to set for the key.
Return: HRESULT indicates the status of this function.
******************************************************************************/
inline HRESULT DDSurface::GetSourceColorKey(DWORD &color)
{
DDCOLORKEY key;
//C: Set the color key.
HRESULT hr = m_pSurface->GetColorKey(DDCKEY_SRCBLT, &key);
//C: Get the color. For a color key, the high and the low value
// should be equal, we will simply use the low value.
color = key.dwColorSpaceLowValue;
return hr;
}
/* Public *********************************************************************
Author: Paul Watt
Date: 4/6/2002
Purpose: Sets the source color key for blt operations.
Parameters: color[in]: The color to set for the key.
Return: HRESULT indicates the status of this function.
******************************************************************************/
inline HRESULT DDSurface::SetSourceColorKey(DWORD color)
{
DDCOLORKEY key;
//C: By setting these two values = it tells the surface that there
// is only one color.
key.dwColorSpaceLowValue = color;
key.dwColorSpaceHighValue = color;
//C: Set the color key.
return m_pSurface->SetColorKey(DDCKEY_SRCBLT, &key);
}
/* Public *********************************************************************
Author: Paul Watt
Date: 11/9/2001
Purpose: Blts the data from the pddSurface to this surface.
Parameters: lpDestRect[in]:
pddSurface[in]:
lpSrcRect[in]:
dwFlags[in]:
lpDDBltFx[in]:
Return: HRESULT indicating the status of this function.
******************************************************************************/
inline HRESULT DDSurface::Blt(LPRECT lpDestRect, DDSurface *pddSurface, LPRECT lpSrcRect, DWORD dwFlags, LPDDBLTFX lpDDBltFx)
{
//C: Offset the dimensions for the destination.
ClientToScreen(m_hWnd, (POINT*)lpDestRect);
ClientToScreen(m_hWnd, ((POINT*)lpDestRect) + 1);
//C: Offset the dimensions for the source if it exists.
if (NULL != pddSurface && NULL != lpSrcRect)
{
ClientToScreen(pddSurface->m_hWnd, (POINT*)lpSrcRect);
ClientToScreen(pddSurface->m_hWnd, ((POINT*)lpSrcRect) + 1);
}
IDirectDrawSurface7* pSurface = (NULL == pddSurface ? NULL : pddSurface->m_pSurface);
return m_pSurface->Blt(lpDestRect, pSurface, lpSrcRect, dwFlags, lpDDBltFx);
}
/* Public *********************************************************************
Author: Paul Watt
Date: 11/7/2001
Purpose: Access function to blit.
Parameters: Blts the data from pddSurface this surface.
dwX[in]:
dwY[in]:
pddSurface[in]:
lpSrcRect[in]:
dwFlags[in]:
dwTrans[in]:
Return: HRESULT indicating the status of this function.
******************************************************************************/
inline HRESULT DDSurface::BltFast(DWORD dwX, DWORD dwY, DDSurface *pddSurface, LPRECT lpSrcRect, DWORD dwTrans)
{
IDirectDrawSurface7* pSurface = (NULL == pddSurface ? NULL : pddSurface->m_pSurface);
return m_pSurface->BltFast(dwX, dwY, pSurface, lpSrcRect, dwTrans);
}
/* Public *********************************************************************
Author: Paul Watt
Date: 11/16/2001
Purpose: Flips memory pages on the video card. This function will only
work for a surface that has exclusive full-screen mode.
Parameters: pddSurface[in]:
dwFlags[in]:
Return: HRESULT indicating the status of this function.
******************************************************************************/
inline HRESULT DDSurface::Flip(DDSurface *pddSurface, DWORD dwFlags)
{
IDirectDrawSurface7* pSurface = (NULL == pddSurface ? NULL : pddSurface->m_pSurface);
return m_pSurface->Flip(pSurface, dwFlags);
}
/* Public *********************************************************************
Author: Paul Watt
Date: 11/16/2001
Purpose: Retrieves a surface that is attached to this surface with the
attributes specified in lpDDSCaps.
Parameters: DDSCaps[in]:
pddAttachedSurface[in/out]: Address of a pointer that will accept
the newly created surface.
Return: An HRESULT will be returned to indicate the status of this function.
******************************************************************************/
inline HRESULT DDSurface::GetAttachedSurface(DDSCAPS2 &DDSCaps, DDSurface **ppddAttachedSurface)
{
//C: Verify input parameters.
if (NULL == ppddAttachedSurface)
{
return E_FAIL;
}
//C: Initialize output parameters.
*ppddAttachedSurface = NULL;
//C: Get the attached surface from this surface.
LPDIRECTDRAWSURFACE7 pAttachedSurface;
HRESULT hr = m_pSurface->GetAttachedSurface(&DDSCaps, &pAttachedSurface);
if (FAILED(hr))
{
return hr;
}
//C: Create a blank DDSurface object and attach the newly created
// surface to it.
*ppddAttachedSurface = new DDSurface;
if (NULL == *ppddAttachedSurface)
{
pAttachedSurface->Release();
return E_FAIL;
}
(*ppddAttachedSurface)->Attach(pAttachedSurface);
//C: Return success.
return S_OK;
}
/* DDOffScreenSurface implementation *****************************************/
/* Global functions **********************************************************/
DDSurface* CreateSurface(IDirectDraw7 *pDirectDraw, UINT nBufferCount);
DDOffScreenSurface* CreateOffScreenSurface(IDirectDraw7 *pDirectDraw, DWORD dwWidth, DWORD dwHeight);
DDOffScreenSurface* CreateOffScreenSurface(IDirectDraw7 *pDirectDraw, const BITMAPINFO * pDIB);
DDOffScreenSurface* CreateOffScreenSurface(IDirectDraw7 *pDirectDraw, const TCHAR *pszFileName);
#endif // !defined(AFX_DDSURFACE_H__C4C1824D_3173_4021_8C39_FE1706277249__INCLUDED_)