📄 directdrawwin.cpp
字号:
#include "Headers.h"
#include "DirectDrawApp.h"
#include "DirectDrawWin.h"
#include "ksrc\sound.h"
extern BOOL InitDirectInput();
extern BOOL ReleaseDirectInput();
#ifdef _DEBUG
#undef THIS_FILE
static char BASED_CODE THIS_FILE[] = __FILE__;
#endif
BEGIN_MESSAGE_MAP(DirectDrawWin, CWnd)
//{{AFX_MSG_MAP(DirectDrawWin)
ON_WM_CREATE()
ON_WM_DESTROY()
ON_WM_ACTIVATEAPP()
ON_WM_ERASEBKGND()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
DirectDrawWin* DirectDrawWin::thisptr;
BOOL DirectDrawWin::ActivateDisplayMode( int mode, DWORD rate )
{
if ( mode<0 || mode>=totaldisplaymodes )
return FALSE;
DWORD width = displaymode[mode].width;
DWORD height = displaymode[mode].height;
DWORD depth = displaymode[mode].depth;
displayrect.left=0;
displayrect.top=0;
displayrect.right=width;
displayrect.bottom=height;
displaydepth=depth;
ddraw2->SetDisplayMode( width, height, depth, rate, 0 );
curdisplaymode = mode;
TRACE("------------------- %dx%dx%d (%dhz) ---------------\n", width, height, depth, rate);
if (CreateFlippingSurfaces()==FALSE)
{
TRACE("CreateFlippingSurfaces() failed");
return FALSE;
}
if (CreateCustomSurfaces()==FALSE)
{
TRACE("CreateCustomSurfaces() failed");
return FALSE;
}
return TRUE;
}
BOOL DirectDrawWin::ActivateDisplayMode( int mode )
{
if ( mode<0 || mode>=totaldisplaymodes )
return FALSE;
DWORD width = displaymode[mode].width;
DWORD height = displaymode[mode].height;
DWORD depth = displaymode[mode].depth;
displayrect.left=0;
displayrect.top=0;
displayrect.right=width;
displayrect.bottom=height;
displaydepth=depth;
ddraw2->SetDisplayMode( width, height, depth, 0, 0 );
curdisplaymode = mode;
TRACE("------------------- %dx%dx%d ----------------------\n", width, height, depth);
if (CreateFlippingSurfaces()==FALSE)
{
TRACE("CreateFlippingSurfaces() failed");
return FALSE;
}
if (CreateCustomSurfaces()==FALSE)
{
TRACE("CreateCustomSurfaces() failed");
return FALSE;
}
return TRUE;
}
BOOL DirectDrawWin::BltSurface( LPDIRECTDRAWSURFACE destsurf, LPDIRECTDRAWSURFACE srcsurf, int x, int y, BOOL srccolorkey )
{
if (destsurf==0 || srcsurf==0)
return FALSE;
BOOL use_fastblt=TRUE;
DDSURFACEDESC destsurfdesc;
ZeroMemory( &destsurfdesc, sizeof(destsurfdesc) );
destsurfdesc.dwSize = sizeof(destsurfdesc);
destsurf->GetSurfaceDesc( &destsurfdesc );
CRect destrect;
destrect.left=0;
destrect.top=0;
destrect.right=destsurfdesc.dwWidth;
destrect.bottom=destsurfdesc.dwHeight;
DDSURFACEDESC srcsurfdesc;
ZeroMemory( &srcsurfdesc, sizeof(srcsurfdesc) );
srcsurfdesc.dwSize = sizeof(srcsurfdesc);
srcsurf->GetSurfaceDesc( &srcsurfdesc );
CRect srcrect;
srcrect.left=0;
srcrect.top=0;
srcrect.right=srcsurfdesc.dwWidth;
srcrect.bottom=srcsurfdesc.dwHeight;
// make sure that there is something to do...
if (x+srcrect.left>=destrect.right)
return FALSE;
if (y+srcrect.top>=destrect.bottom)
return FALSE;
if (x+srcrect.right<=destrect.left)
return FALSE;
if (y+srcrect.bottom<=destrect.top)
return FALSE;
// clip the source rect if nessesary
if (x+srcrect.right>destrect.right)
srcrect.right-=x+srcrect.right-destrect.right;
if (y+srcrect.bottom>destrect.bottom)
srcrect.bottom-=y+srcrect.bottom-destrect.bottom;
CRect dr;
if (x<0)
{
srcrect.left=-x;
x=0;
dr.left=x;
dr.top=y;
dr.right=x+srcrect.Width();
dr.bottom=y+srcrect.Height();
use_fastblt=FALSE;
}
if (y<0)
{
srcrect.top=-y;
y=0;
dr.left=x;
dr.top=y;
dr.right=x+srcrect.Width();
dr.bottom=y+srcrect.Height();
use_fastblt=FALSE;
}
DWORD flags;
if (use_fastblt)
{
flags=DDBLTFAST_WAIT;
if (srccolorkey)
flags |= DDBLTFAST_SRCCOLORKEY;
destsurf->BltFast( x, y, srcsurf, &srcrect, flags );
}
else
{
flags=DDBLT_WAIT;
if (srccolorkey)
flags |= DDBLT_KEYSRC;
destsurf->Blt( &dr, srcsurf, &srcrect, flags, 0 );
}
return TRUE;
}
BOOL DirectDrawWin::ClearSurface( LPDIRECTDRAWSURFACE surf, DWORD clr, RECT* rect )
{
if (surf==0)
return FALSE;
DDBLTFX bltfx;
ZeroMemory( &bltfx, sizeof(bltfx) );
bltfx.dwSize = sizeof(bltfx);
bltfx.dwFillColor = clr;
HRESULT r;
r=surf->Blt( rect, 0, 0, DDBLT_COLORFILL | DDBLT_WAIT, &bltfx );
if (r==DD_OK)
return TRUE;
if (r==DDERR_NOBLTHW && clr==0 && rect==0)
{
DDSURFACEDESC desc;
ZeroMemory( &desc, sizeof(desc) );
desc.dwSize = sizeof(desc);
desc.dwFlags=DDSD_WIDTH | DDSD_HEIGHT;
if (surf->GetSurfaceDesc( &desc )!=DD_OK)
return FALSE;
int w=desc.dwWidth;
int h=desc.dwHeight;
r=surf->Lock( 0, &desc, DDLOCK_WAIT | DDLOCK_WRITEONLY, 0 );
if (r!=DD_OK)
return FALSE;
BYTE* surfbits = (BYTE*)desc.lpSurface;
for (int i=0;i<h;i++)
{
ZeroMemory( surfbits, desc.lPitch );
surfbits += desc.lPitch;
}
surf->Unlock( 0 );
}
return FALSE;
}
int DirectDrawWin::CompareModes( const void *arg1, const void *arg2 )
{
DisplayModeInfo* mode1=(DisplayModeInfo*)arg1;
DisplayModeInfo* mode2=(DisplayModeInfo*)arg2;
DWORD volume1=mode1->width*mode1->height;
DWORD volume2=mode2->width*mode2->height;
if (volume1<volume2)
return -1;
else if (volume1>volume2)
return 1;
if (mode1->depth<mode2->depth)
return -1;
else if (mode1->depth>mode2->depth)
return 1;
return 0;
}
BOOL DirectDrawWin::Copy_Bmp08_Surface08( LPDIRECTDRAWSURFACE surf,
BYTE* bmpbuf, int w, int h )
{
if (surf==0 || bmpbuf==0)
return FALSE;
DDSURFACEDESC desc;
ZeroMemory( &desc, sizeof(desc) );
desc.dwSize = sizeof(desc);
HRESULT r=surf->Lock( 0, &desc, DDLOCK_WAIT | DDLOCK_WRITEONLY, 0 );
if (r!=DD_OK)
{
TRACE("ShowBmp: Lock() failed\n");
return FALSE;
}
int bytesgiven=(w+3) & ~3;
BYTE* surfbits = (BYTE*)desc.lpSurface;
BYTE* imagebits = (BYTE*)(&bmpbuf[(h-1)*bytesgiven]);
for( int i=0; i<h; i++ )
{
memcpy( surfbits, imagebits, w );
surfbits += desc.lPitch;
imagebits -= bytesgiven;
}
surf->Unlock( 0 );
return TRUE;
}
BOOL DirectDrawWin::Copy_Bmp_Surface( LPDIRECTDRAWSURFACE surf,
BITMAPINFOHEADER* bmphdr, BYTE* buf)
{
if (surf==0 || bmphdr==0 || buf==0)
return FALSE;
int imagew=bmphdr->biWidth;
int imageh=bmphdr->biHeight;
int imagebitdepth=bmphdr->biBitCount;
BOOL ret=FALSE;
if (imagebitdepth==8)
{
if (displaydepth==8)
ret=Copy_Bmp08_Surface08( surf, buf, imagew, imageh );
}
else
ret=FALSE;//not implent
return ret;
}
BOOL DirectDrawWin::Create(const CString& title,int icon)
{
CString sClassName;
sClassName = AfxRegisterWndClass(CS_HREDRAW | CS_VREDRAW,LoadCursor(0, IDC_ARROW),
(HBRUSH)(COLOR_WINDOW + 1), LoadIcon(AfxGetInstanceHandle(), MAKEINTRESOURCE(icon)));
return CWnd::CreateEx( WS_EX_TOPMOST, sClassName, title, WS_POPUP, 0,0,100,100, 0, 0 );
}
BOOL DirectDrawWin::CreateFlippingSurfaces()
{
if (primsurf)
primsurf->Release(), primsurf=0;
DDSURFACEDESC desc;
ZeroMemory( &desc, sizeof(desc) );
desc.dwSize = sizeof( desc );
desc.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;
desc.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_FLIP | DDSCAPS_COMPLEX;
desc.dwBackBufferCount = 1;
HRESULT r=ddraw2->CreateSurface( &desc, &primsurf, 0 );
if (r!=DD_OK)
return FALSE;
DDSCAPS surfcaps;
surfcaps.dwCaps = DDSCAPS_BACKBUFFER;
r=primsurf->GetAttachedSurface( &surfcaps, &backsurf );
if (r!=DD_OK)
return FALSE;
ClearSurface( primsurf, 0 );
ClearSurface( backsurf, 0 );
return TRUE;
}
BOOL DirectDrawWin::CreatePalette(RGBQUAD* quad, int ncolors)
{
if (palette)
palette->Release(), palette=0;
PALETTEENTRY pe[256];
ZeroMemory( pe, sizeof(pe) );
for( int i=0; i<ncolors; i++)
{
pe[i].peRed = quad[i].rgbRed;
pe[i].peGreen = quad[i].rgbGreen;
pe[i].peBlue = quad[i].rgbBlue;
}
HRESULT r=ddraw2->CreatePalette( DDPCAPS_8BIT | DDPCAPS_ALLOW256,
pe, &palette, 0 );
if (r!=DD_OK)
{
TRACE("failed to create DirectDraw palette\n");
return FALSE;
}
primsurf->SetPalette( palette );
return TRUE;
}
/*
LPDIRECTDRAWSURFACE DirectDrawWin::CreateSurface(LPCTSTR filename, BOOL installpalette)
{
int imagew, imageh;
GetBmpDimensions( filename, imagew, imageh );
LPDIRECTDRAWSURFACE surf=CreateSurface( imagew, imageh );
if (surf==0)
{
TRACE("CreateSurface(filename) failed to create surface\n");
return 0;
}
ifstream bmp( filename, ios::binary | ios::nocreate );
if (!bmp.is_open())
{
TRACE("LoadSurface: cannot open Bmp file\n");
return 0;
}
BITMAPFILEHEADER bmpfilehdr;
bmp.read( (char*)&bmpfilehdr, sizeof(bmpfilehdr) );
char* ptr=(char*)&bmpfilehdr.bfType;
if (*ptr!='B' || *++ptr!='M')
{
TRACE("invalid bitmap\n");
return 0;
}
BITMAPINFOHEADER bmpinfohdr;
bmp.read( (char*)&bmpinfohdr, sizeof(bmpinfohdr) );
bmp.seekg( sizeof(bmpfilehdr)+bmpinfohdr.biSize, ios::beg );
int imagebitdepth=bmpinfohdr.biBitCount;
int imagesize=bmpinfohdr.biSizeImage;
if (imagesize==0)
imagesize=((imagew*(imagebitdepth/8)+3) & ~3)*imageh;
if (bmpinfohdr.biCompression!=BI_RGB)
{
TRACE("compressed BMP format\n");
return 0;
}
TRACE("loading '%s': width=%d height=%d depth=%d\n", filename, imagew, imageh, imagebitdepth);
if (imagebitdepth==8)
{
int ncolors;
if (bmpinfohdr.biClrUsed==0)
ncolors=256;
else
ncolors=bmpinfohdr.biClrUsed;
RGBQUAD* quad=new RGBQUAD[ncolors];
bmp.read( (char*)quad, sizeof(RGBQUAD)*ncolors );
if (installpalette)
CreatePalette( quad, ncolors );
delete [] quad;
}
BYTE* buf=new BYTE[imagesize];
bmp.read( buf, imagesize );
if (!Copy_Bmp_Surface( surf, &bmpinfohdr, buf ))
{
TRACE("copy failed\n");
delete [] buf;
surf->Release();
return 0;
}
delete [] buf;
return surf;
}
*/
LPDIRECTDRAWSURFACE DirectDrawWin::CreateSurface( DWORD w, DWORD h )
{
DWORD bytes=w*h*(displaydepth/8);
DDSURFACEDESC desc;
ZeroMemory( &desc, sizeof(desc) );
desc.dwSize = sizeof(desc);
desc.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS;
desc.dwWidth = w;
desc.dwHeight = h;
desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY;
LPDIRECTDRAWSURFACE surf;
HRESULT r=ddraw2->CreateSurface( &desc, &surf, 0 );
if (r==DD_OK)
{
TRACE("CreateSurface(%d,%d) created in video memory (%d bytes)\n", w, h, bytes);
return surf;
}
desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY;
r=ddraw2->CreateSurface( &desc, &surf, 0 );
if (r==DD_OK)
{
TRACE("CreateSurface(%d,%d) allocated in system memory (%d bytes)\n", w, h, bytes);
return surf;
}
TRACE("CreateSurface(%d,%d) failed\n", w, h);
return 0;
}
DirectDrawWin::DirectDrawWin()
{
thisptr=this;
totaldrivers=0;
totaldisplaymodes=0;
curdisplaymode=-1;
ddraw2=0;
primsurf=0;
backsurf=0;
palette=0;
window_active=TRUE;
DirectDrawApp* pApp = (DirectDrawApp*)AfxGetApp();
pApp->ddwin = this;
}
HRESULT WINAPI DirectDrawWin::DisplayModeAvailable( LPDDSURFACEDESC desc, LPVOID p )
{
DirectDrawWin* win=(DirectDrawWin*)p;
int& count=win->totaldisplaymodes;
if (count==MAXDISPLAYMODES)
return DDENUMRET_CANCEL;
win->displaymode[count].width = desc->dwWidth;
win->displaymode[count].height = desc->dwHeight;
win->displaymode[count].depth = desc->ddpfPixelFormat.dwRGBBitCount;
count++;
return DDENUMRET_OK;
}
BOOL WINAPI DirectDrawWin::DriverAvailable(LPGUID guid, LPSTR desc, LPSTR name, LPVOID p )
{
DirectDrawWin* win=(DirectDrawWin*)p;
if (win->totaldrivers >= MAXDRIVERS)
return DDENUMRET_CANCEL;
DriverInfo& info=win->driver[win->totaldrivers];
if (guid)
{
info.guid=(GUID*)new BYTE[sizeof(GUID)];
memcpy( info.guid, guid, sizeof(GUID) );
}
else
info.guid=0;
info.desc=strdup( desc );
info.name=strdup( name );
win->totaldrivers++;
return DDENUMRET_OK;
}
/*
BOOL DirectDrawWin::GetBmpDimensions( LPCTSTR filename, int& w, int& h)
{
ifstream bmp( filename, ios::binary | ios::nocreate );
if (!bmp.is_open())
{
TRACE("GetBmpDimensions: cannot open file\n");
return FALSE;
}
BITMAPFILEHEADER bmpfilehdr;
bmp.read( (char*)&bmpfilehdr, sizeof(bmpfilehdr) );
char* ptr=(char*)&bmpfilehdr.bfType;
if (*ptr!='B' || *++ptr!='M')
{
TRACE("GetBmpDimensions: invalid bitmap\n");
return FALSE;
}
BITMAPINFOHEADER bmpinfohdr;
bmp.read( (char*)&bmpinfohdr, sizeof(bmpinfohdr) );
w=bmpinfohdr.biWidth;
h=bmpinfohdr.biHeight;
return TRUE;
}
*/
BOOL DirectDrawWin::GetDisplayModeDimensions( int mode, DWORD& width, DWORD& height, DWORD& depth )
{
if ( mode < 0 || mode > totaldisplaymodes )
return FALSE;
width = displaymode[mode].width;
height = displaymode[mode].height;
depth = displaymode[mode].depth;
return TRUE;
}
int DirectDrawWin::GetDisplayModeIndex( DWORD w, DWORD h, DWORD d )
{
for (int i=0;i<totaldisplaymodes;i++)
{
DisplayModeInfo& m=displaymode[i];
if (m.width==w && m.height==h && m.depth==d)
return i;
}
return -1;
}
BOOL DirectDrawWin::GetDriverInfo( int index, LPGUID* guid, LPSTR* desc, LPSTR* name )
{
if (index<0 || index>totaldrivers)
return FALSE;
if (name)
*name=driver[index].name;
if (desc)
*desc=driver[index].desc;
if (guid)
*guid=driver[index].guid;
return TRUE;
}
BOOL DirectDrawWin::GetSurfaceDimensions( LPDIRECTDRAWSURFACE surf, DWORD& w, DWORD& h )
{
if (surf==0)
return FALSE;
DDSURFACEDESC desc;
ZeroMemory( &desc, sizeof(desc) );
desc.dwSize=sizeof(desc);
desc.dwFlags=DDSD_WIDTH | DDSD_HEIGHT;
if (surf->GetSurfaceDesc( &desc )!=DD_OK)
return FALSE;
w=desc.dwWidth;
h=desc.dwHeight;
return TRUE;
}
BOOL DirectDrawWin::GetSurfaceRect( LPDIRECTDRAWSURFACE surf, RECT& rect)
{
if (surf==0)
return FALSE;
DDSURFACEDESC desc;
desc.dwSize=sizeof(desc);
desc.dwFlags=DDSD_WIDTH | DDSD_HEIGHT;
if (surf->GetSurfaceDesc( &desc )!=DD_OK)
return FALSE;
rect.left=0;
rect.top=0;
rect.right=desc.dwWidth;
rect.bottom=desc.dwHeight;
return TRUE;
}
/*
BOOL DirectDrawWin::LoadSurface( LPDIRECTDRAWSURFACE surf, LPCTSTR filename)
{
ifstream bmp( filename, ios::binary | ios::nocreate );
if (!bmp.is_open())
{
TRACE("LoadSurface: cannot open Bmp file\n");
return FALSE;
}
BITMAPFILEHEADER bmpfilehdr;
bmp.read( (char*)&bmpfilehdr, sizeof(bmpfilehdr) );
char* ptr=(char*)&bmpfilehdr.bfType;
if (*ptr!='B' || *++ptr!='M')
{
TRACE("LoadSurface: invalid bitmap\n");
return FALSE;
}
BITMAPINFOHEADER bmpinfohdr;
bmp.read( (char*)&bmpinfohdr, sizeof(bmpinfohdr) );
bmp.seekg( sizeof(bmpfilehdr)+bmpinfohdr.biSize, ios::beg );
int imagew=bmpinfohdr.biWidth;
int imageh=bmpinfohdr.biHeight;
int imagebitdepth=bmpinfohdr.biBitCount;
int imagesize=bmpinfohdr.biSizeImage;
if (imagesize==0)
imagesize=((imagew*(imagebitdepth/8)+3) & ~3)*imageh;
if (bmpinfohdr.biCompression!=BI_RGB)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -