📄 ddutil.cpp
字号:
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 );
}
//-----------------------------------------------------------------------------
// Name:
// Desc:
//-----------------------------------------------------------------------------
HRESULT CDisplay::Blt( int x, int y, CSurface* pSurface, RECT* prc )
{
if( NULL == pSurface )
return E_INVALIDARG;
RECT rcSrc;
int nX = x;
int nY = y;
int nSrcWidth = pSurface->GetWidth();
int nSrcHeight = pSurface->GetHeight();
int nScreenWidth = m_rcWindow.right - m_rcWindow.left;
int nScreenHeight = m_rcWindow.bottom - m_rcWindow.top;
if(prc)
{
nSrcWidth = prc->right - prc->left;
nSrcHeight = prc->bottom - prc->top;
rcSrc = *prc;
}
else
{
nSrcWidth = pSurface->GetWidth();
nSrcHeight = pSurface->GetHeight();
rcSrc.left = 0;
rcSrc.right = nSrcWidth;
rcSrc.top = 0;
rcSrc.bottom= nSrcHeight;
}
//超出屏幕,返回
if(x + nSrcWidth < 0 || y + nSrcHeight < 0 || x > nScreenWidth || y > nScreenHeight)
{
return DD_OK;
}
//左边在屏幕之外
if(x < 0)
{
rcSrc.left = -x;
nX = 0;
}
//右边在屏幕之外
if(x + nSrcWidth > nScreenWidth)
{
rcSrc.right = nScreenWidth - x;
}
//上边在屏幕之外
if(y < 0)
{
rcSrc.top = -y;
nY = 0;
}
//下边在屏幕之外
if(y + nSrcHeight > nScreenHeight)
{
rcSrc.bottom = nScreenHeight - y;
}
if( pSurface->IsColorKeyed() )
return Blt( nX, nY, pSurface->GetDDrawSurface(), &rcSrc, DDBLTFAST_SRCCOLORKEY );
else
return Blt( nX, nY, pSurface->GetDDrawSurface(), &rcSrc, 0L );
}
//-----------------------------------------------------------------------------
// Name:
// Desc:
//-----------------------------------------------------------------------------
HRESULT CDisplay::Blt( int x, int y, LPALPHASURFACE lpAlphaSurface, int nOption)
/*{
if(x >= m_rcWindow.right - m_rcWindow.left || y >= m_rcWindow.bottom - m_rcWindow.top)
return DD_OK;
HRESULT hr;
int i, j;
LPDIRECTDRAWSURFACE7 pBack = NULL, pSrc =NULL;
long lSrcPitch, lBackPitch; //源图面, BackBuffer 的图面pitch;
int nSrcWidth, nSrcHeight; //源图面的高与宽
int nBackHeight, nBackWidth; //Backbuffer 的高与宽
int nBltHeight, nBltWidth; //要显示的图面的高与宽
RECT rectSrcBlt;
DDSURFACEDESC2 ddsd;
WORD wTemp, *pwBack = NULL, *pwSrc = NULL;
WORD *pwBackLine = NULL, *pwSrcLine = NULL;
BYTE *pAlpha = lpAlphaSurface->lpAlpha;
BYTE *pAlphaLine = pAlpha;
float fAlpha; //alpha值
ZeroMemory( &ddsd, sizeof(ddsd) );
ddsd.dwSize = sizeof(ddsd);
pBack = GetBackBuffer();
pSrc = lpAlphaSurface->lpSurface->GetDDrawSurface();
nSrcWidth = lpAlphaSurface->lpSurface->GetWidth();
if(!FAILED(hr = pBack->Lock(NULL,&ddsd,DDLOCK_WAIT,NULL)))
{
pwBackLine = pwBack = (WORD *)ddsd.lpSurface;
lBackPitch = ddsd.lPitch;
nBackHeight = ddsd.dwHeight;
nBackWidth = ddsd.dwWidth;
if(!FAILED(hr = pSrc->Lock(NULL,&ddsd,DDLOCK_WAIT|DDLOCK_READONLY,NULL)))
{
pwSrcLine = pwSrc = (WORD *)ddsd.lpSurface;
lSrcPitch = ddsd.lPitch;
nSrcWidth = ddsd.dwWidth;
nSrcHeight = ddsd.dwHeight;
rectSrcBlt.left = 0;
rectSrcBlt.top = 0;
rectSrcBlt.right= nSrcWidth;
rectSrcBlt.bottom=nSrcHeight;
if( x < 0 )
{
rectSrcBlt.left = -x;
}
if( x + nSrcWidth < 0)
{
pSrc->Unlock(NULL);
pBack->Unlock(NULL);
return DD_OK;
}
if( x + nSrcWidth > nBackWidth )
{
if( x < nBackWidth)
rectSrcBlt.right = nBackWidth - x;
}
if( y < 0)
{
rectSrcBlt.top = -y;
}
if( y + nSrcHeight < 0)
{
pSrc->Unlock(NULL);
pBack->Unlock(NULL);
return DD_OK;
}
if( y + nSrcHeight > nBackHeight)
{
if( y < nBackHeight)
rectSrcBlt.bottom = nBackHeight - y;
}
pwBack = pwBack+(lBackPitch>>1) * (rectSrcBlt.top+y)+ rectSrcBlt.left+x ;
WORD nMMXCount=(rectSrcBlt.right-rectSrcBlt.left)/4;
WORD nNotMMX= (rectSrcBlt.right-rectSrcBlt.left)%4 ;
WORD nUseH=rectSrcBlt.bottom-rectSrcBlt.top;
_int64 mask1=0x003f003f003f003f,mask2=0x001f001f001f001f, mask3=0x00ff00ff00ff00ff;
_int64 m1=0x00000000ffff0000,m2=0x0000ffff00000000,m3=0xffff000000000000,m4=0x000000000000ffff;
if (nOption==0)
{
pwSrc =pwSrc+(lSrcPitch>>1)*rectSrcBlt.top+ rectSrcBlt.left ;
pAlpha =pAlpha+(nSrcWidth)*rectSrcBlt.top+rectSrcBlt.left;
__asm
{
mov ecx, dword ptr pAlpha;
mov eax, dword ptr pwSrc;
mov ebx, dword ptr pwBack;
mov dx, nUseH;
push dx;
push ecx;
push ebx;
push eax;
AddRow:
cmp dx, 0;
JE AllEnd;
xor dx,dx;
mov dx,nMMXCount;
NextMMX:
cmp dx,0;
JE NotMMX;
// 以下读入4个点,进行运算
movq mm0, [eax];
movq mm1, [ebx];
movq mm6, [ecx]; //读入8个点alpha: adcdefgh
punpcklbw mm6,mm6; //aabbccdd
pand mm6, mask3; //0a0b0c0d
//分离每个点的R G B值
movq mm2,mm0;//g
psrlw mm2,5;
pand mm2,mask1;
movq mm3,mm1;
psrlw mm3,5;
pand mm3,mask1;
movq mm4,mm0;//r
psrlw mm4,11;
pand mm4,mask2;
movq mm5,mm1;
psrlw mm5,11;
pand mm5,mask2;
pand mm0,mask2; //b
pand mm1,mask2;
// pwBack=pwSrc *fAlpha/255 + pwBack *(1-fAlpha/255)
// pwBack=((pwSrc-pwBack)*fAlpha+(pwBack<<5))>>5
psubsw mm0,mm1;//b
pmullw mm0,mm6;
psllw mm1, 8;
paddsw mm1,mm0;
psrlw mm1,8;
psubsw mm2,mm3;//g
pmullw mm2,mm6;
psllw mm3, 8;
paddsw mm3,mm2;
psrlw mm3,8;
psubsw mm4,mm5;//r
pmullw mm4,mm6;
psllw mm5, 8;
paddsw mm5,mm4;
psrlw mm5,8;
psllw mm3,5;
psllw mm5,11;
por mm1,mm3;
por mm1,mm5;
movq [ebx] , mm1;
add eax,8;
add ebx,8;
add ecx,4;
dec dx;
jmp NextMMX;
NotMMX:
xor dx, dx;
mov dx, nNotMMX;
NotNext:
cmp dx, 0;
JE RowEnd;
cmp [ecx],0xf0;
jbe Back;
movd mm1,[eax];
movd [ebx], mm1 ;
Back:
add eax,1;
add ebx,1;
add ecx,1;
dec dx;
jmp NotNext;
RowEnd:
pop eax;
add eax,lSrcPitch;
pop ebx;
add ebx,lBackPitch;
pop ecx;
add ecx,nSrcWidth;
pop dx;
dec dx;
push dx;
push ecx;
push ebx;
push eax;
jmp AddRow;
AllEnd:
pop eax;
pop ebx;
pop ecx;
pop dx;
emms;
}
}
else if (nOption==1)
{
pwSrc =pwSrc+(lSrcPitch>>1)*rectSrcBlt.top+(nSrcWidth-rectSrcBlt.left);
pAlpha =pAlpha+(nSrcWidth)*rectSrcBlt.top+(nSrcWidth-rectSrcBlt.left);
__asm
{
mov ecx, dword ptr pAlpha;
sub ecx, 4;
mov eax, dword ptr pwSrc;
sub eax, 8;
mov ebx, dword ptr pwBack;
mov dx, nUseH;
push dx;
push ecx;
push ebx;
push eax;
Add_Row:
cmp dx, 0;
JE All_End;
xor dx,dx;
mov dx,nMMXCount;
//dec dx;
Next_MMX:
cmp dx,0;
JE Not_MMX;
// 以下读入4个点,进行运算
movq mm0, [eax];
movq mm6, [ecx]; //读入8个点alpha: adcdefgh
punpcklbw mm6,mm6; //aabbccdd
pand mm6,mask3; //0a0b0c0d
movq mm2,mm0;
pand mm2,m1;
movq mm3,mm0;
pand mm3,m2;
movq mm4,mm0;
pand mm4,m3;
psrlq mm4,48;
psllq mm2,16;
psrlq mm3,16;
pand mm0,m4;
psllq mm0,48;
por mm0,mm2;
por mm0,mm3;
por mm0,mm4;
movq mm2,mm6;
pand mm2,m1;
movq mm3,mm6;
pand mm3,m2;
movq mm4,mm6;
pand mm4,m3;
psrlq mm4,48;
psllq mm2,16;
psrlq mm3,16;
pand mm6,m4;
psllq mm6,48;
por mm6,mm2;
por mm6,mm3;
por mm6,mm4;
movq mm1, [ebx];
//分离每个点的R G B值
movq mm2,mm0;//g
psrlw mm2,5;
pand mm2,mask1;
movq mm3,mm1;
psrlw mm3,5;
pand mm3,mask1;
movq mm4,mm0;//r
psrlw mm4,11;
pand mm4,mask2;
movq mm5,mm1;
psrlw mm5,11;
pand mm5,mask2;
pand mm0,mask2; //b
pand mm1,mask2;
// pwBack=pwSrc *fAlpha/255 + pwBack *(1-fAlpha/255)
// pwBack=((pwSrc-pwBack)*fAlpha+(pwBack<<5))>>5
psubsw mm0,mm1;//b
pmullw mm0,mm6;
psllw mm1, 8;
paddsw mm1,mm0;
psrlw mm1,8;
psubsw mm2,mm3;//g
pmullw mm2,mm6;
psllw mm3, 8;
paddsw mm3,mm2;
psrlw mm3,8;
psubsw mm4,mm5;//r
pmullw mm4,mm6;
psllw mm5, 8;
paddsw mm5,mm4;
psrlw mm5,8;
psllw mm3,5;
psllw mm5,11;
por mm1,mm3;
por mm1,mm5;
movq [ebx] , mm1;
sub eax,8;
add ebx,8;
sub ecx,4;
dec dx;
jmp Next_MMX;
Not_MMX:
xor dx, dx;
mov dx, nNotMMX;
Not_Next:
cmp dx, 0;
JE Row_End;
cmp [ecx],0xf0;
jbe _Back;
movd mm1,[eax];
movd [ebx], mm1 ;
_Back:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -