📄 ddutil.cpp
字号:
DeleteObject( hbm );
// clean up and destroy the JPEG Decompressor
ijlFree(&jcprops);
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: CDisplay::CreateSurfaceFromBitmap()
// Desc: Create a DirectDrawSurface from a bitmap resource or bitmap file.
// Use MAKEINTRESOURCE() to pass a constant into strBMP.
//-----------------------------------------------------------------------------
HRESULT CDisplay::CreateSurfaceFromBitmap( CSurface** ppSurface,
TCHAR* strBMP,
DWORD dwDesiredWidth,
DWORD dwDesiredHeight )
{
HRESULT hr;
HBITMAP hBMP = NULL;
BITMAP bmp;
DDSURFACEDESC2 ddsd;
if( m_pDD == NULL || strBMP == NULL || ppSurface == NULL )
return E_INVALIDARG;
//Add By Kylinx
if(dwDesiredWidth==0 || dwDesiredHeight==0)
{
BITMAPINFOHEADER bih;
FILE*fp=fopen(strBMP,"rb");
fseek(fp,sizeof(BITMAPFILEHEADER),SEEK_SET);
fread(&bih,sizeof(bih),1,fp);
fclose(fp);
dwDesiredWidth=bih.biWidth;
dwDesiredHeight=bih.biHeight;
}
//End Add By Kylinx
*ppSurface = NULL;
// Try to load the bitmap as a resource, if that fails, try it as a file
hBMP = (HBITMAP) LoadImage( GetModuleHandle(NULL), strBMP,
IMAGE_BITMAP, dwDesiredWidth, dwDesiredHeight,
LR_CREATEDIBSECTION );
if( hBMP == NULL )
{
hBMP = (HBITMAP) LoadImage( NULL, strBMP,
IMAGE_BITMAP, dwDesiredWidth, dwDesiredHeight,
LR_LOADFROMFILE | LR_CREATEDIBSECTION );
if( hBMP == NULL )
return E_FAIL;
}
// Get size of the bitmap
GetObject( hBMP, sizeof(bmp), &bmp );
// Create a DirectDrawSurface for this bitmap
ZeroMemory( &ddsd, sizeof(ddsd) );
ddsd.dwSize = sizeof(ddsd);
ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN|DDSCAPS_SYSTEMMEMORY;
ddsd.dwWidth = bmp.bmWidth;
ddsd.dwHeight = bmp.bmHeight;
(*ppSurface) = new CSurface();
if( FAILED( hr = (*ppSurface)->Create( m_pDD, &ddsd ) ) )
{
delete (*ppSurface);
return hr;
}
// Draw the bitmap on this surface
if( FAILED( hr = (*ppSurface)->DrawBitmap( hBMP, 0, 0, 0, 0 ) ) )
{
DeleteObject( hBMP );
return hr;
}
DeleteObject( hBMP );
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: CDisplay::CreateSurfaceFromText()
// Desc: Creates a DirectDrawSurface from a text string using hFont or the default
// GDI font if hFont is NULL.
//-----------------------------------------------------------------------------
HRESULT CDisplay::CreateSurfaceFromText( CSurface** ppSurface,
HFONT hFont, TCHAR* strText,
COLORREF crBackground, COLORREF crForeground )
{
HDC hDC = NULL;
HRESULT hr;
DDSURFACEDESC2 ddsd;
SIZE sizeText;
if( m_pDD == NULL || strText == NULL || ppSurface == NULL )
return E_INVALIDARG;
*ppSurface = NULL;
hDC = GetDC( NULL );
if( hFont )
SelectObject( hDC, hFont );
GetTextExtentPoint32( hDC, strText, _tcslen(strText), &sizeText );
ReleaseDC( NULL, hDC );
// Create a DirectDrawSurface for this bitmap
ZeroMemory( &ddsd, sizeof(ddsd) );
ddsd.dwSize = sizeof(ddsd);
ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN|DDSCAPS_SYSTEMMEMORY;
ddsd.dwWidth = sizeText.cx;
ddsd.dwHeight = sizeText.cy;
(*ppSurface) = new CSurface();
if( FAILED( hr = (*ppSurface)->Create( m_pDD, &ddsd ) ) )
{
delete (*ppSurface);
return hr;
}
if( FAILED( hr = (*ppSurface)->DrawText( hFont, strText, 0, 0,
crBackground, crForeground ) ) )
return hr;
return S_OK;
}
//-----------------------------------------------------------------------------
// Name:
// Desc:
//-----------------------------------------------------------------------------
HRESULT CDisplay::Present()
{
HRESULT hr;
if( NULL == m_pddsFrontBuffer && NULL == m_pddsBackBuffer )
return E_POINTER;
if(m_bGrayDisplay && m_nBit==16)
{
DDSURFACEDESC2 ddsddest;
ZeroMemory(&ddsddest,sizeof(ddsddest));
ddsddest.dwSize=sizeof(ddsddest);
this->m_pddsBackBuffer->Lock(NULL,&ddsddest,DDLOCK_WAIT,NULL);
WORD*buf=(WORD*)ddsddest.lpSurface;
long pitch=ddsddest.lPitch>>1;
int index=0;
DWORD dwWidth=pitch-m_nScreenWidth;
for(int j=0;j<this->m_nScreenHeight;j++)
{
for(int i=0;i<this->m_nScreenWidth;i++)
{
buf[index]=pGray(buf[index]);
index++;
}
index+=dwWidth;
}
this->m_pddsBackBuffer->Unlock(NULL);
}
while( 1 )
{
if( m_bWindowed )
hr = m_pddsFrontBuffer->Blt( &m_rcWindow, m_pddsBackBuffer,
NULL, DDBLT_WAIT, NULL );
else
hr = m_pddsFrontBuffer->BltFast(0,0,m_pddsBackBuffer,0,DDBLTFAST_WAIT);//Flip( NULL, 0 );
if( hr == DDERR_SURFACELOST )
{
m_pddsFrontBuffer->Restore();
m_pddsBackBuffer->Restore();
}
if( hr != DDERR_WASSTILLDRAWING )
return hr;
}
}
//-----------------------------------------------------------------------------
// Name:
// Desc:
//-----------------------------------------------------------------------------
HRESULT CDisplay::ShowBitmap( HBITMAP hbm, LPDIRECTDRAWPALETTE pPalette )
{
if( NULL == m_pddsFrontBuffer || NULL == m_pddsBackBuffer )
return E_POINTER;
// Set the palette before loading the bitmap
if( pPalette )
m_pddsFrontBuffer->SetPalette( pPalette );
CSurface backBuffer;
backBuffer.Create( m_pddsBackBuffer );
if( FAILED( backBuffer.DrawBitmap( hbm, 0, 0, 0, 0 ) ) )
return E_FAIL;
return Present();
}
//-----------------------------------------------------------------------------
// Name:
// Desc:
//-----------------------------------------------------------------------------
HRESULT CDisplay::ColorKeyBlt( DWORD x, DWORD y, LPDIRECTDRAWSURFACE7 pdds,
RECT* prc )
{
if( NULL == m_pddsBackBuffer )
return E_POINTER;
return Blt(x,y,pdds,prc,DDBLTFAST_SRCCOLORKEY);
}
#pragma warning(disable:4244)
WORD CDisplay::RGBTo16Bit(DWORD color)
{
BYTE b=(color&0x00ff0000)>>16;
BYTE g=(color&0x0000ff00)>>8;
BYTE r=(color&0x000000ff);
b>>=3;
g>>=2;
r>>=3;
return (b|(g<<6)|(r<<11));
}
WORD CDisplay::Alpha(WORD Sour,WORD Dest,int aValue)
{
DWORD dwDest=(Dest<<16)|Dest;
DWORD dwSour=(Sour<<16)|Sour;
dwDest&=m_dwAlphaMask;
dwSour&=m_dwAlphaMask;
DWORD value=(dwDest*(32-aValue)+dwSour*aValue)>>5;
value&=m_dwAlphaMask;
value|=(value>>16);
return (WORD)value;
}
WORD CDisplay::Gray555(WORD Sour)
{
WORD red=Sour>>10;
WORD green=(Sour&0x3e0)>>5;//0x3e0=0011,1110,0000
WORD blue=Sour&0x1f;
WORD value=(red*3+green*6+blue)/10;//RGB变灰度的公式
return value|(value<<5)|(value<<10);
}
WORD CDisplay::Gray565(WORD Sour)
{
WORD red=Sour>>11;
WORD green=(Sour&0x7e0)>>6; //0x7e0=0111,1110,0000,移动6位是为防止益出
WORD blue=Sour&0x1f;//0x1f=0001,1111
WORD value=(red*3+green*6+blue)/10;//RGB变灰度的公式
return value|(value<<6)|(value<<11);
}
HRESULT CDisplay::ColorAlphaBlt(DWORD dwColor,LPRECT pRectBlt,int iAlpha)
{
RECT rtClip;
DDSURFACEDESC2 ddsddest;
ZeroMemory(&ddsddest,sizeof(ddsddest));
ddsddest.dwSize=sizeof(ddsddest);
this->m_pddsBackBuffer->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);
this->m_pddsBackBuffer->Lock(NULL,&ddsddest,DDLOCK_WAIT,NULL);
WORD*buf=(WORD*)ddsddest.lpSurface;
int index;
WORD color=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);
}
}
this->m_pddsBackBuffer->Unlock(NULL);
return S_OK;
}
HRESULT CDisplay::AlphaBlt(int cx,int cy,LPDIRECTDRAWSURFACE7 pDD,LPRECT pSourRect,BOOL bColorKey,int iAlpha)
{
if(!pDD)
return S_OK;
if(iAlpha>31 || iAlpha<0)
return Blt(cx,cy,pDD,pSourRect,bColorKey);
DDSURFACEDESC2 ddsd,ddsdthis;
ZeroMemory(&ddsd,sizeof(ddsd));
ddsd.dwSize=sizeof(ddsd);
ZeroMemory(&ddsdthis,sizeof(ddsdthis));
ddsdthis.dwSize=sizeof(ddsdthis);
pDD->GetSurfaceDesc(&ddsd);
this->m_pddsBackBuffer->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);
}
this->m_pddsBackBuffer->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;
}
}
this->m_pddsBackBuffer->Unlock(NULL);
pDD->Unlock(NULL);
return S_OK;
}
//-----------------------------------------------------------------------------
// Name:
// Desc:
//-----------------------------------------------------------------------------
HRESULT CDisplay::Blt( int x, int y, LPDIRECTDRAWSURFACE7 pdds, RECT* prc,
DWORD dwFlags )
{
if( NULL == m_pddsBackBuffer )
return E_POINTER;
if(NULL==pdds)
return E_POINTER;
RECT Rect;
if(!prc)
{
DDSURFACEDESC2 ddsd;
ZeroMemory(&ddsd,sizeof(ddsd));
ddsd.dwSize=sizeof(ddsd);
pdds->GetSurfaceDesc(&ddsd);
Rect.left=0;
Rect.top=0;
Rect.right=ddsd.dwWidth;
Rect.bottom=ddsd.dwHeight;
}
else
{
Rect.left=prc->left;
Rect.top=prc->top;
Rect.right=prc->right;
Rect.bottom=prc->bottom;
}
if(x<0)
{
Rect.left-=x;//右移动
x=0;
}
if(y<0)
{
Rect.top-=y;//下移动
y=0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -