📄 ddutil.cpp
字号:
if(x+Rect.right-Rect.left>m_nScreenWidth)
{
Rect.right=Rect.left+m_nScreenWidth-x;
}
if(y+Rect.bottom-Rect.top>m_nScreenHeight)
{
Rect.bottom=Rect.top+m_nScreenHeight-y;
}
return m_pddsBackBuffer->BltFast( x, y, pdds, &Rect, dwFlags );
}
//code add by me
void CSurface::Clear(DWORD dwColor)
{
DDBLTFX ddbltfx;
ZeroMemory( &ddbltfx, sizeof(ddbltfx) );
ddbltfx.dwSize = sizeof(ddbltfx);
ddbltfx.dwFillColor = dwColor;
m_pdds->Blt( NULL, NULL, NULL, DDBLT_COLORFILL, &ddbltfx );
}
void CSurface::BltFast(int cx,int cy,LPDIRECTDRAWSURFACE7 pDD,LPRECT pSourRect,BOOL bColorKey)
{
if(!pDD)
return;
DDSURFACEDESC2 ddsd,ddsdthis;
ZeroMemory(&ddsd,sizeof(ddsd));
ddsd.dwSize=sizeof(ddsd);
ZeroMemory(&ddsdthis,sizeof(ddsdthis));
ddsdthis.dwSize=sizeof(ddsdthis);
pDD->GetSurfaceDesc(&ddsd);
m_pdds->GetSurfaceDesc(&ddsdthis);
RECT rtSour,rtClip;
if(!pSourRect)
{
rtSour.top=0;
rtSour.bottom=ddsd.dwHeight;
rtSour.left=0;
rtSour.right=ddsd.dwWidth;
}
else
{
rtSour.left=pSourRect->left;
rtSour.top=pSourRect->top;
rtSour.right=pSourRect->right;
rtSour.bottom=pSourRect->bottom;
}
rtClip.top=0;
rtClip.left=0;
rtClip.right=ddsdthis.dwWidth;
rtClip.bottom=ddsdthis.dwHeight;
if(cx<rtClip.left)
{
rtSour.left-=cx;//右移动
cx=rtClip.left;
}
if(cy<rtClip.top)
{
rtSour.top-=cy;//下移动
cy=rtClip.top;
}
if(cx+rtSour.right-rtSour.left>rtClip.right)
{
rtSour.right=rtSour.left+rtClip.right-cx;
}
if(cy+rtSour.bottom-rtSour.top>rtClip.bottom)
{
rtSour.bottom=rtSour.top+rtClip.bottom-cy;
}
m_pdds->BltFast(cx,cy,pDD,&rtSour,bColorKey?(DDBLTFAST_WAIT|DDBLTFAST_SRCCOLORKEY):(DDBLTFAST_WAIT|DDBLTFAST_NOCOLORKEY));
}
void CSurface::BltFast(int cx,int cy,CSurface*cs,LPRECT pSourRect,BOOL bColorKey)
{
m_pdds->BltFast(cx,cy,cs->GetDDrawSurface(),pSourRect,bColorKey);
}
void CSurface::ColorAlphaBlt(LPRECT pRectBlt,DWORD dwColor,int iAlpha)
{
RECT rtClip;
DDSURFACEDESC2 ddsddest;
ZeroMemory(&ddsddest,sizeof(ddsddest));
ddsddest.dwSize=sizeof(ddsddest);
m_pdds->GetSurfaceDesc(&ddsddest);
DWORD height=ddsddest.dwHeight;
DWORD width=ddsddest.dwWidth;
if(!pRectBlt)
{
rtClip.top=0;
rtClip.left=0;
rtClip.right=ddsddest.dwHeight;
rtClip.bottom=ddsddest.dwWidth;
}
else
{
rtClip.top=pRectBlt->top;
rtClip.bottom=pRectBlt->bottom;
rtClip.left=pRectBlt->left;
rtClip.right=pRectBlt->right;
if(rtClip.top<0)
rtClip.top=0;
if(rtClip.left<0)
rtClip.left=0;
if(rtClip.right>(int)ddsddest.dwWidth)
rtClip.right=ddsddest.dwWidth;
if(rtClip.bottom>(int)ddsddest.dwHeight)
rtClip.bottom=ddsddest.dwHeight;
}
ZeroMemory(&ddsddest,sizeof(ddsddest));
ddsddest.dwSize=sizeof(ddsddest);
m_pdds->Lock(NULL,&ddsddest,DDLOCK_WAIT,NULL);
WORD*buf=(WORD*)ddsddest.lpSurface;
int index;
WORD color=CDisplay::RGBTo16Bit(dwColor);
for(int i=rtClip.left;i<rtClip.right;i++)
{
for(int j=rtClip.top;j<rtClip.bottom;j++)
{
index=j*width+i;
buf[index]=CDisplay::Alpha(buf[index],color,iAlpha);
}
}
m_pdds->Unlock(NULL);
}
void CSurface::AlphaBlt(int cx,int cy,CSurface*cs,LPRECT pSourRect,BOOL bColorKey,int iAlpha)
{
if(!cs)
return;
AlphaBlt(cx,cy,cs->GetDDrawSurface(),pSourRect,bColorKey,iAlpha);
}
void CSurface::AlphaBlt(int cx,int cy,LPDIRECTDRAWSURFACE7 pDD,LPRECT pSourRect,BOOL bColorKey,int iAlpha)
{
if(!pDD)
return;
if(iAlpha>31 || iAlpha<0)
{
CSurface::BltFast(cx,cy,pDD,pSourRect,bColorKey);
return;
}
DDSURFACEDESC2 ddsd,ddsdthis;
ZeroMemory(&ddsd,sizeof(ddsd));
ddsd.dwSize=sizeof(ddsd);
ZeroMemory(&ddsdthis,sizeof(ddsdthis));
ddsdthis.dwSize=sizeof(ddsdthis);
pDD->GetSurfaceDesc(&ddsd);
m_pdds->GetSurfaceDesc(&ddsdthis);
RECT rtSour,rtClip;
if(!pSourRect)
{
rtSour.top=0;
rtSour.bottom=ddsd.dwHeight;
rtSour.left=0;
rtSour.right=ddsd.dwWidth;
}
else
{
rtSour.bottom=pSourRect->bottom;
rtSour.left=pSourRect->left;
rtSour.right=pSourRect->right;
rtSour.top=pSourRect->top;
if(rtSour.top<0)
rtSour.top=0;
if(rtSour.left<0)
rtSour.left=0;
if(rtSour.right>(int)ddsd.dwWidth)
rtSour.right=ddsd.dwWidth;
if(rtSour.bottom>(int)ddsd.dwHeight)
rtSour.bottom=ddsd.dwHeight;
}
rtClip.top=0;
rtClip.left=0;
rtClip.right=ddsdthis.dwWidth;
rtClip.bottom=ddsdthis.dwHeight;
if(cx<rtClip.left)
{
rtSour.left-=cx;//右移动
cx=rtClip.left;
}
if(cy<rtClip.top)
{
rtSour.top-=cy;//下移动
cy=rtClip.top;
}
if(cx+rtSour.right-rtSour.left>rtClip.right)
{
rtSour.right=rtSour.left+rtClip.right-cx;
}
if(cy+rtSour.bottom-rtSour.top>rtClip.bottom)
{
rtSour.bottom=rtSour.top+rtClip.bottom-cy;
}
DDSURFACEDESC2 ddsddest;
DDSURFACEDESC2 ddsdsour;
ZeroMemory(&ddsddest,sizeof(ddsddest));
ZeroMemory(&ddsdsour,sizeof(ddsdsour));
ddsddest.dwSize=sizeof(ddsddest);
ddsdsour.dwSize=sizeof(ddsdsour);
DDCOLORKEY ddck;
if(bColorKey)
{
pDD->GetColorKey(DDCKEY_SRCBLT,&ddck);
}
m_pdds->Lock(NULL,&ddsddest,DDLOCK_WAIT,NULL);
pDD->Lock(NULL,&ddsdsour,DDLOCK_WAIT,NULL);
WORD*DestBuf=(WORD*)ddsddest.lpSurface;
WORD*SourBuf=(WORD*)ddsdsour.lpSurface;
int SourWidth=ddsdsour.lPitch>>1;
int DestWidth=ddsddest.lPitch>>1;
int DestStart=DestWidth*cy+cx;
int SourStart=SourWidth*rtSour.top+rtSour.left;
int SourOff=SourWidth-rtSour.right+rtSour.left;
int DestOff=DestWidth-rtSour.right+rtSour.left;
if(!bColorKey)
{
for(int iy=0;iy<rtSour.bottom-rtSour.top;iy++)
{
for(int ix=0;ix<rtSour.right-rtSour.left;ix++)
{
DestBuf[DestStart]=CDisplay::Alpha(DestBuf[DestStart],SourBuf[SourStart],iAlpha);
SourStart++;DestStart++;
}
SourStart+=SourOff;
DestStart+=DestOff;
}
}
else
{
for(int iy=0;iy<rtSour.bottom-rtSour.top;iy++)
{
for(int ix=0;ix<rtSour.right-rtSour.left;ix++)
{
if(SourBuf[SourStart]!=ddck.dwColorSpaceHighValue)
DestBuf[DestStart]=CDisplay::Alpha(DestBuf[DestStart],SourBuf[SourStart],iAlpha);
SourStart++;DestStart++;
}
SourStart+=SourOff;
DestStart+=DestOff;
}
}
m_pdds->Unlock(NULL);
pDD->Unlock(NULL);
}
//end my code
//-----------------------------------------------------------------------------
// Name:
// Desc:
//-----------------------------------------------------------------------------
HRESULT CDisplay::Blt( DWORD x, DWORD y, CSurface* pSurface, RECT* prc )
{
if( NULL == pSurface )
return E_INVALIDARG;
if( pSurface->IsColorKeyed() )
return Blt( x, y, pSurface->GetDDrawSurface(), prc, DDBLTFAST_SRCCOLORKEY );
else
return Blt( x, y, pSurface->GetDDrawSurface(), prc, 0L );
}
//-----------------------------------------------------------------------------
// Name:
// Desc:
//-----------------------------------------------------------------------------
HRESULT CDisplay::Clear( DWORD dwColor )
{
if( NULL == m_pddsBackBuffer )
return E_POINTER;
// Erase the background
DDBLTFX ddbltfx;
ZeroMemory( &ddbltfx, sizeof(ddbltfx) );
ddbltfx.dwSize = sizeof(ddbltfx);
ddbltfx.dwFillColor = dwColor;
return m_pddsBackBuffer->Blt( NULL, NULL, NULL, DDBLT_COLORFILL, &ddbltfx );
}
//-----------------------------------------------------------------------------
// Name:
// Desc:
//-----------------------------------------------------------------------------
HRESULT CDisplay::SetPalette( LPDIRECTDRAWPALETTE pPalette )
{
if( NULL == m_pddsFrontBuffer )
return E_POINTER;
return m_pddsFrontBuffer->SetPalette( pPalette );
}
//-----------------------------------------------------------------------------
// Name:
// Desc:
//-----------------------------------------------------------------------------
HRESULT CDisplay::CreatePaletteFromBitmap( LPDIRECTDRAWPALETTE* ppPalette,
const TCHAR* strBMP )
{
HRSRC hResource = NULL;
RGBQUAD* pRGB = NULL;
BITMAPINFOHEADER* pbi = NULL;
PALETTEENTRY aPalette[256];
HANDLE hFile = NULL;
DWORD iColor;
DWORD dwColors;
BITMAPFILEHEADER bf;
BITMAPINFOHEADER bi;
DWORD dwBytesRead;
if( m_pDD == NULL || strBMP == NULL || ppPalette == NULL )
return E_INVALIDARG;
*ppPalette = NULL;
// Try to load the bitmap as a resource, if that fails, try it as a file
hResource = FindResource( NULL, strBMP, RT_BITMAP );
if( hResource )
{
pbi = (LPBITMAPINFOHEADER) LockResource( LoadResource( NULL, hResource ) );
if( NULL == pbi )
return E_FAIL;
pRGB = (RGBQUAD*) ( (BYTE*) pbi + pbi->biSize );
// Figure out how many colors there are
if( pbi == NULL || pbi->biSize < sizeof(BITMAPINFOHEADER) )
dwColors = 0;
else if( pbi->biBitCount > 8 )
dwColors = 0;
else if( pbi->biClrUsed == 0 )
dwColors = 1 << pbi->biBitCount;
else
dwColors = pbi->biClrUsed;
// A DIB color table has its colors stored BGR not RGB
// so flip them around.
for( iColor = 0; iColor < dwColors; iColor++ )
{
aPalette[iColor].peRed = pRGB[iColor].rgbRed;
aPalette[iColor].peGreen = pRGB[iColor].rgbGreen;
aPalette[iColor].peBlue = pRGB[iColor].rgbBlue;
aPalette[iColor].peFlags = 0;
}
return m_pDD->CreatePalette( DDPCAPS_8BIT, aPalette, ppPalette, NULL );
}
// Attempt to load bitmap as a file
hFile = CreateFile( strBMP, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL );
if( NULL == hFile )
return E_FAIL;
// Read the BITMAPFILEHEADER
ReadFile( hFile, &bf, sizeof(bf), &dwBytesRead, NULL );
if( dwBytesRead != sizeof(bf) )
{
CloseHandle( hFile );
return E_FAIL;
}
// Read the BITMAPINFOHEADER
ReadFile( hFile, &bi, sizeof(bi), &dwBytesRead, NULL );
if( dwBytesRead != sizeof(bi) )
{
CloseHandle( hFile );
return E_FAIL;
}
// Read the PALETTEENTRY
ReadFile( hFile, aPalette, sizeof(aPalette), &dwBytesRead, NULL );
if( dwBytesRead != sizeof(aPalette) )
{
CloseHandle( hFile );
return E_FAIL;
}
CloseHandle( hFile );
// Figure out how many colors there are
if( bi.biSize != sizeof(BITMAPINFOHEADER) )
dwColors = 0;
else if (bi.biBitCount > 8)
dwColors = 0;
else if (bi.biClrUsed == 0)
dwColors = 1 << bi.biBitCount;
else
dwColors = bi.biClrUsed;
// A DIB color table has its colors stored BGR not RGB
// so flip them around since DirectDraw uses RGB
for( iColor = 0; iColor < dwColors; iColor++ )
{
BYTE r = aPalette[iColor].peRed;
aPalette[iColor].peRed = aPalette[iColor].peBlue;
aPalette[iColor].peBlue = r;
}
return m_pDD->CreatePalette( DDPCAPS_8BIT, aPalette, ppPalette, NULL );
}
//-----------------------------------------------------------------------------
// Name:
// Desc:
//-----------------------------------------------------------------------------
HRESULT CDisplay::UpdateBounds()
{
if( m_bWindowed )
{
GetClientRect( m_hWnd, &m_rcWindow );
ClientToScreen( m_hWnd, (POINT*)&m_rcWindow );
ClientToScreen( m_hWnd, (POINT*)&m_rcWindow+1 );
}
else
{
SetRect( &m_rcWindow, 0, 0, GetSystemMetrics(SM_CXSCREEN),
GetSystemMetrics(SM_CYSCREEN) );
}
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: CDisplay::InitClipper
// Desc:
//-----------------------------------------------------------------------------
HRESULT CDisplay::InitClipper()
{
LPDIRECTDRAWCLIPPER pClipper;
HRESULT hr;
// Create a clipper when using GDI to draw on the primary surface
if( FAILED( hr = m_pDD->CreateClipper( 0, &pClipper, NULL ) ) )
return hr;
pClipper->SetHWnd( 0, m_hWnd );
if( FAILED( hr = m_pddsFrontBuffer->SetClipper( pClipper ) ) )
return hr;
// We can release the clipper now since g_pDDSPrimary
// now maintains a ref count on the clipper
SAFE_RELEASE( pClipper );
return S_OK;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -