⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ddutil.cpp

📁 一款45度2D游戏地图编辑器和大家一起分享啊!
💻 CPP
📖 第 1 页 / 共 4 页
字号:
			_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 + -