windraw2.cpp
上传用户:zhongxx05
上传日期:2007-06-06
资源大小:33641k
文件大小:169k
- if (lpwd == NULL || lpwds == NULL || lpImageFormat == NULL ||
- nBackBuffers > MAX_BACKBUFFERCOUNT || lpwd->hWnd == NULL ||
- !(lpwd->fMode & WINDRAW_OPENED) || (lpwds->fMode & WINDRAWSURFACE_OPENED))
- return E_INVALIDARG;
-
- /* check image format: */
- sz = lpImageFormat->bmiHeader.biSize;
- memset (lpwds, 0, sizeof (WINDRAWSURFACE));
- if (sz < (int)sizeof(BITMAPINFOHEADER) || sz > (int)sizeof(BMI) ||
- (lpwds->cidSurfaceColor = GetBitmapColor((LPBITMAPINFO)lpImageFormat)) == CID_UNKNOWN)
- return E_INVALIDARG;
-
- /* initialize WinDrawSurface structure: */
- memcpy (&(lpwds->bmiSurfaceFormat), lpImageFormat, sz); /* Flawfinder: ignore */
- lpwds->dwBackBufferCount = nBackBuffers;
-
- /* check type of surface we will need to create: */
- if (fSurfaceType & WINDRAWSURFACE_DIRECTDRAW)
- {
- return WinDraw2_CreateDDSurface(lpwd, lpwds, lpImageFormat, fSurfaceType, nBackBuffers, dwCKey);
- }
- else
- {
- return WinDraw2_CreateGDISurface(lpwd, lpwds, lpImageFormat, fSurfaceType, nBackBuffers, dwCKey);
- }
- }
- /*
- * Creates a new surface to be used for image data.
- * Use:
- * HRESULT WinDraw2_CreateSurface (LPWINDRAW lpwd, LPWINDRAWSURFACE lpwds,
- * LPBMI lpImageFormat, DWORD fSurfaceType, int nBackBuffers, DWORD dwCKey);
- * Input:
- * lpwd - pointer to a base WINDRAW structure
- * lpwds - pointer to a WINDRAWSURFACE structure to initialize
- * lpImageFormat - pointer to BITMAPINFO structure describing image format
- * fSurfaceType - combination of desired properties for a surface
- * nBackBuffers - number of flippable backbuffers to allocate for this surface
- * dwCKey - a color key to use (if transparent surface)
- * Returns:
- * NOERROR if OK, or the last relevant DirectDraw error code, or E_FAIL.
- */
- HRESULT Windraw_AttachSurface(LPWINDRAW lpwd, LPWINDRAWSURFACE lpwds,
- BITMAPINFOHEADER* lpImageFormat, void* pImageData)
- {
- HRESULT retVal = E_INVALIDARG;
-
-
- /* check parameters: */
- if (lpwd == NULL || lpwds == NULL || lpImageFormat == NULL ||
- lpwd->hWnd == NULL || !(lpwd->fMode & WINDRAW_OPENED) ||
- !(lpwds->fMode & WINDRAWSURFACE_OPENED))
- return retVal;
-
- /* check type of surface we will need to create: */
- if (lpwds->fMode & WINDRAWSURFACE_DIRECTDRAW)
- {
- DDSURFACEDESC ddsd;
- ZeroMemory(&ddsd, sizeof(ddsd));
- ddsd.dwSize = sizeof(ddsd);
- ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_PITCH | DDSD_LPSURFACE | DDSD_PIXELFORMAT;
- ddsd.dwHeight = lpImageFormat->biHeight;
- ddsd.dwWidth = lpImageFormat->biWidth;
- ddsd.lPitch = GetBitmapPitch((LPBITMAPINFO)lpImageFormat);
- ddsd.lpSurface = pImageData;
-
- SetDirectDrawColor(&ddsd.ddpfPixelFormat, GetBitmapColor((LPBITMAPINFO)lpImageFormat));
-
- IDirectDrawSurface3* pSurf3 = NULL;
-
- if (SUCCEEDED(lpwds->dd.lpDDSurface->QueryInterface(IID_IDirectDrawSurface3, (void**)&pSurf3)))
- {
- try
- {
- retVal = pSurf3->SetSurfaceDesc(&ddsd, 0);
- }
- catch(...)
- {
- DumpDDInfo(lpwd, lpwds->dd.lpDDSurface, "Windraw_AttachSurface");
- retVal = HXR_FAIL;
- }
- pSurf3->Release();
- }
- return retVal;
- }
- else
- {
- return retVal;
- }
- }
- /*
- * Adds alpha data to a specified surface.
- * Use:
- * HRESULT WinDraw2_AttachAlphaSurface (LPWINDRAW lpwd, LPWINDRAWSURFACE lpwds,
- * UCHAR* pAlphaData);
- * Input:
- * lpwd - pointer to a base WINDRAW structure
- * lpwds - pointer to a WINDRAWSURFACE structure to initialize
- * Returns:
- * NOERROR if OK, or the last relevant DirectDraw error code, or E_FAIL.
- */
- HRESULT WinDraw2_CreateAlphaSurface(LPWINDRAW lpwd, LPWINDRAWSURFACE lpwds)
- {
- /* check parameters: */
- if (lpwd == NULL || lpwds == NULL || lpwd->hWnd == NULL ||
- !(lpwd->fMode & WINDRAW_OPENED) || (!(lpwds->fMode & WINDRAWSURFACE_OPENED)))
- return E_INVALIDARG;
-
- if (lpwds->fMode & WINDRAWSURFACE_DIRECTDRAW)
- {
- /* blit DirectDraw surfaces: */ ;
- } else
- { /* GDI: */
- GDISURFACE* pGDISurf = lpwds->gdi.lpGDIBackBuffer [FRONTBUFFER];
- pGDISurf->lpAlphaSurface = (UCHAR*) malloc(pGDISurf->DibSection.dsBmih.biWidth * pGDISurf->DibSection.dsBmih.biHeight);
- }
-
- return NOERROR;
- }
- /*
- * Adds alpha data to a specified surface.
- * Use:
- * HRESULT WinDraw2_AttachAlphaSurface (LPWINDRAW lpwd, LPWINDRAWSURFACE lpwds,
- * UCHAR* pAlphaData);
- * Input:
- * lpwd - pointer to a base WINDRAW structure
- * lpwds - pointer to a WINDRAWSURFACE structure to initialize
- * Returns:
- * NOERROR if OK, or the last relevant DirectDraw error code, or E_FAIL.
- */
- HRESULT WinDraw2_GetAlphaSurface(LPWINDRAW lpwd, LPWINDRAWSURFACE lpwds, UCHAR** pSurface)
- {
- /* check parameters: */
- if (lpwd == NULL || lpwds == NULL || lpwd->hWnd == NULL ||
- !(lpwd->fMode & WINDRAW_OPENED) || (!(lpwds->fMode & WINDRAWSURFACE_OPENED)))
- return E_INVALIDARG;
-
- if (lpwds->fMode & WINDRAWSURFACE_DIRECTDRAW)
- {
- /* blit DirectDraw surfaces: */ ;
- } else
- { /* GDI: */
- GDISURFACE* pGDISurf = lpwds->gdi.lpGDIBackBuffer [FRONTBUFFER];
- *pSurface = pGDISurf->lpAlphaSurface;
- }
-
- return NOERROR;
- }
- /*
- * Release a WinDraw surface.
- * Use:
- * HRESULT WinDraw2_ReleaseSurface (LPWINDRAW lpwd, LPWINDRAWSURFACE lpwds);
- * Input:
- * lpwd - pointer to a base WINDRAW structure
- * lpwds - pointer to a WINDRAWSURFACE structure to remove
- * Returns:
- * NOERROR if OK, or the last relevant DirectDraw error code, or E_FAIL.
- */
- HRESULT WinDraw2_ReleaseSurface (LPWINDRAW lpwd, LPWINDRAWSURFACE lpwds)
- {
- /* check parameters: */
- if (lpwd == NULL || lpwds == NULL || lpwd->hWnd == NULL ||
- !(lpwd->fMode & WINDRAW_OPENED) || !(lpwds->fMode & WINDRAWSURFACE_OPENED))
- return E_INVALIDARG;
-
- /* check if DirectDraw surface: */
- if (lpwds->fMode & WINDRAWSURFACE_DIRECTDRAW)
- {
- if (lpwds->dd.lpChain)
- {
- for (int i=0; i<(int)lpwds->dwBackBufferCount+1; i++)
- {
- // Wait until the flip has been called on this surface
- WaitForSingleObject(lpwds->dd.lpChain[i].hEmpty, INFINITE);
- CloseHandle(lpwds->dd.lpChain[i].hEmpty);
- }
- CloseHandle(lpwds->dd.hAbort);
- lpwds->dd.hAbort = 0;
- delete [] lpwds->dd.lpChain;
- lpwds->dd.lpChain = NULL;
- CloseHandle(lpwds->hOverlayIndexMutex);
- CloseHandle(lpwds->hOverlayMutex);
- lpwds->hOverlayIndexMutex = 0;
- lpwds->hOverlayMutex = 0;
- lpwds->dwFrontBuffer = 0;
- lpwds->dwNextBuffer = 0;
- }
- /* release DirectDraw objects: */ ;
- int res;
-
- try
- {
- res = lpwds->dd.lpDDSurface->Release();
- }
- catch(...)
- {
- DumpDDInfo(lpwd, lpwds->dd.lpDDSurface, "WinDraw2_ReleaseSurface");
- res = 0;
- }
-
- lpwds->dd.lpDDSurface = 0;
- lpwds->dd.lpDDBackBuffer = 0;
- } else
- { /* GDI: */
- int i;
- /* release GDI surfaces: */
- for (i=lpwds->dwBackBufferCount; i>=0; i--)
- {
- if (lpwds->gdi.lpGDIBackBuffer [i] != NULL) {
- GDISurface_Free(lpwds->gdi.lpGDIBackBuffer [i]);
- lpwds->gdi.lpGDIBackBuffer [i] = NULL;
- }
- }
- }
-
- /* reset mode & exit: */
- lpwds->fMode = 0;
-
- LISTPOSITION pos = lpwd->m_pSurfaceList->Find(lpwds);
- if (pos)
- lpwd->m_pSurfaceList->RemoveAt(pos);
- lpwds->dwBackBufferCount = 0;
-
- return NOERROR;
- }
- HRESULT WinDraw2_GetMonitorProperties (LPWINDRAW lpwd)
- {
- HRESULT hr;
- DWORD dwTemp = 0;
- if (!lpwd || !lpwd->dd.lpDD2)
- return E_FAIL;
- lpwd->ulBadConsecutiveVblankCount = 0;
- lpwd->dwMaxScanLine = 0;
- lpwd->dwReportedHeight = GetSystemMetrics(SM_CYSCREEN);
- LARGE_INTEGER llStart,
- llTime,
- llTemp;
- llStart.QuadPart = 0;
- llTime.QuadPart = 0;
- llTemp.QuadPart = 0;
- QueryPerformanceFrequency(&llTemp);
- LONGLONG llClockFreq = llTemp.QuadPart;
- // Try to get the max scan line but limit the time spent
- // in the loop. Some cards always return 0 from GetScanLine.
- QueryPerformanceCounter(&llStart);
- do
- {
- hr = lpwd->dd.lpDD2->GetScanLine(&dwTemp);
-
- if (DD_OK == hr ||
- DDERR_VERTICALBLANKINPROGRESS == hr)
- {
- // The G400 occasionally reports an obscenely high value here;
- // we filter to 130% of the reported display height
- if (dwTemp > lpwd->dwMaxScanLine
- && dwTemp <= lpwd->dwReportedHeight*1.3)
- lpwd->dwMaxScanLine = dwTemp;
- }
- else
- break;
- QueryPerformanceCounter(&llTime);
- if ((llTime.QuadPart - llStart.QuadPart)*1000 / llClockFreq > 1000)
- break;
- } while (dwTemp >= lpwd->dwMaxScanLine);
- // GetScanLine problem
- if (!lpwd->dwMaxScanLine)
- return HXR_FAIL;
- // Set max scan line to a max of the line and screen screen height
- // we assume a minimum of one vblank line; max line is zero based
- lpwd->dwMaxScanLine = max(lpwd->dwMaxScanLine, (DWORD)GetSystemMetrics(SM_CYSCREEN));
- //HX_TRACE("Max scan line: %lun", lpwd->dwMaxScanLine);
- // Query the monitor's refresh rate
- lpwd->dd.lpDD2->GetMonitorFrequency(&dwTemp);
- //HX_TRACE("Reported refresh rate: %lun", dwTemp);
- if (dwTemp)
- {
- lpwd->dRefreshRate = dwTemp;
- lpwd->dMsPerVBlank = 1000.0 / lpwd->dRefreshRate;
- }
- // Approximate the refresh rate
- const int LIST_SIZE = 6;
- LONGLONG aList[LIST_SIZE],
- llAvgVBlank = 0;
- lpwd->dd.lpDD2->WaitForVerticalBlank(DDWAITVB_BLOCKBEGIN, NULL);
- QueryPerformanceCounter(&llStart);
- // Grab the times for LIST_SIZE vblanks
- for (int i=0; i<LIST_SIZE; i++)
- {
- hr = lpwd->dd.lpDD2->WaitForVerticalBlank(DDWAITVB_BLOCKBEGIN, NULL);
- if (DD_OK == hr)
- {
- QueryPerformanceCounter(&llTime);
- aList[i] = llTime.QuadPart;
- if (i>0)
- {
- llAvgVBlank += aList[i] - aList[i-1];
- }
- }
- }
- llAvgVBlank /= LIST_SIZE-1;
- LONGLONG llModAvg = 0;
- int nCount = 0;
- // Weed out bogus values
- for (i=0; i<LIST_SIZE; i++)
- {
- if (i>0)
- {
- if (abs((int)(aList[i] - aList[i-1] - llAvgVBlank)) <= .3 * llAvgVBlank)
- {
- ++nCount;
- llModAvg += aList[i] - aList[i-1];
- }
- }
- }
- LONGLONG llTmp = llStart.QuadPart,
- llTmp1 = llTime.QuadPart;
- double dEstRate = (double)(nCount*llClockFreq) / (llModAvg);
- //HX_TRACE("Estimated refresh rate: %fn", dEstRate);
- // Map to a common refresh rate
- const int BASE_RATES = 5;
- double dBestRate = -1;
- double aRateList[BASE_RATES] = {24, 25, 29.97, 30, 85};
- double dBestError = 100.0,
- dError;
-
- // Try 10x base rates
- for (int j=1; j<11; j++)
- {
- for (i=0; i<BASE_RATES; i++)
- {
- dError = dEstRate - aRateList[i]*j;
- if (fabs(dError) < dBestError)
- {
- dBestError = fabs(dError);
- dBestRate = aRateList[i]*j;
- }
- }
- }
- //HX_TRACE("Best refresh rate match: %fn", dBestRate);
- // If we are within 1.5% if a known rate, use it. This will not handle
- // cases where the estimate is *closer* to reality than the reported rate
- // due to integer truncation or rounding in GetMonitorFrequency().
- // We do, however, handle 29.97 below.
- if (dBestRate > -1 &&
- dBestError / dBestRate <= .015)
- dEstRate = dBestRate;
- // Compare estimate with DD value and use estimate
- // if the the two are not close.
- if (fabs(dEstRate - lpwd->dRefreshRate) > 5
- || dEstRate == 29.97) // Special case 29.97; Windows reports
- // integer frequencies.
- {
- lpwd->dRefreshRate = dEstRate;
- lpwd->dMsPerVBlank = 1000.0 / lpwd->dRefreshRate;
- }
- //HX_TRACE("Final refresh rate chosen: %fn", lpwd->dRefreshRate);
- return NOERROR;
- }
- /*
- * Get WinDrawSurface capabilities.
- * Use:
- * HRESULT WinDrawSurface_GetCaps (LPWINDRAW lpwd, LPWINDRAWSURFACE lpwds,
- * DWORD *lpdwCaps);
- * Input:
- * lpwd - pointer to a WINDRAW structure to query
- * lpwds - pointer to a WINDRAWSURFACE structure to query
- * lpdwCaps - a variable to contain WinDrawSurface capabilities
- * Returns:
- * NOERROR if OK, or the last relevant DirectDraw error code, or E_FAIL.
- */
- HRESULT WinDrawSurface_GetCaps (LPWINDRAW lpwd, LPWINDRAWSURFACE lpwds,
- DWORD *lpdwCaps)
- {
- /* check parameters: */
- if (lpwd == NULL || lpwds == NULL || lpdwCaps == NULL || lpwd->hWnd == NULL ||
- !(lpwd->fMode & WINDRAW_OPENED) || !(lpwds->fMode & WINDRAWSURFACE_OPENED))
- return E_INVALIDARG;
-
- /* store surface caps and exit: */
- *lpdwCaps = lpwds->fMode;
- return NOERROR;
- }
- HRESULT Windraw_GetCaps(LPWINDRAW lpwd, UINT32* pfSurfaceCaps, UINT32* nMin, UINT32* nMax)
- {
- /* check parameters: */
- if (lpwd == NULL || pfSurfaceCaps == NULL || !(lpwd->fMode & WINDRAW_OPENED) || !(lpwd->fMode & WINDRAW_DIRECTDRAW))
- return E_INVALIDARG;
-
- HRESULT hr = NOERROR;
-
- /* Get the current device caps */
- if (lpwd->dd.lpDD2)
- {
- memset(&lpwd->dd.m_caps, 0, sizeof(DDCAPS));
- lpwd->dd.m_caps.dwSize = sizeof(DDCAPS_DX3);
-
- try
- {
- lpwd->dd.lpDD2->GetCaps(&(lpwd->dd.m_caps), 0);
- }
- catch(...)
- {
- DumpDDInfo(lpwd, lpwd->dd.lpDDSPrimary, "Windraw_GetCaps");
- hr = HXR_FAIL;
- memset(&lpwd->dd.m_caps, 0, sizeof(DDCAPS));
- }
- }
-
- *pfSurfaceCaps = 0;
- if (lpwd->dd.m_caps.dwCaps & DDCAPS_OVERLAY)
- {
- *pfSurfaceCaps |= HX_OVERLAY;
- }
-
- if (lpwd->dd.m_caps.dwCaps & DDCAPS_OVERLAYSTRETCH)
- {
- *pfSurfaceCaps |= HX_OVERLAY_STRETCH;
- }
-
- if (lpwd->dd.m_caps.dwCaps & DDCAPS_BLTFOURCC)
- {
- *pfSurfaceCaps |= HX_BLTFOURCC;
- }
-
- *nMin = lpwd->dd.m_caps.dwMinOverlayStretch;
- *nMax = lpwd->dd.m_caps.dwMaxOverlayStretch;
-
- return hr;
- }
- /*
- * Get WinDrawSurface format.
- * Use:
- * HRESULT WinDrawSurface_GetFormat (LPWINDRAW lpwd, LPWINDRAWSURFACE lpwds,
- * LPBMI lpbiSurfaceFormat);
- * Input:
- * lpwd - pointer to a WINDRAW structure to query
- * lpwds - pointer to a WINDRAWSURFACE structure to query
- * lpbiFormat - a structure to contain surface resolution and color format
- * Returns:
- * NOERROR if OK, or the last relevant DirectDraw error code, or E_FAIL.
- */
- HRESULT WinDrawSurface_GetFormat (LPWINDRAW lpwd, LPWINDRAWSURFACE lpwds,
- LPBMI lpbiSurfaceFormat)
- {
- int sz;
-
- /* check parameters: */
- if (lpwd == NULL || lpwds == NULL ||
- !(lpwd->fMode & WINDRAW_OPENED) || !(lpwds->fMode & WINDRAWSURFACE_OPENED) ||
- lpbiSurfaceFormat == NULL)
- return E_INVALIDARG;
-
- /* check the size of BITMAPINFO structure to copy: */
- sz = lpbiSurfaceFormat->bmiHeader.biSize;
- if (sz < (int)sizeof(BITMAPINFOHEADER) || sz > (int)lpwds->bmiSurfaceFormat.bmiHeader.biSize)
- sz = lpwds->bmiSurfaceFormat.bmiHeader.biSize;
-
- /* copy bitmap info: */
- memcpy(lpbiSurfaceFormat, &(lpwds->bmiSurfaceFormat), sz); /* Flawfinder: ignore */
- return NOERROR;
- }
- /*
- * Locks pointer to a buffer.
- * Use:
- * HRESULT WinDrawSurface_Lock (LPWINDRAW lpwd, LPWINDRAWSURFACE lpwds,
- * int nBufferNo, LPVOID *lpSurfPtr, LONG *lplSurfPitch);
- * Input:
- * lpwd - pointer to a base WINDRAW structure
- * lpwds - pointer to a WINDRAWSURFACE structure to lock
- * nBufferNo - # of the surface buffer to lock
- * lpSurfPtr - a variable to contain a base pointer to the surface's data
- * lplSurfPitch - a variable to contain the pitch of the surface
- * Returns:
- * NOERROR if OK, or the last relevant DirectDraw error code, or E_FAIL.
- * Notes:
- * This functions shall be called before copying data into the surface.
- * Unlock it as soon as you are done with moving data in!!!
- */
- HRESULT WinDrawSurface_Lock (LPWINDRAW lpwd, LPWINDRAWSURFACE lpwds,
- int nBufferNo, LPVOID *lpSurfPtr, LONG *lplSurfPitch)
- {
- /* check parameters: */
- if (lpwd == NULL || lpwds == NULL || nBufferNo > (int)lpwds->dwBackBufferCount ||
- lpSurfPtr == NULL || lplSurfPitch == NULL || lpwd->hWnd == NULL ||
- !(lpwd->fMode & WINDRAW_OPENED) || !(lpwds->fMode & WINDRAWSURFACE_OPENED))
- return E_INVALIDARG;
-
- /* check if DirectDraw surface: */
- if (lpwds->fMode & WINDRAWSURFACE_DIRECTDRAW)
- {
- /* lock DirectDraw surfaces: */
- DDSURFACEDESC ddsd;
- ZeroMemory(&ddsd, sizeof(DDSURFACEDESC));
- ddsd.dwSize = sizeof(DDSURFACEDESC);
- ddsd.dwFlags= DDSD_PITCH;
-
- LPDIRECTDRAWSURFACE lpDDSurface = NULL;
- if (lpwds->dd.lpDDBackBuffer)
- {
- lpDDSurface = lpwds->dd.lpDDBackBuffer;
- if (!lpDDSurface)
- return E_INVALIDARG;
- // For backbuffer locking, we need to keep our locks consistent
- // with videosurface2 locks since we are possibly here after a switch.
- if (DD_OK == LockSurface(lpwd, lpDDSurface, &ddsd, TRUE))
- {
- *lplSurfPitch = ddsd.lPitch;
- lpwds->dd.lpSurfaceData = *lpSurfPtr = (void*) ddsd.lpSurface;
- return NOERROR;
- }
- if (DDERR_WRONGMODE == lpDDSurface->Restore())
- {
- return DDERR_WRONGMODE;
- }
- if (DD_OK == LockSurface(lpwd, lpDDSurface, &ddsd, TRUE))
- {
- /*
- * Consider checking DDSCAPS_VISIBLE if this is not set (and it is not on NT)
- * then something is SERIOUSLY MESSED UP!
- */
- *lplSurfPitch = ddsd.lPitch;
- lpwds->dd.lpSurfaceData = *lpSurfPtr = (void*) ddsd.lpSurface;
- return NOERROR;
- }
- }
- else
- {
- lpDDSurface = lpwds->dd.lpDDSurface;
- if (!lpDDSurface)
- return E_INVALIDARG;
- HRESULT hr;
- try
- {
- hr = lpDDSurface->Lock(NULL, &ddsd, DDLOCK_WAIT, NULL);
- }
- catch(...)
- {
- DumpDDInfo(lpwd, lpwds->dd.lpDDSurface, "WinDrawSurface_Lock");
- hr = HXR_FAIL;
- *lplSurfPitch = 0;
- lpwds->dd.lpSurfaceData = NULL;
- return hr;
- }
- if (DD_OK == hr)
- {
- /*
- * Consider checking DDSCAPS_VISIBLE if this is not set (and it is not on NT)
- * then something is SERIOUSLY MESSED UP!
- */
- *lplSurfPitch = ddsd.lPitch;
- lpwds->dd.lpSurfaceData = *lpSurfPtr = (void*) ddsd.lpSurface;
- return NOERROR;
- }
- if (DDERR_WRONGMODE == lpDDSurface->Restore())
- {
- return DDERR_WRONGMODE;
- }
- try
- {
- hr = lpDDSurface->Lock(NULL, &ddsd, DDLOCK_WAIT, NULL);
- }
- catch(...)
- {
- DumpDDInfo(lpwd, lpwds->dd.lpDDSurface, "WinDrawSurface_Lock");
- hr = HXR_FAIL;
- *lplSurfPitch = 0;
- lpwds->dd.lpSurfaceData = NULL;
- return hr;
- }
- if (DD_OK == hr)
- {
- /*
- * Consider checking DDSCAPS_VISIBLE if this is not set (and it is not on NT)
- * then something is SERIOUSLY MESSED UP!
- */
- *lplSurfPitch = ddsd.lPitch;
- lpwds->dd.lpSurfaceData = *lpSurfPtr = (void*) ddsd.lpSurface;
- return NOERROR;
- }
- }
-
- } else { /* GDI: */
-
- /* check requested GDI surface: */
- if (lpwds->gdi.lpGDIBackBuffer [nBufferNo] != NULL) {
-
- /* retrieve parameters and exit: */
- *lpSurfPtr = lpwds->gdi.lpGDIBackBuffer [nBufferNo]->lpBase;
- *lplSurfPitch = lpwds->gdi.lPitch;
- return NOERROR;
- }
- }
- return E_FAIL;
- }
- /*
- * Unlocks the buffer.
- * Use:
- * HRESULT WinDrawSurface_Lock (LPWINDRAW lpwd, LPWINDRAWSURFACE lpwds,
- * int nBufferNo, LPVOID *lpSurfPtr, LONG *lplSurfPitch);
- * Input:
- * lpwd - pointer to a base WINDRAW structure
- * lpwds - pointer to a WINDRAWSURFACE structure to unlock
- * nBufferNo - # of the surface buffer to unlock
- * Returns:
- * NOERROR if OK, or the last relevant DirectDraw error code, or E_FAIL.
- */
- HRESULT WinDrawSurface_Unlock (LPWINDRAW lpwd, LPWINDRAWSURFACE lpwds,
- int nBufferNo)
- {
- /* check parameters: */
- if (lpwd == NULL || lpwds == NULL ||
- nBufferNo > (int)lpwds->dwBackBufferCount || lpwd->hWnd == NULL ||
- !(lpwd->fMode & WINDRAW_OPENED) || !(lpwds->fMode & WINDRAWSURFACE_OPENED))
- return E_INVALIDARG;
-
- /* check if DirectDraw surface: */
- if (lpwds->fMode & WINDRAWSURFACE_DIRECTDRAW)
- {
- /* unlock DirectDraw surfaces: */ ;
-
- LPDIRECTDRAWSURFACE lpDDSurface = NULL;
- if (lpwds->dd.lpDDBackBuffer)
- {
- lpDDSurface = lpwds->dd.lpDDBackBuffer;
- }
- else
- {
- lpDDSurface = lpwds->dd.lpDDSurface;
- }
-
- try
- {
- if (DD_OK == lpDDSurface->Unlock(lpwds->dd.lpSurfaceData))
- {
- lpwds->dd.lpSurfaceData = NULL;
- if (lpwds->dd.lpDDBackBuffer)
- {
- HRESULT res = lpwds->dd.lpDDSurface->Flip(NULL, 0);
- }
- return NOERROR;
- }
- }
- catch(...)
- {
- DumpDDInfo(lpwd, lpwds->dd.lpDDSurface, "WinDrawSurface_Unlock");
- return HXR_FAIL;
- }
- }
- else
- { /* GDI: */
- /* check requested GDI surface: */
- if (lpwds->gdi.lpGDIBackBuffer [nBufferNo] != NULL) {
-
- /* unlock GDI surface & exit: */
- return NOERROR;
- }
- }
- return E_FAIL;
- }
- /*
- * Gives a DC to the surface.
- * Use:
- * HRESULT WinDrawSurface_GetDC(LPWINDRAW lpwd, LPWINDRAWSURFACE lpwds,
- * HDC* pDC);
- * Input:
- * lpwd - pointer to a base WINDRAW structure
- * lpwds - pointer to a WINDRAWSURFACE structure to unlock
- * HDC* - pointer to a DC which will be created.
- * Returns:
- * NOERROR if OK, or the last relevant DirectDraw error code, or E_FAIL.
- */
- HRESULT WinDrawSurface_GetDC(LPWINDRAW lpwd, LPWINDRAWSURFACE lpwds,
- HDC* pDC)
- {
- /* check parameters: */
- if (lpwd == NULL || lpwds == NULL || lpwd->hWnd == NULL ||
- !(lpwd->fMode & WINDRAW_OPENED) || !(lpwds->fMode & WINDRAWSURFACE_OPENED))
- return E_INVALIDARG;
-
- /* check if DirectDraw surface: */
- if (lpwds->fMode & WINDRAWSURFACE_DIRECTDRAW)
- {
- /* Get DC from Direct Draw: */ ;
- HRESULT hr;
- try
- {
- hr = lpwds->dd.lpDDSurface->GetDC(pDC);
- }
- catch(...)
- {
- DumpDDInfo(lpwd, lpwds->dd.lpDDSurface, "WinDrawSurface_GetDC");
- hr = HXR_FAIL;
- }
- return hr;
- }
- else
- { /* GDI: */
- lpwd->gdi.hOldBitmap = (HBITMAP) SelectObject(lpwd->gdi.hMemoryDC, lpwds->gdi.lpGDIBackBuffer[FRONTBUFFER]->hBitMap);
- *pDC = lpwd->gdi.hMemoryDC;
- return NOERROR;
- }
- }
- /*
- * Releases a DC obtained by WinDrawSurface_GetDC
- * Use:
- * HRESULT WinDrawSurface_ReleaseDC(LPWINDRAW lpwd, LPWINDRAWSURFACE lpwds,
- * HDC pDC);
- * Input:
- * lpwd - pointer to a base WINDRAW structure
- * lpwds - pointer to a WINDRAWSURFACE structure to unlock
- * HDC - pointer to a DC which is to be released.
- * Returns:
- * NOERROR if OK, or the last relevant DirectDraw error code, or E_FAIL.
- */
- HRESULT WinDrawSurface_ReleaseDC(LPWINDRAW lpwd, LPWINDRAWSURFACE lpwds,
- HDC hDC)
- {
- /* check parameters: */
- if (lpwd == NULL || lpwds == NULL || lpwd->hWnd == NULL ||
- !(lpwd->fMode & WINDRAW_OPENED) || !(lpwds->fMode & WINDRAWSURFACE_OPENED))
- return E_INVALIDARG;
-
- /* check if DirectDraw surface: */
- if (lpwds->fMode & WINDRAWSURFACE_DIRECTDRAW)
- {
- /* Release DC through Direct Draw: */ ;
- HRESULT hr;
- try
- {
- hr = lpwds->dd.lpDDSurface->ReleaseDC(hDC);
- }
- catch(...)
- {
- DumpDDInfo(lpwd, lpwds->dd.lpDDSurface, "WinDrawSurface_ReleaseDC");
- hr = HXR_FAIL;
- }
- return hr;
- }
- else
- { /* GDI: */
- assert(lpwd->gdi.hMemoryDC == hDC);
- SelectObject (lpwd->gdi.hMemoryDC, lpwd->gdi.hOldBitmap);
- return NOERROR;
- }
- }
- /*
- * Blits the surface data to the screen (primary surface).
- * Use:
- * HRESULT WinDrawSurface_Blt (LPWINDRAW lpwd, LPWINDRAWSURFACE lpwds,
- * LPRECT lpDestRect, LPRECT lpSrcRect);
- * Input:
- * lpwd - pointer to a base WINDRAW structure
- * lpwds - pointer to a WINDRAWSURFACE structure containing data to blit
- * lpDestRect - rectangle on the primary surface to be blitted to
- * lpSrcRect - rectangle on the source surface to be blitted from
- * Returns:
- * NOERROR if OK, or the last relevant DirectDraw error code, or E_FAIL.
- */
- HRESULT WinDrawSurface_Blt (LPWINDRAW lpwd, LPWINDRAWSURFACE lpwds,
- LPRECT lpDestRect, LPRECT lpSrcRect, int nGdiBufferNo)
- {
- /* check parameters: */
- if (lpwd == NULL || lpwds == NULL ||
- lpDestRect == NULL || lpSrcRect == NULL || lpwd->hWnd == NULL ||
- !(lpwd->fMode & WINDRAW_OPENED) || !(lpwds->fMode & WINDRAWSURFACE_OPENED))
- return E_INVALIDARG;
-
-
- /* check if DirectDraw surface: */
- if (lpwds->fMode & WINDRAWSURFACE_DIRECTDRAW)
- {
- /* blit DirectDraw surfaces: */ ;
- if (lpwds->dd.lpDDSurface)
- {
- return DDSurface_Blt(lpwd, lpwds->dd.lpDDSurface, lpSrcRect, lpDestRect);
- }
-
- } else
- { /* GDI: */
- /* check GDI front surface: */
- if (lpwds->gdi.lpGDIBackBuffer [nGdiBufferNo] != NULL) {
- /* blit GDI surface: */
- if (GDISurface_Blt (lpwd, lpwds->gdi.lpGDIBackBuffer [nGdiBufferNo], lpSrcRect, lpDestRect))
- return NOERROR;
- }
- }
- return E_FAIL;
- }
- /*
- * Blits one secondary surface to another.
- * Use:
- * HRESULT WinDrawSurface_BltIndirect (LPWINDRAW lpwd,
- * LPWINDRAWSURFACE lpwdsDestSurf, LPWINDRAWSURFACE lpwdsSrcSurf,
- * LPRECT lpDestRect, LPRECT lpSrcRect);
- * Input:
- * lpwd - pointer to a base WINDRAW structure
- * lpwdsDestSurf - pointer to a destination WINDRAW structure
- * lpwdsSrcSurf - pointer to a source WINDRAW structure
- * lpDestRect - rectangle on the primary surface to be blitted to
- * lpSrcRect - rectangle on the source surface to be blitted from
- * Returns:
- * NOERROR if OK, or the last relevant DirectDraw error code, or E_FAIL.
- */
- HRESULT WinDrawSurface_BltIndirect (LPWINDRAW lpwd,
- LPWINDRAWSURFACE lpwdsDestSurf, LPWINDRAWSURFACE lpwdsSrcSurf,
- LPRECT lpDestRect, LPRECT lpSrcRect,int nGdiBufferNo)
- {
- /* check parameters: */
- if (lpwd == NULL || lpwdsDestSurf == NULL || lpwdsSrcSurf == NULL ||
- lpDestRect == NULL || lpSrcRect == NULL || lpwd->hWnd == NULL ||
- !(lpwd->fMode & WINDRAW_OPENED) || !(lpwdsSrcSurf->fMode & WINDRAWSURFACE_OPENED)
- || !(lpwdsDestSurf->fMode & WINDRAWSURFACE_OPENED))
- return E_INVALIDARG;
-
- /* check if DirectDraw surface: */
- if (lpwdsSrcSurf->fMode & WINDRAWSURFACE_DIRECTDRAW)
- {
- /* blit DirectDraw surfaces: */ ;
- if (NOERROR == DDSurface_BltIndirect(lpwd, lpwdsDestSurf->dd.lpDDSurface, lpwdsSrcSurf->dd.lpDDSurface, lpDestRect, lpSrcRect))
- {
- return NOERROR;
- }
-
- } else
- { /* GDI: */
- if (GDISurface_BltIndirect(lpwd, lpwdsDestSurf->gdi.lpGDIBackBuffer [nGdiBufferNo],
- lpwdsSrcSurf->gdi.lpGDIBackBuffer [nGdiBufferNo], lpSrcRect, lpDestRect))
- return NOERROR;
- }
- return E_FAIL;
- }
- /*
- * Get Description of all modes availiable on the system
- * Use:
- * HRESULT WinDraw2_GetModes(LPWINDRAW lpwd, CModesDesc* pModesDesc, UINT32* nNumModes);
- * Input:
- * lpwd - pointer to a WINDRAW engine to work with
- * pModesDesc - pointer to a block of memory into which the mode description data will
- * be filled.
- * nNumModes - the number of elements which the pModesDesc can contain. If this is too small
- * then proper value will be placed within it.
- * Returns:
- * NOERROR if OK, or E_FAIL.
- */
- HRESULT WinDraw2_GetModes(LPWINDRAW lpwd, CModesDesc* pModesDesc, UINT32* nNumModes)
- {
- /*
- * For testing we will allow the following:
- * if we are in GDI mode we will create a temp
- * DirectDrawObject. And we will query it for the data.
- */
- if (!(lpwd->fMode & WINDRAW_DIRECTDRAW) && !lpwd->m_pModesList->GetCount())
- {
- WINDRAW tempWindraw;
- memset(&tempWindraw, 0, sizeof(WINDRAW));
- WinDraw2_Open(&tempWindraw, (HWND) lpwd->hWnd, WINDRAW_DIRECTDRAW, NULL, NULL);
- /* Enum the display modes */
- DeleteDisplayModes(lpwd);
- if (tempWindraw.dd.lpDD2)
- {
- /*
- * For SOME reason EnumDisplayModes is causing a number of cards to go CRAZY.
- * So we now we call a function which calls enum display modes early and caches
- * the results. For some reason this does not cause things to go INSANE. Who knows why.
- */
- zm_DisplaySettings.GetSettings(lpwd->m_pModesList);
- // tempWindraw.dd.lpDD2->EnumDisplayModes(0, NULL, lpwd->m_pModesList, DisplayModeEnumeratorCallback);
- }
- else
- {
- // create a node based on the current display setting
- // use GDI to get the current mode that we are in.
- HDC hDC = GetDC(NULL);
- int width = GetDeviceCaps(hDC, HORZRES);
- int height = GetDeviceCaps(hDC, VERTRES);
- int bitCount = GetDeviceCaps(hDC, BITSPIXEL) * GetDeviceCaps(hDC, PLANES);
- CModesDesc* pDesc = new CModesDesc;
- pDesc->m_nWidth = width;
- pDesc->m_nHeight = height;
- pDesc->m_nBitCount = bitCount;
- pDesc->m_fourCC = 0;
- lpwd->m_pModesList->AddTail(pDesc);
- ReleaseDC(NULL, hDC);
- }
- WinDraw2_Close(&tempWindraw);
- }
-
- if (*nNumModes != (UINT32)lpwd->m_pModesList->GetCount())
- {
- *nNumModes = lpwd->m_pModesList->GetCount();
- return NOERROR;
- }
-
- CHXSimpleList::Iterator i;
- for(i=lpwd->m_pModesList->Begin(); i!= lpwd->m_pModesList->End(); ++i)
- {
- CModesDesc* pDesc = (CModesDesc*) *i;
-
- pModesDesc->m_nWidth = pDesc->m_nWidth;
- pModesDesc->m_nHeight = pDesc->m_nHeight;
- pModesDesc->m_nBitCount = pDesc->m_nBitCount;
- pModesDesc->m_fourCC = pDesc->m_fourCC;
- pModesDesc++;
- }
- return NOERROR;
- }
- /*
- * Sets Windraw to DD exclusive and sets the display mode to what is specified (if availiable)
- * Use:
- * HRESULT WinDraw2_SetResolution(LPWINDRAW lpwd, UINT32 width, UINT32 height, UINT32 depth);
- * Input:
- * lpwd - pointer to a WINDRAW engine to work with
- * width - target width
- * height - target height
- * depth - target pixel depth
- *
- * Returns:
- * NOERROR if OK, or E_FAIL.
- */
- HRESULT WinDraw2_GetResolution(LPWINDRAW lpwd, UINT32* width, UINT32* height, UINT32* depth)
- {
- if (! (lpwd->fMode & WINDRAW_DIRECTDRAW) || !width || !height || !depth)
- {
- return E_FAIL;
- }
- DDSURFACEDESC ddDesc;
- memset(&ddDesc,0,sizeof(ddDesc));
- ddDesc.dwSize = sizeof(ddDesc);
-
- HRESULT hr;
- try
- {
- hr = lpwd->dd.lpDD2->GetDisplayMode(&ddDesc);
- }
- catch(...)
- {
- DumpDDInfo(lpwd, lpwd->dd.lpDDSPrimary, "WinDraw2_GetResolution");
- return HXR_FAIL;
- }
- if (DD_OK != hr)
- return E_FAIL;
- *width = ddDesc.dwWidth;
- *height = ddDesc.dwHeight;
- *depth = ddDesc.ddpfPixelFormat.dwRGBBitCount;
- return NO_ERROR;
- }
- HRESULT WinDraw2_SetResolution(LPWINDRAW lpwd, UINT32 width, UINT32 height, UINT32 depth, HWND hwnd)
- {
- if (! (lpwd->fMode & WINDRAW_DIRECTDRAW) )
- {
- return E_FAIL;
- }
-
- HRESULT hr = E_FAIL;
- EnterCriticalSection(&lpwd->csPrimary);
- try
- {
- hr = lpwd->dd.lpDD2->SetCooperativeLevel(hwnd, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
- if (NOERROR == hr)
- {
- if (lpwd->dd.lpDDSPrimary)
- {
- int ref = lpwd->dd.lpDDSPrimary->Release();
- if (!ref)
- lpwd->dd.lpDDSPrimary = 0;
- }
- // we're not going to change the bit depth so we need to overide the depth variable
- UINT32 tmp,tmpDepth;
- if (NO_ERROR == WinDraw2_GetResolution(lpwd, &tmp, &tmp, &tmpDepth))
- depth = tmpDepth;
- lpwd->dd.lpDD2->SetDisplayMode(width, height, depth, NULL, NULL);
- WindrawSurface_CreatePrimarySurface(lpwd);
- }
- }
- catch(...)
- {
- DumpDDInfo(lpwd, lpwd->dd.lpDDSPrimary, "WinDraw2_SetResolution");
- hr = HXR_FAIL;
- }
- LeaveCriticalSection(&lpwd->csPrimary);
-
- return hr;
- }
- HRESULT WinDraw2_RestoreResolution(LPWINDRAW lpwd)
- {
- if (! (lpwd->fMode & WINDRAW_DIRECTDRAW) )
- {
- return E_FAIL;
- }
-
- HRESULT res;
- EnterCriticalSection(&lpwd->csPrimary);
- try
- {
- lpwd->dd.lpDD2->SetCooperativeLevel(lpwd->hWnd, DDSCL_NORMAL);
-
- if (lpwd->dd.lpDDSPrimary)
- {
- int ref = lpwd->dd.lpDDSPrimary->Release();
- if (!ref)
- lpwd->dd.lpDDSPrimary = 0;
- }
-
- lpwd->dd.lpDD2->RestoreDisplayMode();
-
- res = WindrawSurface_CreatePrimarySurface(lpwd);
- }
- catch(...)
- {
- DumpDDInfo(lpwd, lpwd->dd.lpDDSPrimary, "WinDraw2_RestoreResolution");
- res = HXR_FAIL;
- }
-
- LeaveCriticalSection(&lpwd->csPrimary);
- return res;
- }
- HRESULT WinDraw2_RestorePrimarySurface(LPWINDRAW lpwd)
- {
- HRESULT hr = DD_OK;
- if (lpwd && lpwd->fMode & WINDRAW_DIRECTDRAW)
- {
- EnterCriticalSection(&lpwd->csPrimary);
- if (lpwd->dd.lpDDSPrimary)
- {
- int ref = lpwd->dd.lpDDSPrimary->Release();
- if (!ref)
- lpwd->dd.lpDDSPrimary = 0;
- }
-
- hr = WindrawSurface_CreatePrimarySurface(lpwd);
- LeaveCriticalSection(&lpwd->csPrimary);
- }
- return hr;
- }
- /*
- * Updates the window that the clipper should use
- * Use:
- * HRESULT WinDrawSurface_Clipper(LPWINDRAW lpwd, HWND hwnd);
- * Input:
- * lpwd - pointer to a base WINDRAW structure
- * hwnd - the window that the clipper should be set to
- * Returns:
- * NOERROR if OK, or the last relevant DirectDraw error code, or E_FAIL.
- */
- HRESULT WinDrawSurface_SetClipper(LPWINDRAW lpwd, HWND hwnd)
- {
- HRESULT hr = NO_ERROR;
- #ifndef _REMOVE_WINDRAW_CLIPPER
- if (! (lpwd->fMode & WINDRAW_DIRECTDRAW) || ! (lpwd->fMode & WINDRAW_OPENED) )
- {
- return E_FAIL;
- }
-
- IDirectDrawClipper* lpClipper;
-
- try
- {
- hr = lpwd->dd.lpDDSPrimary->GetClipper(&lpClipper);
- }
- catch(...)
- {
- DumpDDInfo(lpwd, lpwd->dd.lpDDSPrimary, "WinDraw2_SetClipper");
- hr = HXR_FAIL;
- }
- if (DD_OK == hr)
- {
- lpClipper->SetHWnd(0, hwnd);
- lpwd->m_hCurrentClipWindow = hwnd;
- return NO_ERROR;
- }
- #endif
-
- return hr;
- }
- HRESULT WinDrawSurface_GetClipperWindow(LPWINDRAW lpwd, HWND* pHwnd)
- {
- #ifndef _REMOVE_WINDRAW_CLIPPER
- if (! (lpwd->fMode & WINDRAW_DIRECTDRAW) || ! (lpwd->fMode & WINDRAW_OPENED) )
- {
- *pHwnd = 0;
- return E_FAIL;
- }
-
- *pHwnd = lpwd->m_hCurrentClipWindow;
- #endif
- return HXR_OK;
- }
- HRESULT WinDrawSurface_GetColorControls(LPWINDRAW lpwd, LPWINDRAWSURFACE lpwds,
- float &fBright, float &fContrast, float &fSaturation,
- float &fHue, float &fSharpness)
- {
- HRESULT hr = HXR_FAIL;
- if ((lpwd == NULL) | (lpwds == NULL))
- {
- HX_ASSERT(0);
- return E_INVALIDARG;
- }
- IDirectDrawColorControl *pcc = NULL;
- lpwds->dd.lpDDSurface->QueryInterface(IID_IDirectDrawColorControl, (void**)&pcc);
- if (pcc)
- {
- DDCOLORCONTROL ddcc;
- memset(&ddcc, 0, sizeof(ddcc));
- ddcc.dwSize = sizeof(ddcc);
-
- try
- {
- pcc->GetColorControls(&ddcc);
- HX_RELEASE(pcc);
- // Map dd values to rma values
- fBright = (float)((ddcc.lBrightness - 5000.0) / 5000.0);
- fContrast = (float)((ddcc.lContrast - 10000.0) / 10000.0);
- fHue = (float)(ddcc.lHue/180.0);
-
- fSaturation = (float)((ddcc.lSaturation - 10000.0) / 10000.0);
- fSharpness = (float)((ddcc.lSharpness - 2.5) / 2.5);
- hr = HXR_OK;
- }
- catch(...)
- {
- DumpDDInfo(lpwd, lpwds->dd.lpDDSurface, "WinDrawSurface_GetColorControls");
- hr = HXR_FAIL;
-
- HX_RELEASE(pcc);
- }
- }
- return hr;
- }
- HRESULT WinDrawSurface_SetColorControls(LPWINDRAW lpwd, LPWINDRAWSURFACE lpwds,
- float fBright, float fContrast, float fSaturation,
- float fHue, float fSharpness)
- {
- HRESULT hr = HXR_OK;
-
- if ((lpwd == NULL) | (lpwds == NULL))
- {
- HX_ASSERT(0);
- return E_INVALIDARG;
- }
- // Map dd values to rma values (where zero is default)
- IDirectDrawColorControl *pcc = NULL;
- lpwds->dd.lpDDSurface->QueryInterface(IID_IDirectDrawColorControl, (void**)&pcc);
- if (pcc)
- {
- DDCOLORCONTROL ddcc;
- memset(&ddcc, 0, sizeof(ddcc));
- ddcc.dwSize = sizeof(ddcc);
- DDCOLORCONTROL ddccCurrent;
- memset(&ddccCurrent, 0, sizeof(ddccCurrent));
- ddccCurrent.dwSize = sizeof(ddccCurrent);
- try
- {
- hr = pcc->GetColorControls(&ddccCurrent);
- ddcc = ddccCurrent;
-
- // (0-10000, 750 is dd default)
- if (fBright == 0.0)
- ddcc.lBrightness = lpwds->dd.ddcc.lBrightness;
- else
- {
- // Mapping [-1,1] to [0,10000] with a default of 750
- if (fBright > 0)
- ddcc.lBrightness = (LONG)(fBright * 9250.0 + 750.0);
- else
- ddcc.lBrightness = (LONG)((fBright + 1.0) * 750.0);
- }
- // (0-20000, 10000 is dd default - limit to 2k-18k for compatabilty)
- if (fContrast == 0.0)
- ddcc.lContrast = lpwds->dd.ddcc.lContrast;
- else
- ddcc.lContrast = (LONG)(fContrast * 8000.0 + 10000.0);
-
- // (-180-180, 0 is dd default)
- if (fHue == 0.0)
- ddcc.lHue = lpwds->dd.ddcc.lHue;
- else
- ddcc.lHue = (LONG)(fHue*180.0);
- // (0-20000, 10000 is dd default limit to 4k-16k for compatabilty)
- if (fSaturation == 0.0)
- ddcc.lSaturation = lpwds->dd.ddcc.lSaturation;
- else
- ddcc.lSaturation = (LONG)(fSaturation * 6000.0 + 10000.0);
- // (0-10, 5 is dd default and -1 is rma def)
- if (fSharpness == 0.0)
- ddcc.lSharpness = lpwds->dd.ddcc.lSharpness;
- else
- ddcc.lSharpness = (LONG)(fSharpness * 5 + 5);
- if (ddccCurrent.lBrightness != ddcc.lBrightness ||
- ddccCurrent.lContrast != ddcc.lContrast ||
- ddccCurrent.lHue != ddcc.lHue ||
- ddccCurrent.lSaturation != ddcc.lSaturation ||
- ddccCurrent.lSharpness != ddcc.lSharpness)
- {
- hr = pcc->SetColorControls(&ddcc);
- }
- }
- catch(...)
- {
- DumpDDInfo(lpwd, lpwds->dd.lpDDSurface, "WinDrawSurface_SetColorControls");
- hr = HXR_FAIL;
- }
- pcc->Release();
- }
- return hr;
- }
- HRESULT WindrawSurface_CreatePrimarySurface(LPWINDRAW lpwd)
- {
- if (lpwd == NULL)
- {
- HX_ASSERT(0);
- return E_INVALIDARG;
- }
- EnterCriticalSection(&lpwd->csPrimary);
- if (lpwd->dd.lpDDSPrimary)
- {
- lpwd->dd.lpDDSPrimary->Release();
- lpwd->dd.lpDDSPrimary = NULL;
- }
- /* Create the primary surface */
- DDSURFACEDESC ddsd;
- ZeroMemory(&ddsd, sizeof(ddsd));
- ddsd.dwSize = sizeof(ddsd);
- ddsd.dwFlags = DDSD_CAPS;
- ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
-
- int res;
- IDirectDrawClipper* lpClipper = NULL;
-
- try
- {
- res = lpwd->dd.lpDD2->CreateSurface (&ddsd, &lpwd->dd.lpDDSPrimary, NULL);
- #ifndef _REMOVE_WINDRAW_CLIPPER
- if (res == DD_OK)
- {
- if (DD_OK == (res = lpwd->dd.lpDD2->CreateClipper(0, &(lpClipper), NULL)))
- {
- lpClipper->SetHWnd(0, lpwd->hWnd);
- lpwd->m_hCurrentClipWindow = lpwd->hWnd;
- lpwd->dd.lpDDSPrimary->SetClipper(lpClipper);
- lpClipper->Release(); /* ok the surface has the ref on it now */
- lpClipper = NULL;
- }
- }
- #endif
-
- }
- catch(...)
- {
- DumpDDInfo(lpwd, lpwd->dd.lpDDSPrimary, "WindrawSurface_CreatePrimarySurface");
- res = HXR_FAIL;
- HX_RELEASE(lpClipper);
- HX_RELEASE(lpwd->dd.lpDDSPrimary);
- }
- LeaveCriticalSection(&lpwd->csPrimary);
- return res;
- }
- int Windraw_ColorMatch(LPWINDRAW lpwd, COLORREF crColor)
- {
- HDC hdc;
- DDSURFACEDESC ddsd;
- int retVal;
- HRESULT res;
-
- if ( lpwd == NULL ||
- (!(lpwd->fMode & WINDRAW_OPENED)) ||
- (!(lpwd->fMode & WINDRAW_DIRECTDRAW)))
- {
- return 0x0000000;
- }
-
- memset(&ddsd, 0, sizeof(DDSURFACEDESC));
- ddsd.dwSize = sizeof(DDSURFACEDESC);
-
- // get primary surface CID.
- BMI bmi;
- memset(&bmi, 0, sizeof(BMI));
- WinDraw2_GetDisplayFormat(lpwd, &bmi);
- bmi.bmiHeader.biHeight = 2;
- bmi.bmiHeader.biWidth = 2;
-
- WINDRAWSURFACE tempSurf;
- memset(&tempSurf, 0, sizeof(WINDRAWSURFACE));
-
- try
- {
- // now attempt to create the surface
- res = WinDraw2_CreateSurface(lpwd, &tempSurf, &bmi, WINDRAWSURFACE_DIRECTDRAW, 0, 0);
- res = WinDrawSurface_GetDC(lpwd, &tempSurf, &hdc);
- COLORREF ref = SetPixel (hdc, 0, 0, crColor);
- res = WinDrawSurface_ReleaseDC(lpwd, &tempSurf, hdc);
-
- res = tempSurf.dd.lpDDSurface->Lock(NULL, &ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL);
- retVal = *(PDWORD)ddsd.lpSurface;
- res = tempSurf.dd.lpDDSurface->Unlock(ddsd.lpSurface);
-
- if (ddsd.ddpfPixelFormat.dwRGBBitCount < 32)
- retVal &= (1L << ddsd.ddpfPixelFormat.dwRGBBitCount) - 1;
- res = WinDraw2_ReleaseSurface(lpwd, &tempSurf);
-
- }
- catch(...)
- {
- DumpDDInfo(lpwd, lpwd->dd.lpDDSPrimary, "Windraw_ColorMatch");
- retVal = HXR_FAIL;
- if (tempSurf.dd.lpDDSurface)
- WinDraw2_ReleaseSurface(lpwd, &tempSurf);
- }
-
- return retVal;
- }
- int countBits(int input)
- {
- int count = 0;
-
- while(input)
- {
- input &= input-1;
- count++;
- }
- return count;
- }
- int Windraw_GetLowestColor(LPWINDRAW lpwd)
- {
- DDSURFACEDESC ddsd;
- int retVal;
- HRESULT res;
-
- if ( lpwd == NULL ||
- (!(lpwd->fMode & WINDRAW_OPENED)) ||
- (!(lpwd->fMode & WINDRAW_DIRECTDRAW)))
- {
- return 0x0000000;
- }
-
- memset(&ddsd, 0, sizeof(DDSURFACEDESC));
- ddsd.dwSize = sizeof(DDSURFACEDESC);
-
- // get primary surface CID.
- BMI bmi;
- memset(&bmi, 0, sizeof(BMI));
- WinDraw2_GetDisplayFormat(lpwd, &bmi);
- bmi.bmiHeader.biHeight = 2;
- bmi.bmiHeader.biWidth = 2;
-
- WINDRAWSURFACE tempSurf;
- memset(&tempSurf, 0, sizeof(WINDRAWSURFACE));
-
- try
- {
- // now attempt to create the surface
- res = WinDraw2_CreateSurface(lpwd, &tempSurf, &bmi, WINDRAWSURFACE_DIRECTDRAW, 0, 0);
- res = tempSurf.dd.lpDDSurface->Lock(NULL, &ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL);
- res = tempSurf.dd.lpDDSurface->Unlock(ddsd.lpSurface);
-
- int redMask = ddsd.ddpfPixelFormat.dwRBitMask;
- int greenMask = ddsd.ddpfPixelFormat.dwGBitMask;
- int blueMask = ddsd.ddpfPixelFormat.dwBBitMask;
-
- retVal = 1 << (9 - countBits(redMask));
- retVal |= (1 << (9 - countBits(greenMask))) << 8;
- retVal |= (1 << (9 - countBits(blueMask))) << 16;
-
- res = WinDraw2_ReleaseSurface(lpwd, &tempSurf);
-
- }
- catch(...)
- {
- DumpDDInfo(lpwd, lpwd->dd.lpDDSPrimary, "Windraw_GetLowestColor");
- retVal = HXR_FAIL;
- if (tempSurf.dd.lpDDSurface)
- WinDraw2_ReleaseSurface(lpwd, &tempSurf);
- }
-
- return retVal;
- }
- HRESULT WinDraw2_GetScanLine(LPWINDRAW lpwd, DWORD *pdwScanLine)
- {
- if ((lpwd == NULL) |
- (lpwd->dd.lpDD2 == NULL) |
- (lpwd->dd.lpDDSPrimary == NULL))
- {
- *pdwScanLine = 0;
- return E_INVALIDARG;
- }
-
- HRESULT hr = NOERROR;
- try
- {
- hr = lpwd->dd.lpDD2->GetScanLine(pdwScanLine);
- if (DD_OK == hr ||
- DDERR_VERTICALBLANKINPROGRESS == hr)
- {
- // The G400 occasionally reports an obscenely high value here;
- // we filter to 130% of the reported display height
- if (*pdwScanLine > lpwd->dwReportedHeight*1.3)
- {
- *pdwScanLine = 0;
- return hr;
- }
- if (*pdwScanLine > lpwd->dwMaxScanLine)
- lpwd->dwMaxScanLine = *pdwScanLine;
- }
- else
- *pdwScanLine = 0;
- }
- catch(...)
- {
- DumpDDInfo(lpwd, lpwd->dd.lpDDSPrimary, "WinDraw2_GetScanLine");
- hr = HXR_FAIL;
- *pdwScanLine = 0;
- }
- return hr;
- }
- HRESULT LockSurface(LPWINDRAW lpwd, LPDIRECTDRAWSURFACE lpSurface, DDSURFACEDESC *pddsd, BOOL bBlock)
- {
- DWORD dwFlags = DDLOCK_WRITEONLY | DDLOCK_NOSYSLOCK;
- HRESULT hr;
- if (bBlock)
- dwFlags |= DDLOCK_WAIT;
- for (int i=0;; i++)
- {
- memset(pddsd, 0, sizeof(*pddsd));
- pddsd->dwSize = sizeof(*pddsd);
- try
- {
- hr = lpSurface->Lock(NULL, pddsd, dwFlags, NULL);
- }
- catch(...)
- {
- char szTmp[256]; /* Flawfinder: ignore */
- sprintf(szTmp, "LockSurface flags %lx", dwFlags); /* Flawfinder: ignore */
-
- DumpDDInfo(lpwd, lpSurface, szTmp);
- hr = HXR_FAIL;
- }
- if (hr == DDERR_INVALIDPARAMS)
- {
- if (i)
- break;
- dwFlags = 0;
- dwFlags |= DDLOCK_WAIT;
- }
- else
- break;
- }
- return hr;
- }
- HRESULT RestoreSurfaces(LPWINDRAW lpwd, LPWINDRAWSURFACE lpwds)
- {
- HRESULT hr;
- EnterCriticalSection(&lpwd->csPrimary);
- try
- {
- // Restore the surfaces if we lost them
- hr = lpwd->dd.lpDDSPrimary->Restore();
- if (hr == DD_OK)
- hr = lpwds->dd.lpDDSurface->Restore();
- }
- catch(...)
- {
- DumpDDInfo(lpwd, lpwds->dd.lpDDSurface, "RestoreSurfaces");
- hr = HXR_FAIL;
- }
- LeaveCriticalSection(&lpwd->csPrimary);
- return hr;
- }
- #if defined (HELIX_FEATURE_VS2)
- /*
- * WinDraw2_GetColorspacePriorities
- *
- * Request preferred color spaces from the DD driver
- */
- HRESULT WinDraw2_GetColorspacePriorities(int cidIn, int *pCPList, int &nSize)
- {
- LPDIRECTDRAW lpTemp = 0;
- LPDIRECTDRAW2 lpDD = 0;
- HINSTANCE hDirectDraw = 0;
- HRESULT ddrval = 0;
- DWORD pFourcc[128];
- DWORD dwNumCodes = 0;
- int j=0;
- unsigned int yv12 = -1,
- yuy2 = -1,
- uyvy = -1;
- try
- {
-
- LoadDirectDraw(NULL, &lpTemp, &hDirectDraw);
-
- if (lpTemp)
- {
- lpTemp->QueryInterface(IID_IDirectDraw2, (void**)&lpDD);
- lpTemp->Release();
- }
- if(lpDD)
- {
- memset(pFourcc, 0, sizeof(pFourcc));
- // Get the number of supported 4CC codes
- if (DD_OK != lpDD->GetFourCCCodes(&dwNumCodes, 0))
- {
- ReleaseDirectDraw(NULL, &lpDD, &hDirectDraw);
- return E_FAIL;
- }
- // Get the list of supported 4CC codes
- ddrval = lpDD->GetFourCCCodes(&dwNumCodes, pFourcc);
- if (ddrval != DD_OK || !dwNumCodes)
- {
- ReleaseDirectDraw(NULL, &lpDD, &hDirectDraw);
- return E_FAIL;
- }
- memset(pCPList, 0, nSize * sizeof(*pCPList));
- // If I420 is not the source format, make it the first priority in hopes
- // of avoiding an unnecessary color conversion when writing to video memory.
- if (IsYUV(cidIn) && CID_I420 != cidIn)
- {
- pCPList[j++] = cidIn;
- }
-
- if(dwNumCodes && pFourcc && DD_OK == ddrval)
- {
- for(int i=0; i < (int)dwNumCodes && j < nSize; i++)
- {
- switch(MapFourCCtoCID(pFourcc[i]))
- {
- case CID_I420: pCPList[j++] = CID_I420; break;
- case CID_YV12: pCPList[j++] = CID_YV12; yv12 = j-1; break;
- case CID_UYVY: pCPList[j++] = CID_UYVY; uyvy = j-1; break;
- case CID_YUY2: pCPList[j++] = CID_YUY2; yuy2 = j-1; break;
- }
- }
- nSize = j;
- BOOL bTrySort = FALSE;
- DDDEVICEIDENTIFIER ddID;
- // Do some hard-coded ovverrides. We want yv12 over packed
- // formats, so, if yv12 is in the list put it at the head
- // EXCEPT for nvidia and Matrox G200, which have poor yv12 support.
- #if DIRECTDRAW_VERSION > 0x0500
- IDirectDraw4* lpDD4 = NULL;
- lpDD->QueryInterface(IID_IDirectDraw4, (void **) &lpDD4);
-
- if (lpDD4)
- {
- DDDEVICEIDENTIFIER dddi;
- memset(&dddi, 0, sizeof(dddi));
- lpDD4->GetDeviceIdentifier(&dddi, DDGDI_GETHOSTIDENTIFIER);
- lpDD4->Release();
- SafeStrCpy(ddID.szDescription, dddi.szDescription, MAX_DDDEVICEID_STRING);
- SafeStrCpy(ddID.szDriver, dddi.szDriver, MAX_DDDEVICEID_STRING);
- ddID.dwVendorId = dddi.dwVendorId;
- ddID.dwDeviceId = dddi.dwDeviceId;
- bTrySort = TRUE;
- }
- // DD4 not supportted (probably NT4)...use more drastic measures
- else
- #endif //DIRECTDRAW_VERSION > 0x0500
- {
- // Check if we are runnning NT
- OSVERSIONINFO osVersion;
- memset(&osVersion,0, sizeof(OSVERSIONINFO));
- osVersion.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
- if (GetVersionEx(&osVersion) && osVersion.dwPlatformId == VER_PLATFORM_WIN32_NT)
- {
- char szChipType[MAXCHIPTYPE]; /* Flawfinder: ignore */
-
- // Try to get WinNT device information
- if (GetWinNTDeviceID (&ddID, szChipType))
- {
- bTrySort = TRUE;
- }
- }
- }
- if (bTrySort &&
- yv12 != -1 &&
-
- // TNT yv12 chroma does not line up
- ddID.dwVendorId != 0x10DE &&
- // NeoMagic yv12 chroma probs when overlay is cropped
- ddID.dwVendorId != 0x10C8 &&
- // Riva128 yv12 has software conversion and
- // locks always return same ptr.
- strcmpi(ddID.szDescription, "NV3") &&
- ddID.dwVendorId != 0x12D2 &&
- // G200 uses sofware converstion to yv12
- !strstr(ddID.szDescription, "Matrox Millennium G200"))
- {
- if (yv12 > uyvy)
- {
- pCPList[uyvy] = CID_YV12;
- pCPList[yv12] = CID_UYVY;
- yv12 = uyvy;
- }
- if (yv12 > yuy2)
- {
- pCPList[yuy2] = CID_YV12;
- pCPList[yv12] = CID_YUY2;
- }
- }
-
- // Filter bad Radeon drivers
- if (ddID.dwVendorId == 0x1002 &&
- ddID.szDriver &&
- pCPList[0] == CID_DVPF)
- {
- // The only difference is in the dll's file version
- char szTmp[256] = "