📄 ddutil.cpp
字号:
_mm_empty(); // 执行MMX指令:emms,清除MMX寄存器中的内
}
}
m_pddsBackBuffer->Unlock(NULL); //Lock!
pSurface->GetDDrawSurface()->Unlock(NULL);
return DD_OK;
}
HRESULT CDisplay::AlphaBlt(int x,int y,CSurface* pSurface,BYTE alpha,DWORD KeyColor)
{
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 AlphaBlt(x1,y1,pSurface,&rt,alpha,KeyColor);
}
__int64 CDisplay::Get_int64(DWORD dwNum)
{
BYTE b = (BYTE)dwNum;
DWORD dwTmp = dwNum>>8;
BYTE g = (BYTE)dwTmp;
dwTmp >>= 8;
BYTE r = (BYTE)dwTmp;
dwTmp = RGB(r,g,b);
__int64 m;
m = dwTmp;
m <<= 32;
m |= dwTmp;
return m;
}
//带KeyColor的alpha的混合blt
HRESULT CDisplay::AlphaBlt(DWORD x,DWORD y,CSurface* pSurface,RECT* prc,BYTE alpha,DWORD KeyColor)
{
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 = alpha; //
if ( nChange > 255 )
nChange = 255;
else if ( nChange < -255 )
nChange = -255;
BYTE b = (BYTE) abs(nChange);
__int64 c = b;
__int64 mask = Get_int64(KeyColor);
c = 0x7F7F7F7F7F7F7F7F;//透明
int w = (prc->right-prc->left)/2;
int h = prc->bottom-prc->top;
//角的坐标
__asm
{
mov edx, src; //src应为储存特效图像的页面的指针
mov eax, dst; //dst应为后台缓存的指针(lpSurfase)
//add eax, destln;
mov ecx, h; //h为要处理的区域的高度
outloop:
push eax;
push edx;
mov ebx, w; //w为要处理的区域的宽度/2
innloop:
movq mm0, [eax]; //[] *()
movq mm1, [edx];
movq mm7, mm1;
pcmpeqw mm7,mask;//这里用来处理透明色的,我的思路就是透明色就用目的颜色填充源,,,
//pcmpeqw将MMX寄存器与MMX寄存器/ 内存单元中的字节组(字组,双字组)数据进行相等比较.
//该指令将目标操作数和源操作数的 相应数据元素进行比较,相等则目标寄存器的对应数据
//元素被置为全1,否则置为全0.
psubusw mm1,mm7; //这样,透明部分目的和源一样,不管怎么去alpha,只要公式是正确的,
pand mm7,mm0; //他们混合后的颜色就是不会变,add color特效也是同样的道理
por mm1,mm7; //
psrlw mm0, 1;
psrlw mm1,1;
pand mm1,c;
pand mm0, c; //实现"psrlb"
paddusb mm0, mm1;
movq [eax], mm0;
add eax, 8;
add edx, 8;
dec ebx;
jnz innloop;
pop edx;
pop eax;
add eax, destln;
add edx, srcln; //lP1应为储存特效图像的页面的lPitch
dec ecx;
jnz outloop;
emms;
}
m_pddsBackBuffer->Unlock(NULL); //Lock!
pSurface->GetDDrawSurface()->Unlock(NULL);
return DD_OK;
}
//add by ajohn
//作用:内存到离屏层的copy
HRESULT CDisplay::Qmemcpy(DWORD x,DWORD y,CSurface* pSurface,RECT* prc, int nQWORDs)
{
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; //目标指针
__m64* pIn = (__m64*) src; // 输入的字节数组指针
__m64* pOut = (__m64*) dst; // 输出的字节数组指针
__m64 tmp; // 临时工作变量
_mm_empty(); // 执行MMX指令:emms,初始化MMX寄存器
for(int j = 0;j<prc->bottom-prc->top;j++)
{
for ( int i = 0; i <(prc->right-prc->left)/2; i++ )
{
*(pOut+i) = *(pIn+i);
}
pIn+=srcln/8;
pOut+=destln/8;
_mm_empty(); // 执行MMX指令:emms,清除MMX寄存器中的内
}
m_pddsBackBuffer->Unlock(NULL); //Lock!
pSurface->GetDDrawSurface()->Unlock(NULL);
return 1;
}
//-----------------------------------------------------------------------------
// 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;
}
//-----------------------------------------------------------------------------
// Name:
// Desc:
//-----------------------------------------------------------------------------
CSurface::CSurface()
{
m_pdds = NULL;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -