📄 windraw2.cpp
字号:
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 */ lTargetHeight, /* destination height */ lpwd->gdi.hMemoryDC2, /* source device context */ lpSourceRect->left, /* x source position */ lpSourceRect->top, /* y source position */ SRCCOPY); /* simple copy */ } else { /* stretch the image when copying to the destination: */ bResult = StretchBlt ( lpwd->gdi.hMemoryDC, /* target device HDC */ lpTargetRect->left, /* x sink position */ lpTargetRect->top, /* y sink position */ lTargetWidth, /* destination width */ lTargetHeight, /* destination height */ lpwd->gdi.hMemoryDC2, /* source device HDC */ lpSourceRect->left, /* x source position */ lpSourceRect->top, /* y source position */ lSourceWidth, /* source width */ lSourceHeight, /* source height */ SRCCOPY); /* simple copy */ } /* put the old bitmap back into the device context so we don't leak */ SelectObject (lpwd->gdi.hMemoryDC, hOldBitmap); SelectObject (lpwd->gdi.hMemoryDC2, hOldBitmap2); /* pass the result of Bit/StretchBlt: */ return bResult;}/** Blits image data into the window.* Use:* BOOL DDSurface_Blt(LPWINDRAW lpwd, LPDIRECTDRAWSURFACE lpDDSurface,* LPRECT lpSourceRect, LPRECT lpTargetRect)* Input:* lpwd - pointer to the WINDRAW structure* lpDDSurface - 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.*/BOOL DDSurface_Blt(LPWINDRAW lpwd, LPDIRECTDRAWSURFACE lpDDSurface, LPRECT lpSourceRect, LPRECT lpT
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -