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

📄 ddutil.cpp

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