windraw2.cpp
来自「symbian 下的helix player源代码」· C++ 代码 · 共 2,002 行 · 第 1/5 页
CPP
2,002 行
{
DeleteObject (lpwd->gdi.hPalette);
lpwd->gdi.hPalette = NULL;
}
/* release DCs, if taken: */
if (lpwd->gdi.hDC != NULL)
{
ReleaseDC (lpwd->hWnd, lpwd->gdi.hDC);
lpwd->gdi.hDC = NULL;
}
if (lpwd->gdi.hMemoryDC != NULL)
{
DeleteDC (lpwd->gdi.hMemoryDC);
lpwd->gdi.hMemoryDC = NULL;
}
if (lpwd->gdi.hMemoryDC2 != NULL)
{
DeleteDC (lpwd->gdi.hMemoryDC2);
lpwd->gdi.hMemoryDC2 = NULL;
}
}
cleanup:
/* deactivate WinDraw & exit: */
lpwd->fMode = 0;
/* remove display mode data */
DeleteDisplayModes(lpwd);
HX_DELETE(lpwd->m_pModesList);
HX_DELETE(lpwd->m_pSurfaceList);
DeleteCriticalSection(&lpwd->csPrimary);
InterlockedDecrement(&g_ehandlerMutexCnt);
if (!g_ehandlerMutexCnt)
{
DeleteCriticalSection(&g_ehandlerMutex);
}
return NOERROR;
}
/*
* Get display/primary surface format.
* Use:
* HRESULT WinDraw2_GetDisplayFormat (LPWINDRAW lpwd, LPBMI lpbiDisplayFormat);
* Input:
* lpwd - pointer to a WINDRAW structure to initialize
* lpbiDisplayFormat - a structure to contain display format
* Returns:
* NOERROR if OK, or the last relevant DirectDraw error code, or E_FAIL.
*/
HRESULT WinDraw2_GetDisplayFormat (LPWINDRAW lpwd, LPBMI lpbiDisplayFormat)
{
int sz;
/* check parameters: */
if (lpwd == NULL || !(lpwd->fMode & WINDRAW_OPENED) ||
lpbiDisplayFormat == NULL)
return E_INVALIDARG;
/* check the size of BITMAPINFO structure to copy: */
sz = lpbiDisplayFormat->bmiHeader.biSize;
if (sz < (int)sizeof(BITMAPINFOHEADER) || sz > (int)lpwd->bmiDisplayFormat.bmiHeader.biSize)
sz = lpwd->bmiDisplayFormat.bmiHeader.biSize;
/* copy bitmap info: */
/* Since it seems that our convention was to set biSize to the sizeof
* BITMAPINFOHEADER instead of the actual size of the structure (which
* causes us to lose the color table of bit fields) we will use the size
* of the structure.
*/
// memcpy(lpbiDisplayFormat, &(lpwd->bmiDisplayFormat), sz);
GetDisplayFormat(&lpwd->bmiDisplayFormat, lpwd->lpszDisplayDevice);
memcpy(lpbiDisplayFormat, &(lpwd->bmiDisplayFormat), sizeof(BMI) ); /* Flawfinder: ignore */
return NOERROR;
}
/*
* GDISURFACE functions:
*/
#define hMEMORY ((HANDLE) 0xFFFFFFFF) /* says to open as memory file */
/*
* This function allocates a shared memory block for use by the source filter
* generating DIBs for us to render. The memory block is created in shared
* memory so that GDI doesn't have to copy the memory when we do a BitBlt
*/
static LPGDISURFACE GDISurface_Alloc (LPBITMAPINFO pbmi)
{
LPGDISURFACE lpGDISurface; /* pointer to a new GDISURFACE */
HANDLE hMapping; /* handle to mapped object */
HBITMAP hBitmap; /* DIB section bitmap handle */
BYTE *pBase; /* pointer to the actual image */
/* allocate a new GDISURFACE structure to use: */
lpGDISurface = (LPGDISURFACE)malloc (sizeof (GDISURFACE));
if (lpGDISurface != NULL) {
/* create a file mapping object and map into our address space: */
hMapping = CreateFileMapping (hMEMORY, NULL, PAGE_READWRITE, (DWORD) 0, pbmi->bmiHeader.biSizeImage, NULL);
if (hMapping != NULL) {
/* create a DIB section using given image format */
hBitmap = CreateDIBSection ((HDC) NULL, pbmi, DIB_RGB_COLORS, (VOID **) &pBase, hMapping, (DWORD) 0);
if (hBitmap != NULL && pBase != NULL) {
/* initialise the GDISURFACE structure: */
lpGDISurface->hBitMap = hBitmap;
lpGDISurface->hMapping = hMapping;
lpGDISurface->lpBase = pBase;
lpGDISurface->lpAlphaSurface = NULL;
lpGDISurface->hEmpty = CreateEvent(NULL, TRUE, TRUE, NULL);
/* lpGDISurface->PaletteVersion = PALETTE_VERSION; */
GetObject (hBitmap, sizeof (DIBSECTION), (VOID *)& (lpGDISurface->DibSection));
/* success: */
return lpGDISurface;
}
/* close file mapping... */
CloseHandle (hMapping);
}
/* free buffer: */
free (lpGDISurface);
}
return NULL;
}
/*
* Releases previously allocated GDI buffer.
* Main application should consider calling GdiFlush ();
* before releasing these buffers.
*/
static void GDISurface_Free (LPGDISURFACE lpGDISurface)
{
/* check pointer to a buffer structure to use: */
if (lpGDISurface != NULL) {
/* close dibsection: */
DeleteObject (lpGDISurface->hBitMap);
/* close file mapping: */
CloseHandle (lpGDISurface->hMapping);
/* close alpha channel */
free(lpGDISurface->lpAlphaSurface);
/* close event */
CloseHandle(lpGDISurface->hEmpty);
/* free buffer: */
free (lpGDISurface);
}
}
static BOOL GDISurface_AlphaBltIndirect(LPWINDRAW lpwd, LPGDISURFACE lpGDISurfaceDest,
LPGDISURFACE lpGDISurfaceSrc, LPRECT lpDestRect, LPRECT lpSrcRect)
{
#if 0
INT32 destX, destY;
INT32 destStride, srcStride, alphaStride;
UINT32 *srcBuf, *destBuf;
UCHAR *alphaBuf;
UCHAR alpha, invalpha;
UCHAR *pSrc, *pDest;
int destCID = GetBitmapColor((LPBITMAPINFO) &lpGDISurfaceDest->DibSection.dsBmih);
int srcCID = GetBitmapColor((LPBITMAPINFO) &lpGDISurfaceSrc->DibSection.dsBmih);
assert(destCID == srcCID); // not supported
switch (destCID)
{
case CID_RGB565:
case CID_RGB555:
destStride = (lpGDISurfaceDest->DibSection.dsBmih.biWidth - (lpDestRect->right - lpDestRect->left)) * 2;
srcStride = (lpGDISurfaceSrc->DibSection.dsBmih.biWidth - (lpSrcRect->right - lpSrcRect->left)) * 2;
srcBuf = (UINT32*)(lpGDISurfaceSrc->lpBase + ( (lpSrcRect->right - lpSrcRect->left) * lpSrcRect->top
+ lpSrcRect->left ) * 2);
destBuf = (UINT32*)(lpGDISurfaceDest->lpBase + ( (lpDestRect->right - lpDestRect->left) * lpDestRect->top
+ lpDestRect->left) *2);
break;
case CID_RGB32:
destStride = (lpGDISurfaceDest->DibSection.dsBmih.biWidth - (lpDestRect->right - lpDestRect->left)) * 4;
srcStride = (lpGDISurfaceSrc->DibSection.dsBmih.biWidth - (lpSrcRect->right - lpSrcRect->left)) * 4;
srcBuf = (UINT32*)(lpGDISurfaceSrc->lpBase + ( (lpSrcRect->right - lpSrcRect->left) * lpSrcRect->top
+ lpSrcRect->left ) *4);
destBuf = (UINT32*)(lpGDISurfaceDest->lpBase + ( (lpDestRect->right - lpDestRect->left) * lpDestRect->top
+ lpDestRect->left ) *4);
break;
case CID_RGB24:
break;
default:
assert(CID_NOTSUPPORTED);
}
alphaBuf = lpGDISurfaceSrc->lpAlphaSurface;
alphaStride = lpGDISurfaceDest->DibSection.dsBmih.biWidth - (lpSrcRect->right - lpSrcRect->left);
switch (destCID)
{
case CID_RGB32:
{
for (destY = lpDestRect->top; destY < lpDestRect->bottom; destY++ )
{
for (destX = lpDestRect->left;destX < lpDestRect->right;destX++, srcBuf++, destBuf++, alphaBuf++)
{
alpha = *alphaBuf>128 ? *alphaBuf + 1 : *alphaBuf;
invalpha = 256 - alpha;
*destBuf =
((((*srcBuf & 0x00ff0000) * alpha) >> 8 ) & 0x00ff0000) +
((((*destBuf & 0x00ff0000) * invalpha) >> 8 ) & 0x00ff0000) +
((((*srcBuf & 0x0000ff00) * alpha) >> 8 ) & 0x0000ff00) +
((((*destBuf & 0x0000ff00) * invalpha) >> 8 ) & 0x0000ff00) +
((((*srcBuf & 0x000000ff) * alpha) >> 8 ) & 0x000000ff) +
((((*destBuf & 0x000000ff) * invalpha) >> 8 ) & 0x000000ff);
}
destBuf += destStride;
srcBuf += srcStride;
alphaBuf += alphaStride;
}
break;
}
case CID_RGB24:
{
pSrc = lpGDISurfaceSrc->lpBase;
pDest = lpGDISurfaceDest->lpBase;
pDest += (lpGDISurfaceDest->DibSection.dsBmih.biWidth * (lpGDISurfaceDest->DibSection.dsBmih.biHeight - lpDestRect->top) + lpDestRect->left)* 3;
pSrc += (lpGDISurfaceSrc->DibSection.dsBmih.biWidth * (lpGDISurfaceSrc->DibSection.dsBmih.biHeight - lpSrcRect->top) + lpSrcRect->left)* 3;
for (destY = lpDestRect->top; destY < lpDestRect->bottom; destY++ )
{
for (destX = lpDestRect->left;destX < lpDestRect->right;destX++, alphaBuf++)
{
// alpha = *alphaBuf;
alpha = 128;
invalpha = 256 - alpha;
*pDest = (*pSrc * alpha) >> 8 + (*pDest * invalpha) >> 8;
pDest++; pSrc++;
*pDest = (*pSrc * alpha) >> 8 + (*pDest * invalpha) >> 8;
pDest++; pSrc++;
*pDest = (*pSrc * alpha) >> 8 + (*pDest * invalpha) >> 8;
pDest++; pSrc++;
}
pDest -= (lpGDISurfaceDest->DibSection.dsBmih.biWidth + (lpDestRect->right - lpDestRect->left))*3;
pSrc -= (lpGDISurfaceSrc->DibSection.dsBmih.biWidth + (lpSrcRect->right - lpSrcRect->left))*3;
alphaBuf +=alphaStride;
}
break;
}
case CID_RGB565:
case CID_RGB555:
{
/*
* The following bugs are plain (and all stem from the same problem)
*
* 1. If the dest/src rects are not both even.
* 2. If the width of the blt is not even
*
*/
for (destY = lpDestRect->top; destY < lpDestRect->bottom; destY++ )
{
for (destX = lpDestRect->left;destX < lpDestRect->right;destX+=2, srcBuf++, destBuf++, alphaBuf++)
{
alpha = *alphaBuf>128 ? *alphaBuf + 1 : *alphaBuf;
invalpha = 256 - alpha;
*destBuf =
((((*srcBuf & 0xf8000000) * alpha) >> 8 ) & 0xf8000000) +
((((*destBuf & 0xf8000000) * invalpha) >> 8 ) & 0xf8000000) +
((((*srcBuf & 0x07e00000) * alpha) >> 8 ) & 0x07e00000) +
((((*destBuf & 0x07e00000) * invalpha) >> 8 ) & 0x07e00000) +
((((*srcBuf & 0x001f0000) * alpha) >> 8 ) & 0x001f0000) +
((((*destBuf & 0x001f0000) * invalpha) >> 8 ) & 0x001f0000) +
((((*srcBuf & 0x0000f800) * alpha) >> 8 ) & 0x0000f800) +
((((*destBuf & 0x0000f800) * invalpha) >> 8 ) & 0x0000f800) +
((((*srcBuf & 0x000007e0) * alpha) >> 8 ) & 0x000007e0) +
((((*destBuf & 0x000007e0) * invalpha) >> 8 ) & 0x000007e0) +
((((*srcBuf & 0x0000001f) * alpha) >> 8 ) & 0x0000001f) +
((((*destBuf & 0x0000001f) * invalpha) >> 8 ) & 0x0000001f);
}
destBuf += destStride;
srcBuf += srcStride;
alphaBuf += alphaStride;
}
break;
}
}
#endif
return NOERROR;
}
/*
* Blits image data into the window.
* Use:
* BOOL DDSurface_BltIndirect(LPWINDRAW lpwd, LPGDISURFACE lpGDISurface,
* LPRECT lpSourceRect, LPRECT lpTargetRect)
* Input:
* lpwd - pointer to the WINDRAW structure
* lpDDSurfaceSrc - a structure containing DIBSECTION of image to blit
* lpDDSurfaceDst - a
* lpSrcRect - a source image region to blit
* lpDstRect - a target window region to fill with image
* Returns:
* TRUE, if success; FALSE, otherwise.
*/
static BOOL DDSurface_BltIndirect(
LPWINDRAW lpwd,
LPDIRECTDRAWSURFACE lpDDSurfaceDst,
LPDIRECTDRAWSURFACE lpDDSurfaceSrc,
LPRECT lpDstRect,
LPRECT lpSrcRect
)
{
/*
* this will currently only work if the two color formats are
* the same.
*/
/* set update mode: */
DWORD dwFlags = DDBLT_WAIT | DDBLT_ROP;
/* set effects: */
DDBLTFX ddBltFx;
ZeroMemory(&ddBltFx, sizeof(DDBLTFX));
ddBltFx.dwSize = sizeof (DDBLTFX);
ddBltFx.dwROP = SRCCOPY;
/* try to blit data from an offscreen surface: */
HRESULT retVal;
try
{
retVal = lpDDSurfaceDst->Blt(lpDstRect, lpDDSurfaceSrc, lpSrcRect, dwFlags, &ddBltFx);
}
catch(...)
{
char szTmp[256]; /* Flawfinder: ignore */
sprintf(szTmp, "DDSurface_BltIndirect srcRect %ld %ld %ld %ld dstRc %ld %ld %ld %ld", /* Flawfinder: ignore */
lpSrcRect->left, lpSrcRect->top, lpSrcRect->right, lpSrcRect->bottom,
lpDstRect->left, lpDstRect->top, lpDstRect->right, lpDstRect->bottom);
DumpDDInfo(lpwd, lpDDSurfaceDst, "DDSurface_BltIndirect");
retVal = HXR_FAIL;
}
return retVal;
}
/*
* Blits image data into the window.
* Use:
* BOOL GDISurface_BltIndirect(LPWINDRAW lpwd, LPGDISURFACE lpGDISurface,
* LPRECT lpSourceRect, LPRECT lpTargetRect)
* Input:
* lpwd - pointer to the WINDRAW structure
* lpGDISurface - a structure containing DIBSECTION of image to blit
* lpSourceRect - a source image region to blit
* lpTargetRect - a target window region to fill with image
* Returns:
* TRUE, if success; FALSE, otherwise.
*/
static BOOL GDISurface_BltIndirect(LPWINDRAW lpwd, LPGDISURFACE lpGDISurfaceDest,
LPGDISURFACE lpGDISurfaceSrc, LPRECT lpSourceRect, LPRECT lpTargetRect)
{
BOOL bResult; /* return value */
/* get sizes of source/destination rectangles: */
LONG lTargetWidth = lpTargetRect->right - lpTargetRect->left;
LONG lTargetHeight = lpTargetRect->bottom - lpTargetRect->top;
LONG lSourceWidth = lpSourceRect->right - lpSourceRect->left;
LONG lSourceHeight = lpSourceRect->bottom - lpSourceRect->top;
/* select bitmap to blit: */
HBITMAP hOldBitmap = (HBITMAP) SelectObject (lpwd->gdi.hMemoryDC, lpGDISurfaceDest->hBitMap);
HBITMAP hOldBitmap2 = (HBITMAP) SelectObject (lpwd->gdi.hMemoryDC2, lpGDISurfaceSrc->hBitMap);
if (lpGDISurfaceSrc->lpAlphaSurface)
{
return GDISurface_AlphaBltIndirect(lpwd, lpGDISurfaceDest, lpGDISurfaceSrc, lpTargetRect, lpSourceRect);
}
/* is the window the same size as the video: */
if (lTargetWidth == lSourceWidth && lTargetHeight == lSourceHeight)
{
/* put the image straight into the destination: */
bResult = BitBlt (
lpwd->gdi.hMemoryDC, /* target device HDC */
lpTargetRect->left, /* x sink position */
lpTargetRect->top, /* y sink position */
lTargetWidth, /* destination width */
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?