CVS: winex/dlls/quartz vidren.c,1.8,1.9

[email protected]
Newsgroups gmane.comp.emulators.winex.cvs
Message-ID <[email protected]>
Subject: winex/dlls/quartz vidren.c,1.8,1.9Update of /var/lib/cvsd/cvsroot/winex/dlls/quartz
In directory agravaine:/tmp/cvs-serv25244/dlls/quartz

Modified Files:
	vidren.c 
Log Message:
I broke the GDI renderer by commenting out a memcpy. Fix it...


Index: vidren.c
===================================================================
RCS file: /var/lib/cvsd/cvsroot/winex/dlls/quartz/vidren.c,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -d -r1.8 -r1.9
--- vidren.c	28 Mar 2007 18:40:03 -0000	1.8
+++ vidren.c	30 Mar 2007 21:36:48 -0000	1.9
@@ -75,8 +75,157 @@
 static const CHAR VIDREN_szWndClass[] = "Wine_VideoRenderer";
 static const CHAR VIDREN_szWndName[] = "Wine Video Renderer";
 
+static HRESULT DDRender_Init(CVideoRendererImpl *This)
+{
+	typedef HRESULT (WINAPI *DirectDrawCreateProc)(LPGUID,LPDIRECTDRAW *,LPUNKNOWN);
+	static DirectDrawCreateProc pDirectDrawCreate = NULL;
+	LRESULT	res;
+
+	if (This->m_lpddraw)
+		return(S_OK);
+
+#ifndef __APPLE__
+	/* don't init ddraw before we've tested it a bit */
+	return S_OK;
+#endif
+
+	if (!pDirectDrawCreate)
+	{
+		HMODULE hmod;
+
+		hmod = LoadLibraryA("ddraw.dll");
+		if (hmod)
+		{
+			pDirectDrawCreate = (DirectDrawCreateProc)GetProcAddress(hmod, "DirectDrawCreate");
+		}
+
+		if (!pDirectDrawCreate) 
+		{
+			ERR("Can't load DirectDraw\n");
+			return E_FAIL;
+		}
+	}
+
+	res = pDirectDrawCreate(NULL, &This->m_lpddraw, NULL);
+	if (res!=S_OK || !This->m_lpddraw) 
+	{
+		ERR("Can't initialize DirectDraw (res = %lx)\n",res);
+		return res;
+	}
+
+	TRACE("ok\n");
+	return S_OK;
+}
+
+static HRESULT DDRender_Exit(CVideoRendererImpl* This)
+{
+	if (This->m_lpddraw)
+	{
+		IDirectDraw_Release(This->m_lpddraw);
+		This->m_lpddraw 	= NULL;
+		This->m_UseDirectDraw 	= 0;
+	}
+
+	TRACE("ok\n");
+	return S_OK;
+}
+
+static HRESULT DDRender_DestroySurfaces(CVideoRendererImpl *This)
+{
+	HRESULT hr;
+
+	if (This->m_pDDSFront)
+		IDirectDrawSurface_Release(This->m_pDDSFront);
+
+	if (This->m_pDDSSource)
+		IDirectDrawSurface_Release(This->m_pDDSSource);
+
+	This->m_pDDSFront	= NULL;
+	This->m_pDDSSource	= NULL;
+
+	if (This->m_lpddraw && (hr = IDirectDraw_SetCooperativeLevel(This->m_lpddraw, 0, DDSCL_NORMAL)))
+	{
+		ERR("Could not set cooperative level to normal (%lx)\n",hr);
+		return hr;
+	}
+
+	TRACE("ok\n");
+	return S_OK; 
+}
+
+static HRESULT DDRender_CreateSurfaces(CVideoRendererImpl *This, int width, int height, int depth)
+{
+	HRESULT		hr;
+	DDSURFACEDESC 	ddsd;
+
+	if (This->m_lpddraw == NULL)
+		return(DDERR_UNSUPPORTED);
+
+	if ((hr = IDirectDraw_SetCooperativeLevel(This->m_lpddraw, This->m_hwnd, DDSCL_FULLSCREEN|DDSCL_EXCLUSIVE)))
+	{
+		ERR("Could not set cooperative level to exclusive (%lx)\n",hr);
+		return hr;
+	}
+
+	TRACE("Creating surface %dx%dx%d\n", width, height, depth);
+
+	/* Clear all members of the structure to 0 */
+	memset(&ddsd, 0, sizeof(ddsd));
+	/* The first parameter of the structure must contain the size of the structure */
+	ddsd.dwSize = sizeof(ddsd);
+
+	/* -- Create the primary surface */
 
+	/* The dwFlags paramater tell DirectDraw which DDSURFACEDESC */
+	/*  fields will contain valid values */
 
+	ddsd.ddsCaps.dwCaps 			= DDSCAPS_PRIMARYSURFACE;
+	ddsd.dwFlags 				= DDSD_CAPS;
+
+	hr = IDirectDraw_CreateSurface(This->m_lpddraw, &ddsd, &This->m_pDDSFront, NULL);
+	if (hr != S_OK)
+		return hr;
+
+	TRACE("Created %p\n", This->m_pDDSFront);
+
+	/* -- Create the source surface */
+	ddsd.ddsCaps.dwCaps			= DDSCAPS_OFFSCREENPLAIN;
+	ddsd.dwFlags				= DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
+	ddsd.dwWidth				= width;
+	ddsd.dwHeight				= height;
+
+	ddsd.ddpfPixelFormat.dwSize		= sizeof(DDPIXELFORMAT);
+	ddsd.ddpfPixelFormat.dwFlags		= DDPF_RGB;
+	ddsd.ddpfPixelFormat.u1.dwRGBBitCount	= (DWORD)depth*8;
+	ddsd.ddpfPixelFormat.u2.dwRBitMask	= 0x00FF0000;
+	ddsd.ddpfPixelFormat.u3.dwGBitMask	= 0x0000FF00;
+	ddsd.ddpfPixelFormat.u4.dwBBitMask	= 0x000000FF;
+
+	hr = IDirectDraw_CreateSurface(This->m_lpddraw, &ddsd, &This->m_pDDSSource, NULL);
+	if (hr != S_OK)
+		return hr;
+		
+	This->m_Width = width;
+	This->m_Height = height;
+
+	TRACE("ok\n");
+
+	return S_OK; 
+}
+
+static void DDRender_Render(CVideoRendererImpl *This, int left, int top, int right, int bottom, int movW, int movH)
+{
+	HRESULT		hr;
+	RECT		rcSrc;	/* source blit rectangle */
+	RECT		rcDst;	/* destination blit rectangle */
+
+	SetRect(&rcSrc, 0, 0, movW, movH);		/* movie size */
+	SetRect(&rcDst, left, top, right, bottom);	/* screen size */
+
+	hr = IDirectDrawSurface_Blt(This->m_pDDSFront, &rcDst, This->m_pDDSSource, &rcSrc, DDBLT_WAIT, NULL);
+
+	TRACE("ok\n");
+}
 
 static void VIDREN_DrawFrame( CVideoRendererImpl* This, HWND hwnd, HDC hdc, BYTE* pData )
 {
@@ -121,15 +270,38 @@
 			pData, (BITMAPINFO*)(&pinfo->bmiHeader),
 			DIB_RGB_COLORS, SRCCOPY );
 	else
-		StretchBlt(
-			hdc,
-			(width - abs(pinfo->bmiHeader.biWidth)) / 2,
-			(height - abs(pinfo->bmiHeader.biHeight)) / 2,
-			abs(pinfo->bmiHeader.biWidth), abs(pinfo->bmiHeader.biHeight),
-			This->m_hMemDC,
-			0, 0,
-			abs(pinfo->bmiHeader.biWidth), abs(pinfo->bmiHeader.biHeight),
-			SRCCOPY );
+	{
+		if (This->m_UseDirectDraw)
+		{
+			RECT		rect;
+#if 1 /* if fullscreen */
+			DDSURFACEDESC	Desc;
+			Desc.dwSize = sizeof(Desc);
+			IDirectDrawSurface_GetSurfaceDesc(This->m_pDDSFront, &Desc);
+			SetRect(&rect, 0, 0, Desc.dwWidth, Desc.dwHeight);
+#else /* if windowed */
+			GetClientRect(hwnd, &rect);
+			MapWindowPoints(hwnd, 0, (LPPOINT)&rect, 2);
+#endif
+
+			DDRender_Render(	This,
+						rect.left,	rect.top,
+						rect.right, 	rect.bottom,
+						abs(pinfo->bmiHeader.biWidth), abs(pinfo->bmiHeader.biHeight));
+		}
+		else
+		{
+			StretchBlt(
+				hdc,
+				(width - abs(pinfo->bmiHeader.biWidth)) / 2,
+				(height - abs(pinfo->bmiHeader.biHeight)) / 2,
+				abs(pinfo->bmiHeader.biWidth), abs(pinfo->bmiHeader.biHeight),
+				This->m_hMemDC,
+				0, 0,
+				abs(pinfo->bmiHeader.biWidth), abs(pinfo->bmiHeader.biHeight),
+				SRCCOPY );
+		}
+	}
 }
 
 static void VIDREN_OnPaint( CVideoRendererImpl* This, HWND hwnd )
@@ -203,7 +375,38 @@
 	if (lLength > (LONG)This->m_cbSampleData)
 		lLength = This->m_cbSampleData;
 
-	memcpy(This->m_pSampleData,pData,lLength);
+	if (This->m_UseDirectDraw)
+	{
+		DDSURFACEDESC	Desc;
+		/* memcpy(This->m_pSampleData,pData,lLength); */
+		Desc.dwSize = sizeof(Desc);
+		if (IDirectDrawSurface_Lock(This->m_pDDSSource, NULL, &Desc, DDLOCK_WAIT, 0) == S_OK)
+		{
+			int y;
+
+			LPBYTE	Src = (LPBYTE)pData;
+			LPBYTE	Dst = (LPBYTE)Desc.lpSurface;
+
+			Dst += Desc.u1.lPitch*Desc.dwHeight;
+
+			for (y=0; y<Desc.dwHeight; y++)
+			{
+				Dst -= Desc.u1.lPitch;
+				memcpy(Dst, Src, Desc.dwWidth * sizeof(DWORD));
+				Src += Desc.dwWidth * sizeof(DWORD);
+			}
+			IDirectDrawSurface_Unlock(This->m_pDDSSource, NULL);
+		}
+		else
+		{
+			TRACE("Surface lock failed\n");
+		}
+	}
+	else
+	{
+		memcpy(This->m_pSampleData,pData,lLength);
+	}
+
 	This->m_bSampleIsValid = TRUE;
 	This->m_bSampleNeedView = TRUE;
 	if (hwnd) PostMessageA( hwnd, VIDRENMSG_UPDATE, 0, 0 );
@@ -583,6 +786,16 @@
 	if ( FAILED(hr) )
 		return hr;
 
+	This->pRender->m_UseDirectDraw = 0;
+	DDRender_DestroySurfaces(This->pRender);
+	if (DDRender_CreateSurfaces(This->pRender, abs(pinfo->bmiHeader.biWidth), abs(pinfo->bmiHeader.biHeight), 4) == S_OK)
+	{
+		TRACE("Rendering with DirectDraw\n");
+		This->pRender->m_UseDirectDraw = 1;
+	}
+	else
+		WARN("DirectDraw not available - Rendering with GDI\n");
+
 	return NOERROR;
 }
 
@@ -619,6 +832,8 @@
 		This->meminput.pAllocator = NULL;
 	}
 
+	DDRender_DestroySurfaces(This->pRender);
+
 	return NOERROR;
 }
 
@@ -633,26 +848,20 @@
 		return E_FAIL;
 	if ( !IsEqualGUID( &pmt->formattype, &FORMAT_VideoInfo ) )
 		return E_FAIL;
+
 	/*
 	 * check subtype.
 	 */
-	if ( !IsEqualGUID( &pmt->subtype, &MEDIASUBTYPE_RGB555 ) &&
-	     !IsEqualGUID( &pmt->subtype, &MEDIASUBTYPE_RGB565 ) &&
-	     !IsEqualGUID( &pmt->subtype, &MEDIASUBTYPE_RGB24 ) &&
-	     !IsEqualGUID( &pmt->subtype, &MEDIASUBTYPE_RGB32 ) )
+#ifdef __APPLE__
+	if ( !IsEqualGUID( &pmt->subtype, &MEDIASUBTYPE_RGB32 ) )
 		return E_FAIL;
-
-	/****
-	 *
-	 *
-	if ( !IsEqualGUID( &pmt->subtype, &MEDIASUBTYPE_RGB8 ) &&
-	     !IsEqualGUID( &pmt->subtype, &MEDIASUBTYPE_RGB555 ) &&
+#else
+	if ( !IsEqualGUID( &pmt->subtype, &MEDIASUBTYPE_RGB555 ) &&
 	     !IsEqualGUID( &pmt->subtype, &MEDIASUBTYPE_RGB565 ) &&
 	     !IsEqualGUID( &pmt->subtype, &MEDIASUBTYPE_RGB24 ) &&
 	     !IsEqualGUID( &pmt->subtype, &MEDIASUBTYPE_RGB32 ) )
 		return E_FAIL;
-	 *
-	 ****/
+#endif
 
 	pinfo = (const VIDEOINFOHEADER*)pmt->pbFormat;
 	if ( pinfo == NULL ||
@@ -1029,6 +1238,9 @@
 	This->m_pSample = NULL;
 	This->m_numFrames = 0;
 	This->m_skipFrames = 0;
+	This->m_pDDSFront = NULL;
+	This->m_pDDSSource = NULL;
+	This->m_lpddraw = NULL;
 
 	QUARTZ_IUnkInit( &This->unk, punkOuter );
 	This->qiext.pNext = NULL;
@@ -1630,12 +1842,17 @@
 	TRACE("(%p)\n",This);
 	ICOM_VTBL(&This->basvid) = &ibasicvideo;
 
+	DDRender_Init(This);
+
 	return NOERROR;
 }
 
 void CVideoRendererImpl_UninitIBasicVideo( CVideoRendererImpl* This )
 {
 	TRACE("(%p)\n",This);
+
+	DDRender_DestroySurfaces(This);
+	DDRender_Exit(This);
 }
 
 /***************************************************************************
@@ -2320,7 +2537,7 @@
 	DWORD	dwStyle;
 	RECT	rc;
 
-	FIXME("(%p)->(%08x)\n",This,hwnd);
+	FIXME("(%p)->(0x%08lx)\n",This,hwnd);
 
 	EnterCriticalSection ( &This->basefilter.csFilter );
 	if ( This->m_hwnd == (HWND)NULL )
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.