📄 dxc_ddraw.cpp
字号:
{
SetTextColor(m_hDC, rgb );
::TextOut(m_hDC, x, y, cStr, strlen(cStr));
}
void DXC_ddraw::_TestPixelFormat()
{
DDSURFACEDESC2 ddSurfaceDesc2;
HRESULT hResult;
ZeroMemory(&ddSurfaceDesc2, sizeof(DDSURFACEDESC2));
ddSurfaceDesc2.dwSize = sizeof(ddSurfaceDesc2);
ddSurfaceDesc2.dwFlags = DDSD_PIXELFORMAT;
hResult = m_lpBackB4->GetSurfaceDesc(&ddSurfaceDesc2);
if (hResult == DD_OK)
{
if (ddSurfaceDesc2.ddpfPixelFormat.dwRBitMask == 0x0000F800) {
m_cPixelFormat = 1;
// RGB 5:6:5
}
if (ddSurfaceDesc2.ddpfPixelFormat.dwRBitMask == 0x00007C00) {
m_cPixelFormat = 2;
// RGB 5:5:5
}
if (ddSurfaceDesc2.ddpfPixelFormat.dwRBitMask == 0x0000001F) {
m_cPixelFormat = 3;
// BGR 5:6:5
}
}
}
long DXC_ddraw::_CalcMaxValue(int iS, int iD, char cMode, char cMethod, double dAlpha)
{
long Sum;
double dTmp;
switch (cMethod) {
case 1:
dTmp = (double)iS;
dTmp = dTmp * dAlpha;
iS = (int)dTmp;
Sum = (iS) + (iD);
if (Sum < iD) Sum = iD;
break;
case 2:
Sum = (iS + iD) / 2;
break;
}
switch (cMode) {
case 'G':
switch (m_cPixelFormat) {
case 1:
if (Sum >= 64) Sum = 63; //v1.3
break;
case 2:
if (Sum >= 32) Sum = 31;
break;
}
break;
default:
if (Sum >= 32) Sum = 31;
break;
}
return Sum;
}
long DXC_ddraw::_CalcMinValue(int iS, int iD, char cMode)
{
long Sum;
Sum = iD - iS;
if (Sum < 0) Sum = 0;
switch (cMode) {
case 'G':
switch (m_cPixelFormat) {
case 1:
if (Sum >= 64) Sum = 63; //v1.3
break;
case 2:
if (Sum >= 32) Sum = 31;
break;
}
break;
default:
if (Sum >= 32) Sum = 31;
break;
}
return Sum;
}
void DXC_ddraw::ClearBackB4()
{
DDSURFACEDESC2 ddsd2;
ddsd2.dwSize = sizeof(ddsd2);
if (m_lpBackB4->Lock(NULL, &ddsd2, DDLOCK_WAIT, NULL) != DD_OK) return;
memset((char *)ddsd2.lpSurface, 0, ddsd2.lPitch * 480);
m_lpBackB4->Unlock(NULL);
}
void DXC_ddraw::DrawShadowBox(short sX, short sY, short dX, short dY, int iType)
{
WORD * pDst, wValue;
int ix, iy;
pDst = (WORD *)m_pBackB4Addr + sX + ((sY)*m_sBackB4Pitch);
if (iType == 0) {
switch (m_cPixelFormat) {
case 1:
for (iy = 0; iy <= (dY - sY); iy++) {
for (ix = 0; ix <= (dX - sX); ix++)
pDst[ix] = (pDst[ix] & 0xf7de) >> 1;
pDst += m_sBackB4Pitch;
}
break;
case 2:
for (iy = 0; iy <= (dY - sY); iy++) {
for (ix = 0; ix <= (dX - sX); ix++)
pDst[ix] = (pDst[ix] & 0x7bde) >> 1;
pDst += m_sBackB4Pitch;
}
break;
}
}
else
{
switch (iType) {
case 1:
if (m_cPixelFormat == 1)
wValue = 0x38e7;
else wValue = 0x1ce7;
break;
case 2:
if (m_cPixelFormat == 1)
wValue = 0x1863;
else wValue = 0xc63;
break;
}
for (iy = 0; iy <= (dY - sY); iy++) {
for (ix = 0; ix <= (dX - sX); ix++)
pDst[ix] = wValue;
pDst += m_sBackB4Pitch;
}
}
}
void DXC_ddraw::PutPixel(short sX, short sY, WORD wR, WORD wG, WORD wB)
{
WORD * pDst;
if ((sX < 0) || (sY < 0) || (sX > 639) || (sY > 479)) return;
pDst = (WORD *)m_pBackB4Addr + sX + ((sY)*m_sBackB4Pitch);
switch (m_cPixelFormat) {
case 1:
*pDst = (WORD)( ((wR>>3)<<11) | ((wG>>2)<<5) | (wB>>3) );
//*pDst = (WORD)((wR<<11) | (wG<<5) | wB);
break;
case 2:
*pDst = (WORD)( ((wR>>3)<<10) | ((wG>>3)<<5) | (wB>>3) );
//*pDst = (WORD)((wR<<10) | (wG<<5) | wB);
break;
}
}
void DXC_ddraw::_GetBackBufferDC()
{
m_lpBackB4->GetDC(&m_hDC);
SelectObject(m_hDC, m_hFontInUse);
SetBkMode(m_hDC, TRANSPARENT);
SetBkColor(m_hDC, RGB(0,0,0));
}
void DXC_ddraw::_ReleaseBackBufferDC()
{
m_lpBackB4->ReleaseDC(m_hDC);
}
void DXC_ddraw::DrawText(LPRECT pRect, char *pString, COLORREF rgb)
{
SetTextColor(m_hDC, rgb);
::DrawText(m_hDC, pString, strlen(pString), pRect, DT_CENTER | DT_NOCLIP | DT_WORDBREAK | DT_NOPREFIX);//v2.15
}
HRESULT DXC_ddraw::InitFlipToGDI(HWND hWnd)
{
LPDIRECTDRAWCLIPPER pClipper;
HRESULT hr;
DDCAPS ddcaps;
ZeroMemory( &ddcaps, sizeof(ddcaps) );
ddcaps.dwSize = sizeof(ddcaps);
m_lpDD4->GetCaps( &ddcaps, NULL );
if( (ddcaps.dwCaps2 & DDCAPS2_CANRENDERWINDOWED) == 0 )
{
// This means FlipToGDISurface() is not supported, so to display GDI
// on these cards, you you must create a bitmap of the GDI window
// and BitBlt the bitmap to the backbuffer then flip as normal. However,
// this specific sample does not show this.
return E_FAIL;
}
// Create a clipper when using GDI to draw on the primary surface
if( FAILED( hr = m_lpDD4->CreateClipper( 0, &pClipper, NULL ) ) )
return hr;
pClipper->SetHWnd( 0, hWnd );
if( FAILED( hr = m_lpFrontB4->SetClipper( pClipper ) ) ) return hr;
// We can release the clipper now since g_pDDSPrimary
// now maintains a ref count on the clipper
if( pClipper )
{
pClipper->Release();
pClipper = NULL;
}
return S_OK;
}
void DXC_ddraw::ColorTransferRGB(COLORREF fcolor, int * iR, int * iG, int * iB)
{
WORD wR, wG, wB;
switch(m_cPixelFormat)
{
case 1:
// R
wR = (WORD)((fcolor&0x000000f8)>>3);
// G
wG = (WORD)((fcolor&0x0000fc00)>>10);
// B
wB = (WORD)((fcolor&0x00f80000)>>19);
*iR = (int)wR;
*iG = (int)wG;
*iB = (int)wB;
break;
case 2:
// R
wR = (WORD)((fcolor&0x000000f8)>>3);
// G
wG = (WORD)((fcolor&0x0000f800)>>11);
// B
wB = (WORD)((fcolor&0x00f80000)>>19);
*iR = (int)wR;
*iG = (int)wG;
*iB = (int)wB;
break;
}
}
//---------------------------------------------------------------------------
bool DXC_ddraw::Screenshot(LPCTSTR FileName, LPDIRECTDRAWSURFACE7 lpDDS)
{
if (!FileName || !lpDDS) return false;
bool Success=false;
HDC SurfDC=NULL; // GDI-compatible device context for the surface
HBITMAP OffscrBmp=NULL; // bitmap that is converted to a DIB
HDC OffscrDC=NULL; // offscreen DC that we can select OffscrBmp into
LPBITMAPINFO lpbi=NULL; // bitmap format info; used by GetDIBits
LPVOID lpvBits=NULL; // pointer to bitmap bits array
HANDLE BmpFile=INVALID_HANDLE_VALUE; // destination .bmp file
BITMAPFILEHEADER bmfh; // .bmp file header
try
{
// Get dimensions of Surface:
DDSURFACEDESC2 ddsd;
ZeroMemory(&ddsd, sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);
if (FAILED(lpDDS->GetSurfaceDesc(&ddsd))) throw 0;
int Width = ddsd.dwWidth;
int Height = ddsd.dwHeight;
// Create a GDI-compatible device context for the surface:
if (FAILED(lpDDS->GetDC(&SurfDC))) throw 1;
// We need an HBITMAP to convert it to a DIB:
if ((OffscrBmp = CreateCompatibleBitmap(SurfDC, Width, Height)) == NULL)
throw 2;
// The bitmap is empty, so let's copy the contents of the surface to it.
// For that we need to select it into a device context. We create one.
if ((OffscrDC = CreateCompatibleDC(SurfDC)) == NULL) throw 3;
// Select OffscrBmp into OffscrDC:
HBITMAP OldBmp = (HBITMAP)SelectObject(OffscrDC, OffscrBmp);
// Now we can copy the contents of the surface to the offscreen bitmap:
BitBlt(OffscrDC, 0, 0, Width, Height, SurfDC, 0, 0, SRCCOPY);
// We don't need SurfDC anymore. Free it:
lpDDS->ReleaseDC(SurfDC); SurfDC = NULL;
// GetDIBits requires format info about the bitmap. We can have GetDIBits
// fill a structure with that info if we pass a NULL pointer for lpvBits:
// Reserve memory for bitmap info (BITMAPINFOHEADER + largest possible
// palette):
if ((lpbi = (LPBITMAPINFO)(new char[sizeof(BITMAPINFOHEADER) +
256 * sizeof(RGBQUAD)])) == NULL) throw 4;
ZeroMemory(&lpbi->bmiHeader, sizeof(BITMAPINFOHEADER));
lpbi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
// Get info but first de-select OffscrBmp because GetDIBits requires it:
SelectObject(OffscrDC, OldBmp);
if (!GetDIBits(OffscrDC, OffscrBmp, 0, Height, NULL, lpbi, DIB_RGB_COLORS))
throw 5;
// Reserve memory for bitmap bits:
if ((lpvBits = new char[lpbi->bmiHeader.biSizeImage]) == NULL)
throw 6;
// Have GetDIBits convert OffscrBmp to a DIB (device-independent bitmap):
if (!GetDIBits(OffscrDC, OffscrBmp, 0, Height, lpvBits, lpbi,
DIB_RGB_COLORS)) throw 7;
// Create a file to save the DIB to:
if ((BmpFile = CreateFile(FileName,
GENERIC_WRITE,
0, NULL,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL)) == INVALID_HANDLE_VALUE) throw 8;
DWORD Written; // number of bytes written by WriteFile
// Write a file header to the file:
bmfh.bfType = 19778; // 'BM'
// bmfh.bfSize = ??? // we'll write that later
bmfh.bfReserved1 = bmfh.bfReserved2 = 0;
// bmfh.bfOffBits = ??? // we'll write that later
if (!WriteFile(BmpFile, &bmfh, sizeof(bmfh), &Written, NULL))
throw 9;
if (Written < sizeof(bmfh)) throw 9;
// Write BITMAPINFOHEADER to the file:
if (!WriteFile(BmpFile, &lpbi->bmiHeader, sizeof(BITMAPINFOHEADER),
&Written, NULL)) throw 10;
if (Written < sizeof(BITMAPINFOHEADER)) throw 10;
// Calculate size of palette:
int PalEntries;
// 16-bit or 32-bit bitmaps require bit masks:
if (lpbi->bmiHeader.biCompression == BI_BITFIELDS) PalEntries = 3;
else
// bitmap is palettized?
PalEntries = (lpbi->bmiHeader.biBitCount <= 8) ?
// 2^biBitCount palette entries max.:
(int)(1 << lpbi->bmiHeader.biBitCount)
// bitmap is TrueColor -> no palette:
: 0;
// If biClrUsed use only biClrUsed palette entries:
if (lpbi->bmiHeader.biClrUsed) PalEntries = lpbi->bmiHeader.biClrUsed;
// Write palette to the file:
if (PalEntries)
{
if (!WriteFile(BmpFile, &lpbi->bmiColors, PalEntries * sizeof(RGBQUAD),
&Written, NULL)) throw 11;
if (Written < PalEntries * sizeof(RGBQUAD)) throw 11;
}
// The current position in the file (at the beginning of the bitmap bits)
// will be saved to the BITMAPFILEHEADER:
bmfh.bfOffBits = SetFilePointer(BmpFile, 0, 0, FILE_CURRENT);
// Write bitmap bits to the file:
if (!WriteFile(BmpFile, lpvBits, lpbi->bmiHeader.biSizeImage,
&Written, NULL)) throw 12;
if (Written < lpbi->bmiHeader.biSizeImage) throw 12;
// The current pos. in the file is the final file size and will be saved:
bmfh.bfSize = SetFilePointer(BmpFile, 0, 0, FILE_CURRENT);
// We have all the info for the file header. Save the updated version:
SetFilePointer(BmpFile, 0, 0, FILE_BEGIN);
if (!WriteFile(BmpFile, &bmfh, sizeof(bmfh), &Written, NULL))
throw 13;
if (Written < sizeof(bmfh)) throw 13;
OutputDebugString("Screenshot Success\r\n");
Success = true;
}
catch (int &errorcode)
{
char Buf[100];
wsprintf(Buf, "Screenshot error #%i\r\n", errorcode);
OutputDebugString(Buf);
}
catch (...)
{
OutputDebugString("Screenshot error\r\n");
}
if (SurfDC) lpDDS->ReleaseDC(SurfDC);
if (OffscrDC) DeleteDC(OffscrDC);
if (OffscrBmp) DeleteObject(OffscrBmp);
if (lpbi) delete[] lpbi;
if (lpvBits) delete[] lpvBits;
if (BmpFile != INVALID_HANDLE_VALUE) CloseHandle(BmpFile);
return Success;
}
//---------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -