📄 cdxapp.cpp
字号:
return( TRUE );
}
#ifdef _DEBUG
static void StatsHelper( char *szBuff,int nLen,LPDIRECTDRAWSURFACE lpSurf, SIZE *pSize )
{
/* Helper function */
HDC hDC;
HFONT hOldFont;
HRESULT err;
RECT r;
if ( (err=lpSurf->GetDC(&hDC))!=DD_OK )
{
pApp->ErrHandler( "StatsHelper() Failure to GetDC for surface ",szBuff,err );
return;
}
/* Render info to surface using GDI */
hOldFont = (HFONT)::SelectObject( hDC,gStats.hFont );
::SetTextColor( hDC,RGB(255,255,255) );
::SetBkColor( hDC,RGB(0,0,0) );
::SetBkMode( hDC,OPAQUE );
::GetTextExtentPoint32( hDC,szBuff,nLen,pSize );
::SetRect( &r,0,0,pSize->cx,pSize->cy );
::ExtTextOut( hDC,0,0,ETO_OPAQUE,&r,szBuff,nLen,NULL );
::SelectObject( hDC,hOldFont );
/* Release GDI interface */
lpSurf->ReleaseDC( hDC );
}
BOOL CDXApp::ShowStatistics()
{
/* Update surface with some stats */
float fps=GetFPS();
DWORD dwPolys=GetTPS();
char szBuff[128];
int nLen;
LPDIRECTDRAWSURFACE lpSurf=GetStatsSurface();
if ( !lpSurf ) return( TRUE );
nLen = wsprintf( szBuff,"%d.%02d fps, %lu tps",(((int)fps)*100)/100,(((int)fps)*100)%100,dwPolys );
StatsHelper( szBuff,nLen,lpSurf,&gStats.sizeStats );
return( TRUE );
}
BOOL CDXApp::ShowModeInfo()
{
/* Update the info surface with some stats */
HRESULT err;
char szBuff[128];
int nLen;
LPDIRECTDRAWSURFACE lpSurf=GetInfoSurface();
if ( !lpSurf ) return( TRUE );
nLen = wsprintf( szBuff,"%dx%dx%d (%s)",m_sizeScreen.cx,m_sizeScreen.cy,GetBitDepth(),(IsRGB()?"RGB":"MONO" ) );
StatsHelper( szBuff,nLen,lpSurf,&gStats.sizeInfo );
return( TRUE );
}
BOOL CDXApp::InitialiseStatistics()
{
/* Create our surfaces for stats info, etc */
DDCOLORKEY ddck;
DDSURFACEDESC ddsd;
HRESULT err;
BOOL bError=FALSE;
/* Cater for bogus recalling */
RELEASE( m_pStatsSurface );
RELEASE( m_pInfoSurface );
if ( gStats.hFont!=NULL )
{
::DeleteObject( gStats.hFont );
gStats.hFont=NULL;
}
gStats.bValid = FALSE;
/* Create the GDI font */
gStats.hFont = ::CreateFont(12,0,0,0,FW_NORMAL,0,0,0,ANSI_CHARSET,0,0,0,VARIABLE_PITCH,"Arial");
/* Create the surfaces */
ZeroMemory( &ddsd,sizeof(ddsd) );
ddsd.dwSize = sizeof(ddsd);
ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
ddsd.dwHeight = 50; /* 50 should be plenty */
ddsd.dwWidth = 300; /* 300 should be plenty too */
if ( (err=m_pDD->CreateSurface(&ddsd,&m_pStatsSurface,NULL))!=DD_OK )
{
ErrHandler( "CDXApp::InitialiseStats()","Error creating stats surface",err );
bError=TRUE;
}
else
{
ZeroMemory( &ddck,sizeof(ddck) );
m_pStatsSurface->SetColorKey( DDCKEY_SRCBLT,&ddck );
if ( (err=m_pDD->CreateSurface(&ddsd,&m_pInfoSurface,NULL))!=DD_OK )
{
ErrHandler( "CDXApp::InitialiseStats()","Error creating info surface",err );
bError=TRUE;
}
else
{
ZeroMemory( &ddck,sizeof(ddck) );
m_pInfoSurface->SetColorKey( DDCKEY_SRCBLT,&ddck );
}
}
if ( bError )
{
RELEASE( m_pStatsSurface );
RELEASE( m_pInfoSurface );
if ( gStats.hFont!=NULL )
{
::DeleteObject( gStats.hFont );
gStats.hFont=NULL;
}
return( FALSE );
}
return( TRUE );
}
float CDXApp::GetFPS()
{
/* Calculate the frame rate */
return( gStats.floatFPS );
}
DWORD CDXApp::GetTPS()
{
/* Determine the triangles being drawn per second (ave) */
return( gStats.dwTPS );
}
void CDXApp::CalculateFrameRate()
{
/* Calculate frames per second, etc, at some interval */
gStats.dwFrameCount++;
if ( ++gStats.dwIntervalCount >= FRAME_INTERVAL )
{
double t;
int p, f;
time_t time=clock();
gStats.dwIntervalCount = 0;
t = (time-gStats.timeLast)/(double)CLOCKS_PER_SEC;
gStats.timeLast = time;
p = Get3DDevice()->GetTrianglesDrawn() - gStats.dwLastTriangles;
gStats.dwLastTriangles = Get3DDevice()->GetTrianglesDrawn();
f = gStats.dwFrameCount;
gStats.dwFrameCount = 0;
gStats.floatFPS = (float) (f/t);
gStats.dwTPS = (DWORD) (p/t);
ShowStatistics();
ShowModeInfo();
gStats.bValid = TRUE;
}
}
void CDXApp::DisplayStats()
{
/* Update the info surfaces and blt them to render target */
LPDIRECT3DDEVICE2 lpD3D2=NULL;
LPDIRECTDRAWSURFACE lpTarget=NULL;
HRESULT err;
RECT rc;
/* Show the frame rate centered across the top of the window */
CalculateFrameRate();
/* Don't bother if not initialised yet */
if ( !gStats.bValid ) return;
if ( (err=Get3DDevice()->GetDirect3DDevice2(&lpD3D2))!=D3DRM_OK )
{
ErrHandler( "CDXApp::DisplayStats()","GetDirect3DDevice2 Failed",err );
return;
}
if ( (err=lpD3D2->GetRenderTarget(&lpTarget))!=DD_OK )
{
ErrHandler( "CDXApp::DisplayStats()","GetRenderTarget Failed",err );
RELEASE( lpD3D2 );
return;
}
if ( gStats.sizeStats.cx < m_sizeScreen.cx && gStats.sizeStats.cy < m_sizeScreen.cy )
{
int xdif=(m_sizeScreen.cx-gStats.sizeStats.cx)/2;
::SetRect( &rc,0,0,gStats.sizeStats.cx,gStats.sizeStats.cy );
if ( GetStatsSurface()!=NULL )
{
if ( (err=lpTarget->BltFast(xdif,0,GetStatsSurface(),&rc,DDBLTFAST_SRCCOLORKEY|DDBLTFAST_WAIT))!=DD_OK )
{
/* Not an important error */
if ( lpTarget->IsLost() ) lpTarget->Restore();
if ( GetStatsSurface()->IsLost() ) GetStatsSurface()->Restore();
}
else
{
/* Add rectangle as dirty */
GetViewport()->ForceUpdate( xdif,0,gStats.sizeStats.cx+xdif,gStats.sizeStats.cy );
}
}
}
/* Show the info centered across the bottom of the window */
if ( gStats.sizeInfo.cx < m_sizeScreen.cx && gStats.sizeInfo.cy < m_sizeScreen.cy )
{
int xdif=(m_sizeScreen.cx-gStats.sizeInfo.cx)/2;
int ydif=m_sizeScreen.cy-gStats.sizeInfo.cy;
::SetRect( &rc,0,0,gStats.sizeInfo.cx,gStats.sizeInfo.cy );
if ( GetInfoSurface()!=NULL )
{
if ( (err=lpTarget->BltFast(xdif,ydif,GetInfoSurface(),&rc,DDBLTFAST_SRCCOLORKEY|DDBLTFAST_WAIT))!=DD_OK )
{
/* Not an important error */
if ( lpTarget->IsLost() ) lpTarget->Restore();
if ( GetInfoSurface()->IsLost() ) GetInfoSurface()->Restore();
}
else
{
/* Add dirty rectange */
GetViewport()->ForceUpdate( xdif,ydif,gStats.sizeInfo.cx+xdif,ydif+gStats.sizeInfo.cy );
}
}
}
RELEASE( lpTarget );
RELEASE( lpD3D2 );
}
#endif // _DEBUG
BOOL CDXApp::IsRGB()
{
return( !bMono );
}
BOOL CDXApp::ActivateMenu()
{
/* Invoke the menu (only) if full screen mode */
if ( GetHMenu()==NULL ) return( FALSE );
if ( !IsFullScreen() ) return( TRUE );
::SetMenu( GetHWnd(),GetHMenu() ); /* This will also force redraw */
PauseApp( TRUE );
return( TRUE );
}
void CDXApp::PauseApp( BOOL bPause )
{
/* Pause or un-pause the application */
HRESULT err;
HDC hDC;
if ( bPause!=m_bIsPaused )
{
m_bIsPaused = bPause;
if ( m_bIsPaused )
{
/* Need to display a paused message on screen */
if ( IsFullScreen() )
{
if ( (err=m_pDD2->FlipToGDISurface())!=DD_OK )
{
ErrHandler( "CDXApp::PauseApp()","FlipToGDISurface Failed",err );
return;
}
}
/* Use simple GDI */
if ( IsFullScreen() ) err=m_pPrimarySurface->GetDC(&hDC); else
{
hDC = ::GetDC( GetHWnd() );
err = DD_OK;
}
if ( err==DD_OK )
{
RECT rc;
LPCSTR lpszMsg="Paused";
::SetRect( &rc,0,0,m_sizeScreen.cx,m_sizeScreen.cy );
::SetBkMode( hDC,TRANSPARENT );
::SetTextColor( hDC,RGB(255,255,255) );
::DrawText( hDC,lpszMsg,lstrlen(lpszMsg),&rc,DT_CENTER|DT_VCENTER|DT_SINGLELINE );
if ( !IsFullScreen() )
{
::ReleaseDC( GetHWnd(),hDC );
}
else
{
if ( (err=m_pPrimarySurface->ReleaseDC(hDC))!=DD_OK )
{
ErrHandler( "CDXApp::PauseApp()","ReleaseDC Failed",err );
}
}
}
else
{
ErrHandler( "CDXApp::PauseApp()","GetDC Failed",err );
}
}
else
{
/* Force update of entire viewport */
m_bForceFullUpdate = TRUE;
/* Remove any menu for full screen mode */
if ( IsFullScreen() && GetHMenu()!=NULL ) ::SetMenu( GetHWnd(),NULL );
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -