📄 ddutil.cpp
字号:
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;
}
//add by ajohn 创建一个大小为文件指定的页面,不需要自己指定
HRESULT CDisplay::CreateSurfaceFromBitmap( CSurface** ppSurface,
TCHAR* strBMP,DWORD nFlags)
{
HRESULT hr;
HBITMAP hBMP = NULL;
BITMAP bmp;
DWORD dwDesiredWidth;
DWORD dwDesiredHeight;
DDSURFACEDESC2 ddsd;
if( m_pDD == NULL || strBMP == NULL || ppSurface == NULL )
return E_INVALIDARG;
*ppSurface = NULL;
// Try to load the bitmap as a resource, if that fails, try it as a file
/* HANDLE file=NULL; //定义一个文件
file = CreateFile(strBMP,GENERIC_READ|GENERIC_WRITE,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_READONLY,NULL);
//打开文件
if (file) //打开文件
{
BITMAPFILEHEADER bmfHeader; //位图信息头
DWORD length = sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER); //
DWORD a;
char* bitmap = new char[length+1];
if ( ReadFile(file,bitmap,length,&a,NULL)) //从文件中读取文件头,我们只需要得到宽度和高度
{
strncpy((LPSTR)&bmfHeader, (LPSTR)bitmap, (DWORD)sizeof(bmfHeader));
if (bmfHeader.bfType == (*(WORD*)"BM") )//BM代表位图必须为BM
{
LPSTR lpDIB = bitmap + sizeof(bmfHeader); //内存指针的+运算
BITMAPINFOHEADER &bmiHeader = *(LPBITMAPINFOHEADER)lpDIB;//读内存 强制装换
dwDesiredWidth = bmiHeader.biWidth;
dwDesiredHeight = bmiHeader.biHeight;
}
else
{
return E_FAIL;
}
}
delete[] bitmap;
}
CloseHandle(file); //关闭文件*/
HANDLE file;
file = CreateFile(strBMP,GENERIC_READ|GENERIC_WRITE,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_READONLY,NULL);
BITMAPFILEHEADER fileinfo;
BITMAPINFOHEADER bmpinfo;
DWORD a;
ReadFile(file,&fileinfo,sizeof(fileinfo),&a,NULL);
ReadFile(file,&bmpinfo,sizeof(bmpinfo),&a,NULL);
dwDesiredWidth = bmpinfo.biWidth;
dwDesiredHeight = bmpinfo.biHeight;
CloseHandle(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;
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,DWORD nFlags)
{
HDC hDC = NULL;
LPDIRECTDRAWSURFACE7 pDDS = 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 = nFlags;
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;
while( 1 )
{
if( m_bWindowed )
hr = m_pddsFrontBuffer->Blt( &m_rcWindow, m_pddsBackBuffer,
NULL, DDBLT_WAIT, NULL );
else
hr = m_pddsFrontBuffer->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 m_pddsBackBuffer->BltFast( x, y, pdds, prc, DDBLTFAST_SRCCOLORKEY );
}
//-----------------------------------------------------------------------------
// Name:
// Desc:
//-----------------------------------------------------------------------------
HRESULT CDisplay::Blt( DWORD x, DWORD y, LPDIRECTDRAWSURFACE7 pdds, RECT* prc,
DWORD dwFlags )
{
if( NULL == m_pddsBackBuffer )
return E_POINTER;
return m_pddsBackBuffer->BltFast( x, y, pdds, prc, dwFlags );
}
HRESULT CDisplay::Blt(int x,int y,CSurface* pSurface)
{
int p = -(pSurface->GetDDrawDesc().dwWidth);
int k = (-pSurface->GetDDrawDesc().dwHeight);
if(x<0&&x<p) return E_FAIL;
if(y<0&&y<k) return E_FAIL;
if(x>(int)ddsd.dwWidth) return E_FAIL;
if(y>(int)ddsd.dwHeight) return E_FAIL;
//if((x<0&&x<p)||(y<0&&y<k)||x>ddsd.dwWidth||y>ddsd.dwHeight)
// return E_FAIL;
RECT rt;
int x1,y1;
x1 = x>0?x:0;
y1 = y>0?y:0;
rt.left = x>0?0:-x;
if(x>0)
rt.right = (x+pSurface->GetDDrawDesc().dwWidth)>ddsd.dwWidth?(ddsd.dwWidth-x):(pSurface->GetDDrawDesc().dwWidth);
else
{
rt.right = (pSurface->GetDDrawDesc().dwWidth+x)>ddsd.dwWidth?(ddsd.dwWidth):(pSurface->GetDDrawDesc().dwWidth);
}
rt.top = y>0?0:-y;
if(y>0)
rt.bottom =(y+pSurface->GetDDrawDesc().dwHeight)>ddsd.dwHeight?(ddsd.dwHeight-y):(pSurface->GetDDrawDesc().dwHeight);
else
rt.bottom =(pSurface->GetDDrawDesc().dwHeight+y)>ddsd.dwHeight?(ddsd.dwHeight):(pSurface->GetDDrawDesc().dwHeight);
return Blt(x1,y1,pSurface,&rt);
}
__m64 CDisplay::Get_m64(__int64 n)
{
union __m64__m64
{
__m64 m;
__int64 i;
} mi;
mi.i = n;
return mi.m;
}
//加亮,减暗的Blt
HRESULT CDisplay::ShadleBlt(DWORD x,DWORD y,CSurface* pSurface,RECT* prc,int shadle)
{
DDSURFACEDESC2 ddsd, ddsd2; //DirectDraw页面描述
ZeroMemory(&ddsd, sizeof(ddsd)); //ddsd用前要清空
ddsd.dwSize = sizeof(ddsd); //DirectDraw中的对象都要这样
ZeroMemory(&ddsd2, sizeof(ddsd2));
ddsd2.dwSize = sizeof(ddsd2);
//
m_pddsBackBuffer->Lock(NULL, &ddsd, DDLOCK_WAIT, NULL); //Lock!
pSurface->GetDDrawSurface()->Lock(NULL, &ddsd2, DDLOCK_WAIT, NULL);
BYTE *dst = (BYTE*)ddsd.lpSurface; //Lock后页面的信息被存在这里,请注意
//这个指针可能每次Lock( )后都不同!
BYTE *src = (BYTE*)ddsd2.lpSurface;
DWORD destln = ddsd.lPitch;
DWORD srcln = ddsd2.lPitch;
src = src+prc->top*srcln+prc->left*4; //源指针
dst = dst+y*destln+x*4; //目标指针
int nChange = shadle; //
if ( nChange > 255 )
nChange = 255;
else if ( nChange < -255 )
nChange = -255;
BYTE b = (BYTE) abs(nChange);
__int64 c = b;
for ( int i = 1; i <= 7; i++ )
{
c = c << 8;
c |= b;
}
__m64* pIn = (__m64*) src; // 输入的字节数组指针
__m64* pOut = (__m64*) dst; // 输出的字节数组指针
__m64 tmp; // 临时工作变量
_mm_empty(); // 执行MMX指令:emms,初始化MMX寄存器
__m64 nChange64 = Get_m64(c);
if(nChange>0)
{
for(int j = 0;j<prc->bottom-prc->top;j++)
{
for ( int i = 0; i <(prc->right-prc->left)/2; i++ )
{
tmp = _mm_adds_pu8(*(pIn+i), nChange64); // 饱和模式下的无符号加法
// 对每一个字节执行操作:tmp = *pIn + nChange64
*(pOut+i) = tmp;
}
pIn+=srcln/8;
pOut+=destln/8;
_mm_empty(); // 执行MMX指令:emms,清除MMX寄存器中的内
}
}
else
{
for(int j = 0;j<prc->bottom-prc->top;j++)
{
for ( int i = 0; i <(prc->right-prc->left)/2; i++ )
{
tmp = _mm_subs_pu8(*(pIn+i), nChange64); // 饱和模式下的无符号加法
// 对每一个字节执行操作:tmp = *pIn + nChange64
*(pOut+i) = tmp;
}
pIn+=srcln/8;
pOut+=destln/8;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -