📄 basesurf.cpp
字号:
FillColorKey();
m_nOldBltMode = HX_BASIC_BLT;
m_bOffBecauseofShinking = FALSE;
}
}
return TRUE;
}
/************************************************************************
* Method:
* IUnknown::QueryInterface
*/
STDMETHODIMP CBaseSurface::QueryInterface(REFIID riid, void** ppvObj)
{
if (IsEqualIID(riid, IID_IHXVideoSurface))
{
AddRef();
*ppvObj = (IUnknown*)(IHXVideoSurface*)this;
return HXR_OK;
}
else if (IsEqualIID(riid, IID_IUnknown))
{
AddRef();
*ppvObj = (IUnknown*)(IHXSite*)this;
return HXR_OK;
}
else if (IsEqualIID(riid, IID_IHXVideoControl))
{
AddRef();
*ppvObj = (IUnknown*)(IHXVideoControl*)this;
return HXR_OK;
}
else if (IsEqualIID(riid, IID_IHXOverlayResponse))
{
AddRef();
*ppvObj = (IUnknown*)(IHXOverlayResponse*)this;
return HXR_OK;
}
*ppvObj = NULL;
return HXR_NOINTERFACE;
}
/************************************************************************
* Method:
* IUnknown::AddRef
*/
STDMETHODIMP_(ULONG32) CBaseSurface::AddRef()
{
return InterlockedIncrement(&m_lRefCount);
}
/************************************************************************
* Method:
* IUnknown::Release
*/
STDMETHODIMP_(ULONG32) CBaseSurface::Release()
{
if (InterlockedDecrement(&m_lRefCount) > 0)
{
return m_lRefCount;
}
delete this;
return 0;
}
BOOL CBaseSurface::IsPixelTransparent(HXxPoint& point, INT32 nAlphaLevel )
{
BOOL retVal = FALSE;
INT32 nCID = -1;
INT32 nPitch = 0;
HXxPoint origin = *(m_pSite->GetOrigin());
//It can only be transparent if we are blt'ing ARGB32.
nCID = GETBITMAPCOLOR(&m_bmiLastBlt);
nPitch = GETBITMAPPITCH(&m_bmiLastImage);
if( nCID == CID_ARGB32 )
{
if( m_pucLastImage )
{
UINT32* pPixel=NULL;
if( nPitch<0 )
{
pPixel = (UINT32*)(m_pucLastImage+m_bmiLastImage.biSizeImage+nPitch);
pPixel -= (point.y-origin.y)*m_bmiLastImage.biWidth - (point.x-origin.x);
}
else
{
pPixel = (UINT32*)m_pucLastImage;
pPixel += (point.y-origin.y)*m_bmiLastImage.biWidth + (point.x-origin.x);
}
if( pPixel>=(UINT32*)m_pucLastImage &&
pPixel<(UINT32*)(m_pucLastImage+m_bmiLastImage.biSizeImage))
{
int alpha = (*pPixel&0xff000000)>>24;
if( alpha > nAlphaLevel )
{
retVal = TRUE;
}
}
}
}
return retVal;
}
void CBaseSurface::_AlphaBlend( HXREGION* pRegionToBlend,
UCHAR* pBottomImage,
HXBitmapInfoHeader* pbmiBottomImageInfo,
HXxPoint* pBottomPosition,
UCHAR* pTopImage,
HXBitmapInfoHeader* pbmiTopImageInfo,
HXxPoint* pTopPosition
)
{
#ifdef _USE_MMX
static const BOOL bMMXAvailable = (checkMmxAvailablity()&CPU_HAS_MMX)?1:0;
#else
static const BOOL bMMXAvailable = FALSE;
#endif
#if defined(_DEBUG) && 0
_DumpRegion(pRegionToBlend);
#endif
if( pBottomImage == NULL || pTopImage == NULL )
{
return;
}
//Make sure we only try to alpha blend ARGB32 content.
int nCIDBottom = GETBITMAPCOLOR( pbmiBottomImageInfo );
int nCIDTop = GETBITMAPCOLOR( pbmiTopImageInfo );
int nBottomPitch = GETBITMAPPITCH( pbmiBottomImageInfo );
int nTopPitch = GETBITMAPPITCH( pbmiTopImageInfo );
if( nCIDTop != CID_ARGB32 || (nCIDBottom!=CID_ARGB32 && nCIDBottom!=CID_RGB32) )
{
HX_ASSERT( "Trying to alphablend unsupported type." );
return;
}
BOOL bFade=FALSE;
int completeness = 0;
if( (m_pSite->m_fpTransitionEffect == Crossfade ||
m_pSite->m_fpTransitionEffect == FadeToColor ||
m_pSite->m_fpTransitionEffect == FadeFromColor )
&& m_pSite->m_nTransitionState!= 1000 )
{
completeness = m_pSite->m_nTransitionState;
if((m_pSite->m_fpTransitionEffect != Crossfade &&
m_pSite->m_bTransitionReversed) ||
(m_pSite->m_fpTransitionEffect == Crossfade &&
(!m_pSite->m_bTransitionTranIn ^
m_pSite->m_bTransitionReversed)))
{
completeness = 1000 - completeness;
}
if( m_pSite->m_fpTransitionEffect== FadeFromColor)
{
completeness = 1000 - completeness;
}
//Map [0,1000] --> [0,1024] for fixed point fade math.
completeness = (int)((float)completeness*1024.0/1000.0);
bFade=TRUE;
}
if( !HXEmptyRegion(pRegionToBlend) )
{
int nBottomOffset = 0;
int nTopOffset = 0;
int nBotPosX = 0;
int nBotPosY = 0;
int nTopPosX = 0;
int nTopPosY = 0;
for(int i =0; i< pRegionToBlend->numRects; i++)
{
//We need to alpha blend each rect in the region.
int topX=0, topY = 0;
int botX=0, botY = 0;
topX = pRegionToBlend->rects[i].x1;
topY = pRegionToBlend->rects[i].y1;
botX = pRegionToBlend->rects[i].x2;
botY = pRegionToBlend->rects[i].y2;
if( nBottomPitch<0 )
nBottomOffset = -(pbmiBottomImageInfo->biWidth+(botX-topX));
else
nBottomOffset = pbmiBottomImageInfo->biWidth-(botX-topX);
if( nTopPitch<0 )
nTopOffset = -(pbmiTopImageInfo->biWidth+(botX-topX));
else
nTopOffset = pbmiTopImageInfo->biWidth-(botX-topX);
nTopPosX = pTopPosition->x;
nTopPosY = pTopPosition->y;
nBotPosX = pBottomPosition->x;
nBotPosY = pBottomPosition->y;
//blend this rect.
UINT32* pulBotPixel=NULL;
UINT32* pulTopPixel=NULL;
if( nBottomPitch<0 )
{
pulBotPixel = (UINT32*)(pBottomImage+pbmiBottomImageInfo->biSizeImage+nBottomPitch);
pulBotPixel -= ((topY-nBotPosY)*pbmiBottomImageInfo->biWidth - (topX-nBotPosX));
}
else
{
pulBotPixel = (UINT32*)pBottomImage;
pulBotPixel += ((topY-nBotPosY)*pbmiBottomImageInfo->biWidth + (topX-nBotPosX));
}
if( nTopPitch<0 )
{
pulTopPixel = (UINT32*)(pTopImage+pbmiTopImageInfo->biSizeImage+nTopPitch);
pulTopPixel -= ((topY-nTopPosY)*pbmiTopImageInfo->biWidth - (topX-nTopPosX));
}
else
{
pulTopPixel = (UINT32*)pTopImage;
pulTopPixel += ((topY-nTopPosY)*pbmiTopImageInfo->biWidth + (topX-nTopPosX));
}
int alpha = 0;
int alphasave = 0;
for( int y=topY ; y<=botY-1 ; y++ )
{
//XXXgfw this blows! We need a version of our MMX version
//for doing fades as well.
if( !bMMXAvailable || bFade )
{
for( int x=topX ; x<=botX-1 ; x++ )
{
//Blend it.
//We *MUST* preserve the alpha channel in the top image.
//This is needed for hit testing on transparent pixels.
if( !bFade )
{
alpha = 255-((*pulTopPixel & 0xff000000)>>24);
alphasave = *pulTopPixel & 0xff000000;
alpha = alpha>128 ? alpha + 1 : alpha;
}
else
{
if( m_pSite->m_fpTransitionEffect == Crossfade )
{
//fixed point version of (comp/1000 * alpha )
alpha = (*pulTopPixel & 0xff000000)>>24;
if( GETBITMAPCOLOR(&m_bmiLastBlt) != CID_ARGB32 )
alpha = 0x00;
alpha = ((completeness*(255-alpha)+512))>>10;
alphasave = (255-alpha)<<24;
}
else if( m_pSite->m_fpTransitionEffect == FadeToColor ||
m_pSite->m_fpTransitionEffect == FadeFromColor)
{
//Not only affect alpha but also fading to color.
alpha = (completeness*255+512)>>10;
UINT32 fadeColor = (m_pSite->m_ulTransitionFadeColor&0x00ffffff)|(alpha<<24);
int a1 = 255-((*pulTopPixel&0xff000000)>>24);
*pulTopPixel =
(((alpha*( (fadeColor&0x00ff0000)-(*pulTopPixel&0x00ff0000))+((*pulTopPixel&0x00ff0000)<<8))>>8)&0x00ff0000)|
(((alpha*( (fadeColor&0x0000ff00)-(*pulTopPixel&0x0000ff00))+((*pulTopPixel&0x0000ff00)<<8))>>8)&0x0000ff00)|
(((alpha*( (fadeColor&0x000000ff)-(*pulTopPixel&0x000000ff))+((*pulTopPixel&0x000000ff)<<8))>>8)&0x000000ff);
if( alpha<a1 )
alpha = a1;
//Now make sure the rest of the blending uses the
//new alpha channel from the FadeToColor state.
alphasave = *pulTopPixel & ((255-alpha)<<24);
//OK, we never alpha blend if a renderer outputs in plain old
//RGB, only if they output in ARGB. Now, some renderer blt'ing in
//RGB32 output random numbers, all zeros or all 0xFF in the alpha
//channel. That can screw us up, so we will just set it here to not
//have an alpha channel.
if( GETBITMAPCOLOR(&m_bmiLastBlt) != CID_ARGB32 )
alpha = 0xFF;
}
}
*pulTopPixel =
(((alpha*( (*pulTopPixel&0x00ff0000)-(*pulBotPixel&0x00ff0000))+((*pulBotPixel&0x00ff0000)<<8))>>8)&0x00ff0000)|
(((alpha*( (*pulTopPixel&0x0000ff00)-(*pulBotPixel&0x0000ff00))+((*pulBotPixel&0x0000ff00)<<8))>>8)&0x0000ff00)|
(((alpha*( (*pulTopPixel&0x000000ff)-(*pulBotPixel&0x000000ff))+((*pulBotPixel&0x000000ff)<<8))>>8)&0x000000ff);
*pulTopPixel = *pulTopPixel|alphasave;
//Next pixel
pulBotPixel++;
pulTopPixel++;
}
//Next row.
pulBotPixel += nBottomOffset;
pulTopPixel += nTopOffset;
}
else
{
#ifdef _USE_MMX
//Use MMX version of blender
AlphaBlendMMX( pulTopPixel,
pulBotPixel,
(botX-topX)
);
//Next row.
pulBotPixel += nBottomOffset+(botX-topX);
pulTopPixel += nTopOffset+(botX-topX);
#endif
}
}
#ifdef _USE_MMX
//Do our emms instruction here so we don't have do it each
//line. It is a expensive operation.
#ifdef _WIN32
__asm emms
#elif defined(_LINUX)
__asm__ __volatile__ ( "emms" );
#endif
#endif
}
}
}
#if 0
void CBaseSurface::DrawCheckerBoard(UCHAR *pY, UCHAR *pU, UCHAR *pV,
INT32 nYPitch, INT32 nUPitch, INT32 nVPitch,
INT32 nImageWidth, INT32 nImageHeight)
{
const int COLS = 5;
const int ROWS = 5;
int Y[2] = {255, 0};
int Cb = 128;
int Cr = 128;
int nColWidth = nImageWidth/COLS;
int nRowWidth = nImageHeight/ROWS;
IHXPreferences* pPreferences = NULL;
IHXBuffer* pBuffer = NULL;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -