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

📄 tddrawbase.cpp

📁 一个小游戏程序!! 大家可以来
💻 CPP
📖 第 1 页 / 共 2 页
字号:
}
//-----------------------------------------------------------------------------

TDDrawDisplay::~TDDrawDisplay()
{
  DestroyObjects();
}
//-----------------------------------------------------------------------------

HRESULT TDDrawDisplay::DestroyObjects()
{
  SAFE_RELEASE( _BackBuffer );
  SAFE_RELEASE( _FrontBuffer );

  if(_DirectDraw)
    _DirectDraw->SetCooperativeLevel( _hWindow, DDSCL_NORMAL );
  SAFE_RELEASE(_DirectDraw);

  return S_OK;
}
//-----------------------------------------------------------------------------

HRESULT TDDrawDisplay::CreateFullScreenDisplay(DWORD dwWidth, DWORD dwHeight, DWORD dwBPP)
{
  DestroyObjects();

  if(FAILED(DirectDrawCreateEx(NULL, (VOID**)&_DirectDraw, IID_IDirectDraw7, NULL)))
    return E_FAIL;

  if(FAILED(_DirectDraw->SetCooperativeLevel(_hWindow, DDSCL_EXCLUSIVE|DDSCL_FULLSCREEN)))
    return E_FAIL;

  if(FAILED(_DirectDraw->SetDisplayMode(dwWidth, dwHeight, dwBPP, 0, 0)))
    return E_FAIL;

  _ScrWidth = dwWidth;
  _ScrHeight = dwHeight;

  DDSURFACEDESC2 ddsd;
  ZeroMemory( &ddsd, sizeof( ddsd ) );
  ddsd.dwSize            = sizeof( ddsd );
  ddsd.dwFlags           = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;
  ddsd.ddsCaps.dwCaps    = DDSCAPS_PRIMARYSURFACE | DDSCAPS_FLIP | DDSCAPS_COMPLEX | DDSCAPS_3DDEVICE;
  ddsd.dwBackBufferCount = 1; //Create primary surface (with backbuffer attached)

  if(FAILED(_DirectDraw->CreateSurface(&ddsd, &_FrontBuffer, NULL)))
    return E_FAIL;

  DDSCAPS2 ddscaps;
  ZeroMemory(&ddscaps, sizeof(ddscaps));
  ddscaps.dwCaps = DDSCAPS_BACKBUFFER; //Get a pointer to the back buffer

  if(FAILED(_FrontBuffer->GetAttachedSurface(&ddscaps, &_BackBuffer)))
    return E_FAIL;

  _BackBuffer->AddRef();
  _bWindowed = false;
  UpdateBounds();
  return S_OK;
}

//-----------------------------------------------------------------------------
HRESULT TDDrawDisplay::CreateWindowedDisplay(void)
{
  DestroyObjects();

  if(FAILED(DirectDrawCreateEx(NULL, (VOID**)&_DirectDraw, IID_IDirectDraw7, NULL)))
    return E_FAIL;

  if(FAILED(_DirectDraw->SetCooperativeLevel(_hWindow, DDSCL_NORMAL)))
    return E_FAIL;

  GetClientRect( _hWindow, &_WindowRect );

  DDSURFACEDESC2 ddsd;
  ZeroMemory( &ddsd, sizeof( ddsd ) );
  ddsd.dwSize         = sizeof( ddsd );
  ddsd.dwFlags        = DDSD_CAPS;
  ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; //Create the primary surface

  if(FAILED(_DirectDraw->CreateSurface(&ddsd, &_FrontBuffer, NULL)))
    return E_FAIL;

  ddsd.dwFlags        = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
  ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE; //Create the backbuffer surface
  ddsd.dwWidth        = _WindowRect.right - _WindowRect.left;
  ddsd.dwHeight       = _WindowRect.bottom - _WindowRect.top;

  if(FAILED(_DirectDraw->CreateSurface(&ddsd, &_BackBuffer, NULL)))
    return E_FAIL;

  LPDIRECTDRAWCLIPPER pcClipper;
  if(FAILED(_DirectDraw->CreateClipper(0, &pcClipper, NULL)))
    return E_FAIL;

  if(FAILED(pcClipper->SetHWnd( 0, _hWindow)))
   {
     pcClipper->Release();
     return E_FAIL;
   }

  if(FAILED(_FrontBuffer->SetClipper(pcClipper)))
   {
     pcClipper->Release();
     return E_FAIL;
   }
  pcClipper->Release();

  _bWindowed = true;
  UpdateBounds();
  return S_OK;
}
//-----------------------------------------------------------------------------

HRESULT TDDrawDisplay::Present()
{
  HRESULT hr;

  if((!_FrontBuffer) || (!_BackBuffer))
     return E_POINTER;

  while(1)
   {
     if(_bWindowed)
       hr = _FrontBuffer->Blt(&_WindowRect, _BackBuffer, NULL, DDBLT_WAIT, NULL);
     else
       hr = _FrontBuffer->Flip(NULL, 0);

     if(hr == DDERR_SURFACELOST)
      {
        _FrontBuffer->Restore();
        _BackBuffer->Restore();
      }

     if(hr != DDERR_WASSTILLDRAWING)
       return hr;
   }
}
//-----------------------------------------------------------------------------

HRESULT TDDrawDisplay::ShowBitmap( HBITMAP hbm, LPDIRECTDRAWPALETTE pPalette )
{
  if((!_FrontBuffer) || (!_BackBuffer))
    return E_POINTER;

  if(pPalette)
    _FrontBuffer->SetPalette( pPalette );

  TDDrawSurface backBuffer(this);
  backBuffer.Create(_BackBuffer);

  if(FAILED(backBuffer.DrawBitmap(hbm, 0, 0, 0, 0)))
    return E_FAIL;
  return Present();
}
//-----------------------------------------------------------------------------

HRESULT TDDrawDisplay::ColorKeyBlt(DWORD x, DWORD y, LPDIRECTDRAWSURFACE7 pdds, RECT* prc)
{
  if(!_BackBuffer)
    return E_POINTER;
  return _BackBuffer->BltFast(x, y, pdds, prc, DDBLTFAST_SRCCOLORKEY);
}
//-----------------------------------------------------------------------------

HRESULT TDDrawDisplay::Blt(DWORD x, DWORD y, LPDIRECTDRAWSURFACE7 pdds, RECT* prc, DWORD dwFlags)
{
  if(!_BackBuffer)
    return E_POINTER;
  return _BackBuffer->BltFast(x, y, pdds, prc, dwFlags);
}
//-----------------------------------------------------------------------------

HRESULT TDDrawDisplay::Blt(DWORD x, DWORD y, TDDrawSurface* pSurface, RECT* prc)
{
  if(!pSurface )
    return E_INVALIDARG;

  if(pSurface->ColorKeyed)
    return Blt(x, y, pSurface->DDrawSurface, prc, DDBLTFAST_SRCCOLORKEY);
  else
    return Blt(x, y, pSurface->DDrawSurface, prc, 0L);
}
//-----------------------------------------------------------------------------

HRESULT TDDrawDisplay::Clear(DWORD dwColor)
{
  if(!_BackBuffer)
    return E_POINTER;

  DDBLTFX ddbltfx;
  ZeroMemory(&ddbltfx, sizeof(ddbltfx));
  ddbltfx.dwSize      = sizeof(ddbltfx);
  ddbltfx.dwFillColor = dwColor;

  return _BackBuffer->Blt(NULL, NULL, NULL, DDBLT_COLORFILL, &ddbltfx);
}
//-----------------------------------------------------------------------------

HRESULT TDDrawDisplay::SetPalette( LPDIRECTDRAWPALETTE pPalette )
{
  if(!_FrontBuffer)
    return E_POINTER;
  return _FrontBuffer->SetPalette(pPalette);
}
//-----------------------------------------------------------------------------

HRESULT TDDrawDisplay::CreatePaletteFromBitmap(LPDIRECTDRAWPALETTE* ppPalette, const TCHAR* strBMP)
{
  HRSRC             hResource;
  RGBQUAD*          pRGB;
  BITMAPINFOHEADER* pbi;
  PALETTEENTRY      aPalette[256];
  HANDLE            hFile;
  DWORD             iColor;
  DWORD             dwColors;
  BITMAPFILEHEADER  bf;
  BITMAPINFOHEADER  bi;
  DWORD             dwBytesRead;

  if((!_DirectDraw) || (!strBMP) || (!ppPalette))
    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(!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 _DirectDraw->CreatePalette(DDPCAPS_8BIT, aPalette, ppPalette, NULL);
   }

  //Attempt to load bitmap as a file
  bool bOK = false;
  if((hFile=CreateFile( strBMP, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL))!=NULL)
   {
     ReadFile(hFile, &bf, sizeof(bf), &dwBytesRead, NULL); //Read the BITMAPFILEHEADER
     if(dwBytesRead == sizeof(bf))
      {
        ReadFile(hFile, &bi, sizeof(bi), &dwBytesRead, NULL); //Read the BITMAPINFOHEADER
        if(dwBytesRead == sizeof(bi))
         {
           ReadFile(hFile, aPalette, sizeof(aPalette), &dwBytesRead, NULL); //Read the PALETTEENTRY
           if(dwBytesRead == sizeof(aPalette))
             bOK = true;
         }
      }
     CloseHandle( hFile );
   }
  if(!bOK)return E_FAIL;

  //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 _DirectDraw->CreatePalette( DDPCAPS_8BIT, aPalette, ppPalette, NULL );
}

//-----------------------------------------------------------------------------
HRESULT TDDrawDisplay::UpdateBounds()
{
  if(_bWindowed)
   {
     GetClientRect(_hWindow, &_WindowRect);
     ClientToScreen(_hWindow, (POINT*)&_WindowRect);
     ClientToScreen(_hWindow, (POINT*)&_WindowRect+1);
   }
  else
   {
     SetRect(&_WindowRect, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN));
   }
  return S_OK;
}

//-----------------------------------------------------------------------------
HRESULT TDDrawDisplay::InitClipper()
{
  LPDIRECTDRAWCLIPPER pClipper;
  HRESULT hr;

  //Create a clipper when using GDI to draw on the primary surface 
  if(FAILED(hr=_DirectDraw->CreateClipper(0, &pClipper, NULL)))
    return hr;

  pClipper->SetHWnd(0, _hWindow);

  if(FAILED(hr=_FrontBuffer->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;
}
//-----------------------------------------------------------------------------

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -