📄 ddutil.cpp
字号:
//-----------------------------------------------------------------------------
// Name:
// Desc:
//-----------------------------------------------------------------------------
CSurface::CSurface()
{
m_pdds = NULL;
m_bColorKeyed = NULL;
}
//-----------------------------------------------------------------------------
// Name:
// Desc:
//-----------------------------------------------------------------------------
CSurface::~CSurface()
{
SAFE_RELEASE( m_pdds );
}
//-----------------------------------------------------------------------------
// Name:
// Desc:
//-----------------------------------------------------------------------------
HRESULT CSurface::Create( LPDIRECTDRAWSURFACE7 pdds )
{
m_pdds = pdds;
if( m_pdds )
{
m_pdds->AddRef();
// Get the DDSURFACEDESC structure for this surface
m_ddsd.dwSize = sizeof(m_ddsd);
m_pdds->GetSurfaceDesc( &m_ddsd );
}
return S_OK;
}
//-----------------------------------------------------------------------------
// Name:
// Desc:
//-----------------------------------------------------------------------------
HRESULT CSurface::Create( LPDIRECTDRAW7 pDD, DDSURFACEDESC2* pddsd )
{
HRESULT hr;
// Create the DDraw surface
if( FAILED( hr = pDD->CreateSurface( pddsd, &m_pdds, NULL ) ) )
return hr;
// Prepare the DDSURFACEDESC structure
m_ddsd.dwSize = sizeof(m_ddsd);
// Get the DDSURFACEDESC structure for this surface
m_pdds->GetSurfaceDesc( &m_ddsd );
return S_OK;
}
//-----------------------------------------------------------------------------
// Name:
// Desc:
//-----------------------------------------------------------------------------
HRESULT CSurface::Destroy()
{
SAFE_RELEASE( m_pdds );
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: CSurface::DrawBitmap()
// Desc: Draws a bitmap over an entire DirectDrawSurface, stretching the
// bitmap if nessasary
//-----------------------------------------------------------------------------
HRESULT CSurface::DrawBitmap( HBITMAP hBMP,
DWORD dwBMPOriginX, DWORD dwBMPOriginY,
DWORD dwBMPWidth, DWORD dwBMPHeight )
{
HDC hDCImage;
HDC hDC;
BITMAP bmp;
DDSURFACEDESC2 ddsd;
HRESULT hr;
if( hBMP == NULL || m_pdds == NULL )
return E_INVALIDARG;
// Make sure this surface is restored.
if( FAILED( hr = m_pdds->Restore() ) )
return hr;
// Get the surface.description
ddsd.dwSize = sizeof(ddsd);
m_pdds->GetSurfaceDesc( &ddsd );
if( ddsd.ddpfPixelFormat.dwFlags == DDPF_FOURCC )
return E_NOTIMPL;
// Select bitmap into a memoryDC so we can use it.
hDCImage = CreateCompatibleDC( NULL );
if( NULL == hDCImage )
return E_FAIL;
SelectObject( hDCImage, hBMP );
// Get size of the bitmap
GetObject( hBMP, sizeof(bmp), &bmp );
// Use the passed size, unless zero
dwBMPWidth = ( dwBMPWidth == 0 ) ? bmp.bmWidth : dwBMPWidth;
dwBMPHeight = ( dwBMPHeight == 0 ) ? bmp.bmHeight : dwBMPHeight;
// Stretch the bitmap to cover this surface
if( FAILED( hr = m_pdds->GetDC( &hDC ) ) )
return hr;
StretchBlt( hDC, 0, 0,
ddsd.dwWidth, ddsd.dwHeight,
hDCImage, dwBMPOriginX, dwBMPOriginY,
dwBMPWidth, dwBMPHeight, SRCCOPY );
if( FAILED( hr = m_pdds->ReleaseDC( hDC ) ) )
return hr;
DeleteDC( hDCImage );
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: CSurface::DrawText()
// Desc: Draws a text string on a DirectDraw surface using hFont or the default
// GDI font if hFont is NULL.
//-----------------------------------------------------------------------------
HRESULT CSurface::DrawText( HFONT hFont, TCHAR* strText,
DWORD dwOriginX, DWORD dwOriginY,
COLORREF crBackground, COLORREF crForeground )
{
HDC hDC = NULL;
HRESULT hr;
if( m_pdds == NULL || strText == NULL )
return E_INVALIDARG;
// Make sure this surface is restored.
if( FAILED( hr = m_pdds->Restore() ) )
return hr;
if( FAILED( hr = m_pdds->GetDC( &hDC ) ) )
return hr;
// Set the background and foreground color
SetBkColor( hDC, crBackground );
SetTextColor( hDC, crForeground );
if( hFont )
SelectObject( hDC, hFont );
// Use GDI to draw the text on the surface
TextOut( hDC, dwOriginX, dwOriginY, strText, _tcslen(strText) );
if( FAILED( hr = m_pdds->ReleaseDC( hDC ) ) )
return hr;
return S_OK;
}
HRESULT CSurface::DrawJPEG( char* strJPEG )
{
IJLERR jerr;
//Create the JPEG object
JPEG_CORE_PROPERTIES jcprops;
//Initialize the JPEG object
jerr = ijlInit(&jcprops);
if (jerr != IJL_OK)
{
return E_FAIL;
}
//Set the IJL data source as a filename
jcprops.JPGFile = strJPEG;
//Read JPEG parameters from the file
jerr = ijlRead(&jcprops, IJL_JFILE_READPARAMS);
//Make sure Parameter read was successful
if (jerr != IJL_OK)
{
return E_FAIL;
}
//Prepare a 24Bit buffer to receive image data
BYTE *buffer24;
//Determine the required size
long szbuff24 = (jcprops.JPGWidth * C24BIT + 7) / 8
* jcprops.JPGHeight;
//Resize the buffer
buffer24 = new BYTE [szbuff24];
if (buffer24 == NULL)
{
return E_FAIL;
}
//Set up the DIB specification for the JPEG decoder
jcprops.DIBWidth = jcprops.JPGWidth;
jcprops.DIBHeight = jcprops.JPGHeight; //Implies a bottom-up DIB.
jcprops.DIBChannels = 3;
jcprops.DIBColor = IJL_BGR;
jcprops.DIBPadBytes = IJL_DIB_PAD_BYTES(jcprops.JPGWidth,3);
jcprops.DIBBytes = reinterpret_cast<BYTE*>(buffer24);
//Set the JPG color space ... this will always be somewhat of an
//educated guess at best because JPEG is "color blind" (i.e.,
//nothing in the bit stream tells you what color space the data was
//encoded from. However, in this example we assume that we are
//reading JFIF files which means that 3 channel images are in the
//YCbCr color space and 1 channel images are in the Y color space.
switch(jcprops.JPGChannels)
{
case 1: jcprops.JPGColor = IJL_G;
break;
case 3: jcprops.JPGColor = IJL_YCBCR;
break;
default:
//This catches everything else, but no color twist will be
//performed by the IJL.
jcprops.DIBColor = (IJL_COLOR)IJL_OTHER;
jcprops.JPGColor = (IJL_COLOR)IJL_OTHER;
break;
}
//Read JPEG image data into our 24bit buffer
jerr = ijlRead(&jcprops, IJL_JFILE_READWHOLEIMAGE);
//Make sure the read was successful
if (jerr != IJL_OK)
{
return E_FAIL;
}
HBITMAP hbm;
WORD *buffer16;
long szbuff16;
//determine the size of our buffer
szbuff16 = ((jcprops.JPGWidth * C16BIT + 7) / 8)
* jcprops.JPGHeight;
//resize the buffer and make sure resize works
buffer16 = new WORD [szbuff16];
if (buffer16 == NULL)
{
return E_FAIL;
}
//Start at the beginning of the buffer
long j = 0;
//Step through the 24bit buffer
//Retrieve 3 channels at a time and convert their values to 16bit
for (long i = 0; i < szbuff24; i += 3)
{
//Check the pixel format and write the color data
//to the 16bit buffer. After the write, advance the
//16bit buffer by one.
if (!CDisplay::Is565())
buffer16[j++] = RGB555(buffer24[i], buffer24[i + 1],
buffer24[i + 2]);
else
buffer16[j++] = RGB565(buffer24[i], buffer24[i + 1],
buffer24[i + 2]);
}
//Create the bitmap using the new 16bit buffer
hbm = CreateBitmap (jcprops.JPGWidth, jcprops.JPGHeight, 1,
C16BIT, buffer16);
if(hbm == NULL)
{
return E_FAIL;
}
//remove the new buffer
delete [] buffer16;
//remove the old buffer
delete [] buffer24;
HRESULT hr;
DDSURFACEDESC2 ddsd;
ZeroMemory(&ddsd, sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);
ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN|DDSCAPS_SYSTEMMEMORY;
ddsd.dwWidth = jcprops.JPGWidth;
ddsd.dwHeight = jcprops.JPGHeight;
// Draw the bitmap on this surface
if( FAILED( hr = DrawBitmap( hbm, 0, 0, 0, 0 ) ) )
{
DeleteObject( hbm );
return hr;
}
DeleteObject( hbm );
// clean up and destroy the JPEG Decompressor
ijlFree(&jcprops);
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: CSurface::ReDrawBitmapOnSurface()
// Desc: Load a bitmap from a file or resource into a DirectDraw surface.
// normaly used to re-load a surface after a restore.
//-----------------------------------------------------------------------------
HRESULT CSurface::DrawBitmap( TCHAR* strBMP,
DWORD dwDesiredWidth, DWORD dwDesiredHeight )
{
HBITMAP hBMP;
HRESULT hr;
if( m_pdds == NULL || strBMP == NULL )
return E_INVALIDARG;
// Try to load the bitmap as a resource, if that fails, try it as a 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;
}
// Draw the bitmap on this surface
if( FAILED( hr = DrawBitmap( hBMP, 0, 0, 0, 0 ) ) )
{
DeleteObject( hBMP );
return hr;
}
DeleteObject( hBMP );
return S_OK;
}
//-----------------------------------------------------------------------------
// Name:
// Desc:
//-----------------------------------------------------------------------------
HRESULT CSurface::SetColorKey( DWORD dwColorKey )
{
if( NULL == m_pdds )
return E_POINTER;
m_bColorKeyed = TRUE;
DDCOLORKEY ddck;
ddck.dwColorSpaceLowValue = ConvertGDIColor( dwColorKey );
ddck.dwColorSpaceHighValue = ConvertGDIColor( dwColorKey );
return m_pdds->SetColorKey( DDCKEY_SRCBLT, &ddck );
}
//-----------------------------------------------------------------------------
// Name: CSurface::ConvertGDIColor()
// Desc: Converts a GDI color (0x00bbggrr) into the equivalent color on a
// DirectDrawSurface using its pixel format.
//-----------------------------------------------------------------------------
DWORD CSurface::ConvertGDIColor( COLORREF dwGDIColor )
{
if( m_pdds == NULL )
return 0x00000000;
COLORREF rgbT;
HDC hdc;
DWORD dw = CLR_INVALID;
DDSURFACEDESC2 ddsd;
HRESULT hr;
// Use GDI SetPixel to color match for us
if( dwGDIColor != CLR_INVALID && m_pdds->GetDC(&hdc) == DD_OK)
{
rgbT = GetPixel(hdc, 0, 0); // Save current pixel value
SetPixel(hdc, 0, 0, dwGDIColor); // Set our value
m_pdds->ReleaseDC(hdc);
}
// Now lock the surface so we can read back the converted color
ddsd.dwSize = sizeof(ddsd);
hr = m_pdds->Lock( NULL, &ddsd, DDLOCK_WAIT, NULL );
if( hr == DD_OK)
{
dw = *(DWORD *) ddsd.lpSurface;
if( ddsd.ddpfPixelFormat.dwRGBBitCount < 32 ) // Mask it to bpp
dw &= ( 1 << ddsd.ddpfPixelFormat.dwRGBBitCount ) - 1;
m_pdds->Unlock(NULL);
}
// Now put the color that was there back.
if( dwGDIColor != CLR_INVALID && m_pdds->GetDC(&hdc) == DD_OK )
{
SetPixel( hdc, 0, 0, rgbT );
m_pdds->ReleaseDC(hdc);
}
return dw;
}
//-----------------------------------------------------------------------------
// Name: CSurface::GetBitMaskInfo()
// Desc: Returns the number of bits and the shift in the bit mask
//-----------------------------------------------------------------------------
HRESULT CSurface::GetBitMaskInfo( DWORD dwBitMask, DWORD* pdwShift, DWORD* pdwBits )
{
DWORD dwShift = 0;
DWORD dwBits = 0;
if( pdwShift == NULL || pdwBits == NULL )
return E_INVALIDARG;
if( dwBitMask )
{
while( (dwBitMask & 1) == 0 )
{
dwShift++;
dwBitMask >>= 1;
}
}
while( (dwBitMask & 1) != 0 )
{
dwBits++;
dwBitMask >>= 1;
}
*pdwShift = dwShift;
*pdwBits = dwBits;
return S_OK;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -