📄 ddraw04.cpp
字号:
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 + -