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

📄 ddraw04.cpp

📁 《Visual C 6.0高级编程技术——DirectX篇》程序源代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
  HRESULT ddrval, hr;

  //  try to load the bitmap as a resource, if that fails, try it as a file
  hbm = ( HBITMAP )LoadImage( GetModuleHandle( NULL ), szBitmap, IMAGE_BITMAP, dx, dy, LR_CREATEDIBSECTION );
  if( hbm == NULL )
  	hbm = ( HBITMAP )LoadImage( NULL, szBitmap, IMAGE_BITMAP, dx, dy, LR_LOADFROMFILE | LR_CREATEDIBSECTION );
  if( hbm == NULL )
  {
    OutputDebugString("handle is null\n");
    return NULL;
  }

  // get size of the bitmap
  GetObject( hbm, sizeof( bm ), &bm );      // get size of bitmap

  // 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 = bm.bmWidth;
  ddsd.dwHeight = bm.bmHeight;
  ddrval = pdd->CreateSurface( &ddsd, &pdds, NULL );
  if( ddrval != DD_OK )
  {
  	OutputDebugString("DirectDraw CreateSurface failed\n");
    return NULL;
  }

  hr = DDCopyBitmap( pdds, hbm, 0, 0, 0, 0 );
  if( hr != DD_OK )
  {
  	OutputDebugString("ddcopybitmap failed\n");
  }

  DeleteObject( hbm );
  return pdds;
}

// DDAttachBitmap
// load a bitmap from a file or resource into a directdraw surface.
// normaly used to re-load a surface after a restore.
HRESULT DDAttachBitmap( LPDIRECTDRAWSURFACE pdds, LPCSTR szBitmap )
//HRESULT DDAttachBitmap( IDirectDrawSurface *pdds, LPCSTR szBitmap )
{
  HBITMAP hbm;
  HRESULT hr;

  //  try to load the bitmap as a resource, if that fails, try it as a file
  hbm = (HBITMAP)LoadImage(GetModuleHandle(NULL), szBitmap, IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION);
  if (hbm == NULL)
  	hbm = (HBITMAP)LoadImage(NULL, szBitmap, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE|LR_CREATEDIBSECTION);
  if (hbm == NULL)
  {
  	OutputDebugString("handle is null\n");
	  return E_FAIL;
  }
  hr = DDCopyBitmap(pdds, hbm, 0, 0, 0, 0);
  if (hr != DD_OK)
  {
  	OutputDebugString("ddcopybitmap failed\n");
  }
  DeleteObject(hbm);
  return hr;
}

// DDCopyBitmap
// draw a bitmap into a DirectDrawSurface
HRESULT DDCopyBitmap( LPDIRECTDRAWSURFACE pdds, HBITMAP hbm, int x, int y, int dx, int dy )
//HRESULT DDCopyBitmap( IDirectDrawSurface *pdds, HBITMAP hbm, int x, int y, int dx, int dy )
{
  HDC hdcImage;
  HDC hdc;
  BITMAP bm;
  DDSURFACEDESC ddsd;
  HRESULT hr;

  if (hbm == NULL || pdds == NULL)
  	return E_FAIL;

  // make sure this surface is restored.
  pdds->Restore();

  //  select bitmap into a memoryDC so we can use it.
  hdcImage = CreateCompatibleDC(NULL);
  if (!hdcImage)
  	OutputDebugString("createcompatible dc failed\n");
  SelectObject(hdcImage, hbm);

  // get size of the bitmap
  GetObject(hbm, sizeof(bm), &bm);    // get size of bitmap
  dx = dx == 0 ? bm.bmWidth  : dx;    // use the passed size, unless zero
  dy = dy == 0 ? bm.bmHeight : dy;

  // get size of surface.
  ddsd.dwSize = sizeof(ddsd);
  ddsd.dwFlags = DDSD_HEIGHT | DDSD_WIDTH;
  pdds->GetSurfaceDesc(&ddsd);

  if ((hr = pdds->GetDC(&hdc)) == DD_OK)
  {
  	StretchBlt(hdc, 0, 0, ddsd.dwWidth, ddsd.dwHeight, hdcImage, x, y, dx, dy, SRCCOPY);
	  pdds->ReleaseDC(hdc);
  }

  DeleteDC(hdcImage);
  return hr;
}

// RestoreAllDirectDrawObjects
// restore all lost objects
HRESULT RestoreAllDirectDrawObjects( void )
{
  HRESULT	ddrval;
  ddrval = lpDDSPrimary->Restore();
  if( ddrval == DD_OK )
  {
  	ddrval = lpDDSOne->Restore();
	  if( ddrval == DD_OK )
	  {
      DDAttachBitmap( lpDDSOne, szBitmap );
	  }
  }
  return ddrval;
} /* restoreAll */

// UpdateFrame
// Decide what needs to be blitted next, wait for flip to complete, then flip the buffers.
void UpdateFrame( void )
{
//  static DWORD lastTickCount[3] = {0,0,0};
  static int currentFrame[ MAX_SPRITES ] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
//  DWORD thisTickCount;
  RECT rcRect;
//  DWORD delay[3] = {50, 78, 13};
  int i;
  int	xpos[ MAX_SPRITES ] = { 67, 128, 200, 288, 313, 390, 476, 555, 555, 555 };
  int	ypos[ MAX_SPRITES ] = { 67,  97, 256, 288, 190, 416, 288, 190, 288, 400 };
  HRESULT	ddrval;

  // Decide which frame will be blitted next
//  thisTickCount = GetTickCount();
  for( i = 0; i < MAX_SPRITES; i++ )
  {
/*
  	if((thisTickCount - lastTickCount[i]) > delay[i])
	  {
	    // Move to next frame;
	    lastTickCount[i] = thisTickCount;
	    currentFrame[i]++;
	    if(currentFrame[i] > 59)
	    {
		    currentFrame[i] = 0;
	    }
	  }
*/
    currentFrame[ i ]++;
	  if(currentFrame[ i ] > 59)
	  {
	    currentFrame[ i ] = 0;
	  }
  }

  // Blit the stuff for the next frame
  rcRect.left = 0;
  rcRect.top = 0;
  rcRect.right = 640;
  rcRect.bottom = 480;
  while( TRUE )
  {
    ddrval = lpDDSBack->BltFast( 0, 0, lpDDSOne, &rcRect, DDBLTFAST_NOCOLORKEY );
  	if( ddrval == DD_OK )
	  {
	    break;
	  }
	  if( ddrval == DDERR_SURFACELOST )
	  {
	    ddrval = RestoreAllDirectDrawObjects();
	    if( ddrval != DD_OK )
	    {
		    return;
	    }
	  }
	  if( ddrval != DDERR_WASSTILLDRAWING )
	  {
	    return;
	  }
  }
  if(ddrval != DD_OK)
  {
  	return;
  }

  for( i = 0; i < MAX_SPRITES; i++ )
  {
    rcRect.left = currentFrame[ i ] % 10 * 64;
    rcRect.top = currentFrame[ i ] / 10 * 64 + 480;
    rcRect.right = currentFrame[ i ] % 10 * 64 + 64;
    rcRect.bottom = currentFrame[ i ] / 10 * 64 + 64 + 480;
  	while( TRUE )
	  {
	    ddrval = lpDDSBack->BltFast( xpos[i], ypos[i], lpDDSOne, &rcRect, DDBLTFAST_SRCCOLORKEY );
	    if( ddrval == DD_OK )
	    {
		    break;
	    }
	    if( ddrval == DDERR_SURFACELOST )
	    {
    		ddrval = RestoreAllDirectDrawObjects();
		    if( ddrval != DD_OK )
		    {
		      return;
		    }
	    }
	    if( ddrval != DDERR_WASSTILLDRAWING )
	    {
		    return;
	    }
	  }
  }

  // Flip the surfaces
  while( TRUE )
  {
  	ddrval = lpDDSPrimary->Flip( NULL, 0 );
	  if( ddrval == DD_OK )
	  {
	    break;
	  }
	  if( ddrval == DDERR_SURFACELOST )
	  {
	    ddrval = RestoreAllDirectDrawObjects();
	    if( ddrval != DD_OK )
	    {
		    break;
	    }
	  }
	  if( ddrval != DDERR_WASSTILLDRAWING )
	  {
	    break;
	  }
  }
} /* updateFrame */

//  DDLoadPalette
//
//  Create a DirectDraw palette object from a bitmap resoure
//
//  if the resource does not exist or NULL is passed create a
//  default 332 palette.
//
LPDIRECTDRAWPALETTE DDLoadPalette( LPDIRECTDRAW pdd, LPCSTR szBitmap )
//IDirectDrawPalette * DDLoadPalette( IDirectDraw *pdd, LPCSTR szBitmap )
{
//  IDirectDrawPalette* ddpal;
  LPDIRECTDRAWPALETTE ddpal;
  int                 i;
  int                 n;
  int                 fh;
  HRSRC               h;
  LPBITMAPINFOHEADER  lpbi;
  PALETTEENTRY        ape[ 256 ];
  RGBQUAD *           prgb;

  // build a 332 palette as the default.
  for( i=0; i<256; i++ )
  {
  	ape[ i ].peRed   = ( BYTE )( ( ( i >> 5 ) & 0x07 ) * 255 / 7 );
	  ape[ i ].peGreen = ( BYTE )( ( ( i >> 2 ) & 0x07 ) * 255 / 7 );
	  ape[ i ].peBlue  = ( BYTE )( ( ( i >> 0 ) & 0x03 ) * 255 / 3 );
	  ape[ i ].peFlags = ( BYTE )0;
  }

  // get a pointer to the bitmap resource.
  if( szBitmap && ( h = FindResource( NULL, szBitmap, RT_BITMAP ) ) )
  {
  	lpbi = ( LPBITMAPINFOHEADER )LockResource( LoadResource( NULL, h ) );
	  if( !lpbi )
	    OutputDebugString( "lock resource failed\n" );
	  prgb = ( RGBQUAD * )( ( BYTE * )lpbi + lpbi->biSize );

	  if( lpbi == NULL || lpbi->biSize < sizeof( BITMAPINFOHEADER ) )
	    n = 0;
	  else if( lpbi->biBitCount > 8 )
	    n = 0;
	  else if( lpbi->biClrUsed == 0 )
	    n = 1 << lpbi->biBitCount;
	  else
	    n = lpbi->biClrUsed;

  	//  a DIB color table has its colors stored BGR not RGB
	  //  so flip them around.
	  for( i=0; i<n; i++ )
	  {
      ape[ i ].peRed   = prgb[ i ].rgbRed;
	    ape[ i ].peGreen = prgb[ i ].rgbGreen;
	    ape[ i ].peBlue  = prgb[ i ].rgbBlue;
	    ape[ i ].peFlags = 0;
	  }
  }
  else if( szBitmap && ( fh = _lopen( szBitmap, OF_READ ) ) != -1 )
  {
	  BITMAPFILEHEADER bf;
	  BITMAPINFOHEADER bi;

	  _lread( fh, &bf, sizeof( bf ) );
	  _lread( fh, &bi, sizeof( bi ) );
	  _lread( fh, ape, sizeof( ape ) );
	  _lclose( fh );

	  if( bi.biSize != sizeof( BITMAPINFOHEADER ) )
	    n = 0;
	  else if( bi.biBitCount > 8 )
	    n = 0;
	  else if( bi.biClrUsed == 0 )
	    n = 1 << bi.biBitCount;
	  else
	    n = bi.biClrUsed;

  	//  a DIB color table has its colors stored BGR not RGB
	  //  so flip them around.
	  for( i=0; i<n; i++ )
	  {
	    BYTE r = ape[ i ].peRed;
	    ape[ i ].peRed = ape[ i ].peBlue;
	    ape[ i ].peBlue = r;
  	}
  }

  pdd->CreatePalette( DDPCAPS_8BIT, ape, &ddpal, NULL );

  return ddpal;
}

// DDConvertRGBToPysicalColor
// convert a RGB color to a pysical color.
// we do this by leting GDI SetPixel() do the color matching
// then we lock the memory and see what it got mapped to.
DWORD DDConvertRGBToPysicalColor( LPDIRECTDRAWSURFACE pdds, COLORREF rgb )
//DWORD DDConvertRGBToPysicalColor( IDirectDrawSurface *pdds, COLORREF rgb )
{
  COLORREF rgbT;
  HDC hdc;
  DWORD dw = CLR_INVALID;
  DDSURFACEDESC ddsd;
  HRESULT hres;

  // Use GDI SetPixel to color match for us
  if( rgb != CLR_INVALID && pdds->GetDC( &hdc ) == DD_OK )
  {
  	rgbT = GetPixel( hdc, 0, 0 ); // save current pixel value
	  SetPixel( hdc, 0, 0, rgb ); // set our value
	  pdds->ReleaseDC( hdc );
  }

  // Lock the surface so we can read back the converted color
  ddsd.dwSize = sizeof( ddsd );
  while( ( hres = pdds->Lock( NULL, &ddsd, 0, NULL ) ) == DDERR_WASSTILLDRAWING )
    ;

  if( hres == DD_OK )
  {
  	dw  = *( DWORD * )ddsd.lpSurface; // get DWORD
    if( ddsd.ddpfPixelFormat.dwRGBBitCount < 32 )
      dw &= ( 1 << ddsd.ddpfPixelFormat.dwRGBBitCount ) - 1;  // mask it to bpp
	  pdds->Unlock( NULL );
  }

  // Put the color that was there back.
  if( rgb != CLR_INVALID && pdds->GetDC( &hdc ) == DD_OK )
  {
  	SetPixel( hdc, 0, 0, rgbT );
	  pdds->ReleaseDC( hdc );
  }

  return dw;
}

// DDSetColorKey
// set a color key for a surface, given a RGB.
// if you pass CLR_INVALID as the color key, the pixel
// in the upper-left corner will be used.
HRESULT DDSetColorKey( LPDIRECTDRAWSURFACE pdds, COLORREF rgb )
//HRESULT DDSetColorKey( IDirectDrawSurface *pdds, COLORREF rgb )
{
  DDCOLORKEY ddck;
  ddck.dwColorSpaceLowValue  = DDConvertRGBToPysicalColor( pdds, rgb );
  ddck.dwColorSpaceHighValue = ddck.dwColorSpaceLowValue;
  return pdds->SetColorKey( DDCKEY_SRCBLT, &ddck );
}

// Inserted code end

⌨️ 快捷键说明

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