📄 direct~2.cpp
字号:
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;
}
WORD DirectDrawWin::HighBitPos( DWORD dword )
{
DWORD test=1;
test<<=31;
for (WORD i=0;i<32;i++)
{
if ( dword & test )
return (WORD)(31-i);
test>>=1;
}
return 0;
}
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)
{
TRACE("compressed BMP format\n");
return 0;
}
TRACE("loading '%s': width=%d height=%d depth=%d\n", filename, imagew, imageh, imagebitdepth);
if (imagebitdepth==8)
{
// skip over palette info...
int ncolors = (bmpinfohdr.biClrUsed==0) ? 256 : bmpinfohdr.biClrUsed;
bmp.seekg( sizeof(RGBQUAD)*ncolors, ios::cur );
}
BYTE* buf=new BYTE[imagesize];
bmp.read( buf, imagesize );
if (!Copy_Bmp_Surface( surf, &bmpinfohdr, buf ))
{
TRACE("copy failed\n");
delete [] buf;
return 0;
}
delete [] buf;
return TRUE;
}
WORD DirectDrawWin::LowBitPos( DWORD dword )
{
DWORD test=1;
for (WORD i=0;i<32;i++)
{
if ( dword & test )
return i;
test<<=1;
}
return 0;
}
void DirectDrawWin::OnActivateApp(BOOL bActive, HTASK hTask)
{
CWnd::OnActivateApp(bActive, hTask);
window_active = bActive;
}
int DirectDrawWin::OnCreate(LPCREATESTRUCT)
{
DirectDrawEnumerate( DriverAvailable, this );
if (totaldrivers==0)
{
AfxMessageBox("No DirectDraw drivers detected");
return -1;
}
// insure the first entry is the primary display driver
if (driver[0].guid!=0 && totaldrivers>1)
{
for (int i=1;i<totaldrivers;i++)
if (driver[i].guid==0)
{
DriverInfo tmp;
tmp.guid=0;
tmp.desc=driver[i].desc;
tmp.name=driver[i].name;
driver[i].guid=driver[0].guid;
driver[i].desc=driver[0].desc;
driver[i].name=driver[0].name;
driver[0].guid=0;
driver[0].desc=tmp.desc;
driver[0].name=tmp.name;
}
}
int driverindex=SelectDriver();
if (driverindex<0)
{
TRACE("No DirectDraw driver selected\n");
return -1;
}
else if (driverindex>totaldrivers-1)
{
AfxMessageBox("Invalid DirectDraw driver selected\n");
return -1;
}
LPDIRECTDRAW ddraw1;
//DirectDrawCreate( driver[driverindex].guid, &ddraw1, 0 );
DirectDrawCreate( NULL, &ddraw1, 0 );
HRESULT r;
r=ddraw1->QueryInterface( IID_IDirectDraw2, (void**)&ddraw2 );
if (r!=S_OK)
{
AfxMessageBox("DirectDraw2 interface not supported");
return -1;
}
ddraw1->Release(), ddraw1=0;
ddraw2->SetCooperativeLevel( GetSafeHwnd(), DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN | DDSCL_ALLOWMODEX );
ddraw2->EnumDisplayModes( 0, 0, this, DisplayModeAvailable );
qsort( displaymode, totaldisplaymodes, sizeof(DisplayModeInfo), CompareModes );
CDC* dc=GetDC();
displaydepth=dc->GetDeviceCaps( BITSPIXEL );
displayrect.left=0;
displayrect.top=0;
displayrect.right=dc->GetDeviceCaps( HORZRES );
displayrect.bottom=dc->GetDeviceCaps( VERTRES );
dc->DeleteDC();
int initmode=SelectInitialDisplayMode();
if (ActivateDisplayMode( initmode )==FALSE)
return -1;
return 0;
}
void DirectDrawWin::OnDestroy()
{
if (primsurf)
primsurf->Release(), primsurf=0;
if (palette)
palette->Release(), palette=0;
if (ddraw2)
ddraw2->Release(), ddraw2=0;
for (int i=0;i<totaldrivers;i++)
{
if (driver[i].guid)
delete [] driver[i].guid;
free( driver[i].desc );
free( driver[i].name );
}
}
BOOL DirectDrawWin::OnEraseBkgnd(CDC* pDC)
{
CBrush br( RGB(0,0,0) );
CRect rc;
CWnd::GetClientRect( &rc );
pDC->FillRect( &rc, &br );
return TRUE;
}
void DirectDrawWin::OnMouseMove( UINT state, CPoint point )
{
mousestate = state;
mousex = point.x;
mousey = point.y;
}
BOOL DirectDrawWin::PreDrawScene()
{
if (window_active && primsurf->IsLost())
{
HRESULT r;
r=primsurf->Restore();
if (r!=DD_OK)
TRACE("can't restore primsurf\n");
if (backsurf)
{
r=backsurf->Restore();
if (r!=DD_OK)
TRACE("can't restore backsurf\n");
}
RestoreSurfaces();
}
return window_active;
}
void DirectDrawWin::PrintSurfaceInfo(LPDIRECTDRAWSURFACE surf, LPCTSTR name)
{
ASSERT(surf);
ASSERT(name);
DDSURFACEDESC desc;
ZeroMemory( &desc, sizeof(desc) );
desc.dwSize=sizeof(desc);
surf->GetSurfaceDesc( &desc );
TRACE("Description for surface '%s':\n", name );
if (desc.ddsCaps.dwCaps & DDSCAPS_COMPLEX)
TRACE(" Complex\n");
if (desc.ddsCaps.dwCaps & DDSCAPS_FLIP)
TRACE(" Flipable\n");
if (desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)
TRACE(" Primary surface\n");
if (desc.ddsCaps.dwCaps & DDSCAPS_FRONTBUFFER)
TRACE(" Front buffer\n");
if (desc.ddsCaps.dwCaps & DDSCAPS_BACKBUFFER)
TRACE(" Back buffer\n");
if (desc.ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY)
TRACE(" Video memory\n");
if (desc.ddsCaps.dwCaps & DDSCAPS_LOCALVIDMEM)
TRACE(" Local Video memory\n");
if (desc.ddsCaps.dwCaps & DDSCAPS_SYSTEMMEMORY)
TRACE(" System memory\n");
if (desc.ddsCaps.dwCaps & DDSCAPS_OFFSCREENPLAIN)
TRACE(" Offscreen/plain\n");
if (desc.ddsCaps.dwCaps & DDSCAPS_MODEX)
TRACE(" Mode X\n");
}
DWORD DirectDrawWin::RGBtoPixel(DWORD r, DWORD g, DWORD b)
{
if (displaydepth==8 && palette)
{
static PALETTEENTRY pal[256];
palette->GetEntries( 0, 0, 256, pal);
DWORD bestmatch=0;
DWORD bestscore=30000;
for (int i=0;i<256;i++)
{
DWORD pr=pal[i].peRed;
DWORD pg=pal[i].peGreen;
DWORD pb=pal[i].peBlue;
DWORD rdif = abs((int)(pr - r));
DWORD gdif = abs((int)(pg - g));
DWORD bdif = abs((int)(pb - b));
DWORD score=rdif+gdif+bdif;
if (score==0)
return i;
if (score<bestscore)
{
bestscore=score;
bestmatch=i;
}
}
return bestmatch;
}
else if (displaydepth==16)
{
int REDdiv=256/(int)pow( 2, numREDbits );
int GREENdiv=256/(int)pow( 2, numGREENbits );
int BLUEdiv=256/(int)pow( 2, numBLUEbits );
float rf=(float)r/(float)REDdiv;
float gf=(float)g/(float)GREENdiv;
float bf=(float)b/(float)BLUEdiv;
DWORD rt=((DWORD)rf<<loREDbit);
DWORD gt=((DWORD)gf<<loGREENbit);
DWORD bt=((DWORD)bf<<loBLUEbit);
return rt|gt|bt;
}
else if (displaydepth==24 || displaydepth==32)
return (r<<loREDbit) | (g<<loGREENbit) | (b<<loBLUEbit);
return 0;
}
BOOL DirectDrawWin::SaveSurface(LPDIRECTDRAWSURFACE surf, LPCTSTR filename)
{
DDSURFACEDESC desc;
ZeroMemory( &desc, sizeof(desc) );
desc.dwSize = sizeof(desc);
desc.dwFlags = DDSD_WIDTH | DDSD_HEIGHT;
surf->GetSurfaceDesc( &desc );
DWORD width = desc.dwWidth;
DWORD height = desc.dwHeight;
DWORD depth = desc.ddpfPixelFormat.dwRGBBitCount;
BITMAPFILEHEADER filehdr;
BITMAPINFOHEADER infohdr;
RGBQUAD quads[256];
PALETTEENTRY pe[256];
ZeroMemory( &filehdr, sizeof(filehdr) );
*((char*)&filehdr.bfType)='B';
*(((char*)&filehdr.bfType)+1)='M';
filehdr.bfOffBits=sizeof(filehdr)+sizeof(infohdr);
if (depth==8)
filehdr.bfOffBits+=sizeof(quads);
ZeroMemory( &infohdr, sizeof(infohdr) );
infohdr.biSize=sizeof(infohdr);
infohdr.biWidth = width;
infohdr.biHeight = height;
infohdr.biPlanes = 1;
infohdr.biBitCount = depth==8 ? 8 : 24;
infohdr.biCompression=BI_RGB;
infohdr.biSizeImage = 0;
if (depth==8)
infohdr.biClrUsed = 256;
else
infohdr.biClrUsed = 0;
LPDIRECTDRAWPALETTE palette;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -