#include <tchar.h>
#include <ddraw.h>
#pragma comment(lib, "dxguid.lib")
IDirectDraw7 *pIDirectDraw7;
IDirectDrawSurface7 *pIDirectDrawSurface7Primary;
IDirectDrawSurface7 *pIDirectDrawSurface7OffScreen;
DDSURFACEDESC2 tDDSurfaceDesc2;
HINSTANCE Hinstance = NULL;
BOOL UnInitDirectDrawC()
{
if(pIDirectDraw7)
{
IDirectDraw7_Release(pIDirectDraw7);
pIDirectDraw7 = NULL;
}
if(pIDirectDrawSurface7Primary)
{
IDirectDrawSurface_Release(pIDirectDrawSurface7Primary);
pIDirectDrawSurface7Primary = NULL;
}
if(pIDirectDrawSurface7OffScreen)
{
IDirectDrawSurface_Release(pIDirectDrawSurface7OffScreen);
pIDirectDrawSurface7OffScreen = NULL;
}
if(Hinstance)
{
FreeLibrary(Hinstance);
Hinstance = NULL;
}
return TRUE;
}
BOOL InitDirectDrawC(HWND hWnd, int Width, int Height)
{
HRESULT (WINAPI *ZRDirectDrawCreateEx)(GUID *lpGuid, LPVOID *lplpDD, REFIID iid, IUnknown FAR *pUnkOuter);
IDirectDrawClipper *pcClipper = NULL;
if((NULL == hWnd) || (0 != Width % 2) || (0 != Height % 2))
{
return FALSE;
}
do
{
Hinstance = LoadLibrary(_T("DDRAW.dll"));
ZRDirectDrawCreateEx = (void *)GetProcAddress(Hinstance, _T("DirectDrawCreateEx"));
if(ZRDirectDrawCreateEx == NULL)
{
break;
}
if(DD_OK != ZRDirectDrawCreateEx(NULL, (VOID**)&pIDirectDraw7, &IID_IDirectDraw7, NULL))
{
break;
}
if(DD_OK != IDirectDraw7_SetCooperativeLevel(pIDirectDraw7, hWnd, DDSCL_NORMAL | DDSCL_NOWINDOWCHANGES))
{
break;
}
ZeroMemory(&tDDSurfaceDesc2, sizeof(tDDSurfaceDesc2));
tDDSurfaceDesc2.dwSize = sizeof(tDDSurfaceDesc2);
tDDSurfaceDesc2.dwFlags = DDSD_CAPS;
tDDSurfaceDesc2.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
if(DD_OK != IDirectDraw7_CreateSurface(pIDirectDraw7, &tDDSurfaceDesc2, &pIDirectDrawSurface7Primary, NULL))
{
break;
}
if(DD_OK != IDirectDraw7_CreateClipper(pIDirectDraw7, 0, &pcClipper, NULL))
{
break;
}
if(DD_OK != IDirectDrawClipper_SetHWnd(pcClipper, 0, hWnd))
{
break;
}
if(DD_OK != IDirectDrawSurface_SetClipper(pIDirectDrawSurface7Primary, pcClipper))
{
break;
}
if(pcClipper)
{
IDirectDrawClipper_Release(pcClipper);
pcClipper = NULL;
}
ZeroMemory(&tDDSurfaceDesc2, sizeof(tDDSurfaceDesc2));
tDDSurfaceDesc2.dwSize = sizeof(tDDSurfaceDesc2);
tDDSurfaceDesc2.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
tDDSurfaceDesc2.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT;
tDDSurfaceDesc2.dwWidth = Width;
tDDSurfaceDesc2.dwHeight = Height;
tDDSurfaceDesc2.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT);
tDDSurfaceDesc2.ddpfPixelFormat.dwFlags = DDPF_FOURCC | DDPF_YUV;
tDDSurfaceDesc2.ddpfPixelFormat.dwFourCC = MAKEFOURCC('Y','V', '1', '2');
tDDSurfaceDesc2.ddpfPixelFormat.dwYUVBitCount = 8;
if(DD_OK != IDirectDraw7_CreateSurface(pIDirectDraw7, &tDDSurfaceDesc2, &pIDirectDrawSurface7OffScreen, NULL))
{
break;
}
return TRUE;
}while(0);
if(pcClipper)
{
IDirectDrawClipper_Release(pcClipper);
pcClipper = NULL;
}
UnInitDirectDrawC();
return FALSE;
}
BOOL DirectDrawC(LPBYTE pBuffer)
{
BOOL ddRval = FALSE;
int i = 0;
LPBYTE PtrY = NULL, PtrU = NULL, PtrV = NULL, lpSurf = NULL;
if(NULL == pBuffer)
{
return FALSE;
}
PtrY = pBuffer;
PtrU = pBuffer + tDDSurfaceDesc2.dwWidth * tDDSurfaceDesc2.dwHeight;
PtrV = pBuffer + tDDSurfaceDesc2.dwWidth * tDDSurfaceDesc2.dwHeight * 5 / 4;
lpSurf = (LPBYTE)tDDSurfaceDesc2.lpSurface;
do
{
ddRval = IDirectDrawSurface_Lock(pIDirectDrawSurface7OffScreen, NULL, &tDDSurfaceDesc2, DDLOCK_WAIT | DDLOCK_WRITEONLY, NULL);
}while(ddRval == DDERR_WASSTILLDRAWING);
if(DD_OK != ddRval)
{
return FALSE;
}
if(lpSurf)
{
for(i = 0; i < (int)tDDSurfaceDesc2.dwHeight; i++)
{
memcpy(lpSurf, PtrY, tDDSurfaceDesc2.dwWidth);
PtrY += tDDSurfaceDesc2.dwWidth;
lpSurf += tDDSurfaceDesc2.lPitch;
}
for(i = 0; i < (int)tDDSurfaceDesc2.dwHeight / 2; i++)
{
memcpy(lpSurf, PtrV, tDDSurfaceDesc2.dwWidth / 2);
PtrV += tDDSurfaceDesc2.dwWidth / 2;
lpSurf += tDDSurfaceDesc2.lPitch / 2;
}
for(i = 0; i < (int)tDDSurfaceDesc2.dwHeight / 2; i++)
{
memcpy(lpSurf, PtrU, tDDSurfaceDesc2.dwWidth / 2);
PtrU += tDDSurfaceDesc2.dwWidth / 2;
lpSurf += tDDSurfaceDesc2.lPitch / 2;
}
}
IDirectDrawSurface_Unlock(pIDirectDrawSurface7OffScreen, NULL);
IDirectDrawSurface_Blt(pIDirectDrawSurface7Primary, NULL, pIDirectDrawSurface7OffScreen, NULL, DDBLT_WAIT, NULL);
return TRUE;
}