📄 d3dsettings.cpp
字号:
// --------------------------------------------------------------------------
// Dingus project - a collection of subsystems for game/graphics applications
// --------------------------------------------------------------------------
#include "stdafx.h"
#include <windowsx.h>
#include "D3DSettings.h"
#include "D3DApplication.h"
#include "resource.h"
#include "DXUtil.h"
#include "D3DUtil.h"
using namespace dingus;
static CD3DSettingsDialog* gSettingsDialog = NULL;
static CD3DApplication* gSettingsApp = NULL;
//---------------------------------------------------------------------------
/**
* Returns the string for the given D3DDEVTYPE.
*/
TCHAR* gD3DDevTypeToString( D3DDEVTYPE devType )
{
switch( devType ) {
case D3DDEVTYPE_HAL: return TEXT("HW accelerated");
case D3DDEVTYPE_SW: return TEXT("Software");
case D3DDEVTYPE_REF: return TEXT("Reference");
default: return TEXT("Unknown");
}
};
/**
* Returns the string for the given D3DMULTISAMPLE_TYPE.
*/
TCHAR* gMultiSampleTypeToString( D3DMULTISAMPLE_TYPE msType )
{
switch( msType ) {
case D3DMULTISAMPLE_NONE: return TEXT("None");
case D3DMULTISAMPLE_NONMASKABLE: return TEXT("Nonmaskable");
case D3DMULTISAMPLE_2_SAMPLES: return TEXT("2x");
case D3DMULTISAMPLE_3_SAMPLES: return TEXT("3x");
case D3DMULTISAMPLE_4_SAMPLES: return TEXT("4x");
case D3DMULTISAMPLE_5_SAMPLES: return TEXT("5x");
case D3DMULTISAMPLE_6_SAMPLES: return TEXT("6x");
case D3DMULTISAMPLE_7_SAMPLES: return TEXT("7x");
case D3DMULTISAMPLE_8_SAMPLES: return TEXT("8x");
case D3DMULTISAMPLE_9_SAMPLES: return TEXT("9x");
case D3DMULTISAMPLE_10_SAMPLES: return TEXT("10x");
case D3DMULTISAMPLE_11_SAMPLES: return TEXT("11x");
case D3DMULTISAMPLE_12_SAMPLES: return TEXT("12x");
case D3DMULTISAMPLE_13_SAMPLES: return TEXT("13x");
case D3DMULTISAMPLE_14_SAMPLES: return TEXT("14x");
case D3DMULTISAMPLE_15_SAMPLES: return TEXT("15x");
case D3DMULTISAMPLE_16_SAMPLES: return TEXT("16x");
default: return TEXT("Unknown");
}
};
/**
* Returns the string for the given vertex processing.
*/
TCHAR* gVertexProcessingToString( eVertexProcessing vpt )
{
switch( vpt ) {
case SOFTWARE_VP: return TEXT("Software");
case MIXED_VP: return TEXT("Mixed");
case HARDWARE_VP: return TEXT("Hardware");
case PURE_HARDWARE_VP: return TEXT("Pure hardware");
default: return TEXT("Unknown");
}
};
/**
* Returns the string for the given present interval.
*/
TCHAR* gPresentIntervalToString( UINT pi )
{
switch( pi ) {
case D3DPRESENT_INTERVAL_IMMEDIATE: return TEXT("Immediate");
case D3DPRESENT_INTERVAL_DEFAULT: return TEXT("Default");
case D3DPRESENT_INTERVAL_ONE: return TEXT("One refresh");
case D3DPRESENT_INTERVAL_TWO: return TEXT("Two refreshes");
case D3DPRESENT_INTERVAL_THREE: return TEXT("Three refreshes");
case D3DPRESENT_INTERVAL_FOUR: return TEXT("Four refreshes");
default: return TEXT("Unknown");
}
};
//---------------------------------------------------------------------------
INT_PTR CALLBACK gDialogProcHelper( HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam )
{
return gSettingsDialog->dialogProc( hDlg, msg, wParam, lParam );
};
//---------------------------------------------------------------------------
// CD3DSettingsDialog
//---------------------------------------------------------------------------
CD3DSettingsDialog::CD3DSettingsDialog( const CD3DEnumeration& enumeration, const CD3DSettings& settings )
: mEnumeration(&enumeration),
mSettings(settings)
{
gSettingsDialog = this;
};
/** Adds an entry to the combo box. */
void CD3DSettingsDialog::comboBoxAdd( int id, const void* pData, const TCHAR* pstrDesc )
{
HWND hwndCtrl = GetDlgItem( mDlg, id );
DWORD dwItem = ComboBox_AddString( hwndCtrl, pstrDesc );
ComboBox_SetItemData( hwndCtrl, dwItem, pData );
};
/** Selects an entry in the combo box. */
void CD3DSettingsDialog::comboBoxSelect( int id, const void* pData )
{
HWND hwndCtrl = GetDlgItem( mDlg, id );
int count = comboBoxCount( id );
for( int iItem = 0; iItem < count; ++iItem ) {
if( (void*)ComboBox_GetItemData( hwndCtrl, iItem ) == pData ) {
ComboBox_SetCurSel( hwndCtrl, iItem );
PostMessage( mDlg, WM_COMMAND, MAKEWPARAM( id, CBN_SELCHANGE ), (LPARAM)hwndCtrl );
return;
}
}
};
/** Selects an entry in the combo box. */
void CD3DSettingsDialog::comboBoxSelectIndex( int id, int index )
{
HWND hwndCtrl = GetDlgItem( mDlg, id );
ComboBox_SetCurSel( hwndCtrl, index );
PostMessage( mDlg, WM_COMMAND, MAKEWPARAM( id, CBN_SELCHANGE ), (LPARAM)hwndCtrl );
};
/** Returns the data for the selected entry in the combo box. */
const void* CD3DSettingsDialog::comboBoxSelected( int id )
{
HWND hwndCtrl = GetDlgItem( mDlg, id );
int index = ComboBox_GetCurSel( hwndCtrl );
if( index < 0 )
return NULL;
return (const void*)ComboBox_GetItemData( hwndCtrl, index );
};
/**
* Returns whether any entry in the combo box is selected. This is more useful
* than comboBoxSelected() when you need to distinguish between having no item
* selected vs. having an item selected whose itemData is NULL.
*/
bool CD3DSettingsDialog::comboBoxSomethingSelected( int id )
{
HWND hwndCtrl = GetDlgItem( mDlg, id );
int index = ComboBox_GetCurSel( hwndCtrl );
return ( index >= 0 );
};
/** Returns the number of entries in the combo box. */
int CD3DSettingsDialog::comboBoxCount( int id )
{
HWND hwndCtrl = GetDlgItem( mDlg, id );
return ComboBox_GetCount( hwndCtrl );
};
/** Clears the entries in the combo box. */
void CD3DSettingsDialog::comboBoxClear( int id )
{
HWND hwndCtrl = GetDlgItem( mDlg, id );
ComboBox_ResetContent( hwndCtrl );
};
/** Returns whether the combo box contains the given text. */
bool CD3DSettingsDialog::comboBoxContainsText( int id, const TCHAR* pstrText )
{
TCHAR strItem[200];
HWND hwndCtrl = GetDlgItem( mDlg, id );
UINT count = comboBoxCount( id );
for( UINT iItem = 0; iItem < count; iItem++ )
{
if( ComboBox_GetLBTextLen( hwndCtrl, iItem ) >= 200 )
continue; // shouldn't happen, but don't overwrite buffer if it does
ComboBox_GetLBText( hwndCtrl, iItem, strItem );
if( lstrcmp( strItem, pstrText ) == 0 )
return true;
}
return false;
};
/** Show the D3D settings dialog. */
INT_PTR CD3DSettingsDialog::showDialog( HINSTANCE instance, HWND hwndParent, CD3DApplication& application )
{
gSettingsApp = &application;
return DialogBox( instance, MAKEINTRESOURCE( IDD_SELECTDEVICE ), hwndParent, gDialogProcHelper );
};
/** Handle window messages in the dialog. */
INT_PTR CD3DSettingsDialog::dialogProc( HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam )
{
UNREFERENCED_PARAMETER( lParam );
switch( msg ) {
case WM_INITDIALOG:
{
//
// initialize dialog
mDlg = hDlg;
// fill adapter combo box, updating the selected adapter will trigger
// updates of the rest of the dialog.
for( int iai = 0; iai < mEnumeration->mAdapterInfos.size(); ++iai ) {
const SD3DAdapterInfo* adInfo = mEnumeration->mAdapterInfos[iai];
TCHAR strDescription[512];
dingus::convertAnsiStringToGenericCch( strDescription, adInfo->adapterID.Description, 512 );
comboBoxAdd( IDC_ADAPTER_COMBO, adInfo, strDescription );
if( adInfo->adapterOrdinal == mSettings.getAdapterOrdinal() )
comboBoxSelect( IDC_ADAPTER_COMBO, adInfo );
}
if( !comboBoxSomethingSelected( IDC_ADAPTER_COMBO ) && comboBoxCount( IDC_ADAPTER_COMBO ) > 0 )
comboBoxSelectIndex( IDC_ADAPTER_COMBO, 0 );
// fill custom dialog
gSettingsApp->customSettingsInit( hDlg );
}
return TRUE;
case WM_COMMAND:
switch( LOWORD(wParam) )
{
case IDOK:
// get custom settings
gSettingsApp->customSettingsOK( hDlg );
EndDialog( hDlg, IDOK );
break;
case IDCANCEL:
EndDialog( hDlg, IDCANCEL );
break;
case IDC_ADAPTER_COMBO:
if( CBN_SELCHANGE == HIWORD(wParam) )
adapterChanged();
break;
case IDC_DEVICE_COMBO:
if( CBN_SELCHANGE == HIWORD(wParam) )
deviceChanged();
break;
case IDC_ADAPTERFORMAT_COMBO:
if( CBN_SELCHANGE == HIWORD(wParam) )
adapterFormatChanged();
break;
case IDC_RESOLUTION_COMBO:
if( CBN_SELCHANGE == HIWORD(wParam) )
resolutionChanged();
break;
case IDC_REFRESHRATE_COMBO:
if( CBN_SELCHANGE == HIWORD(wParam) )
refreshRateChanged();
break;
case IDC_BACKBUFFERFORMAT_COMBO:
if( CBN_SELCHANGE == HIWORD(wParam) )
backBufferFormatChanged();
break;
case IDC_DEPTHSTENCILBUFFERFORMAT_COMBO:
if( CBN_SELCHANGE == HIWORD(wParam) )
depthStencilBufferChanged();
break;
case IDC_MULTISAMPLE_COMBO:
if( CBN_SELCHANGE == HIWORD(wParam) )
multiSampleTypeChanged();
break;
case IDC_MULTISAMPLE_QUALITY_COMBO:
if( CBN_SELCHANGE == HIWORD(wParam) )
multiSampleQualityChanged();
break;
case IDC_VERTEXPROCESSING_COMBO:
if( CBN_SELCHANGE == HIWORD(wParam) )
vertexProcessingChanged();
break;
case IDC_PRESENTINTERVAL_COMBO:
if( CBN_SELCHANGE == HIWORD(wParam) )
presentIntervalChanged();
break;
case IDC_WINDOW:
case IDC_FULLSCREEN:
windowedFullscreenChanged();
break;
}
return TRUE;
default:
return FALSE;
}
}
/** Respond to a change of selected adapter. */
void CD3DSettingsDialog::adapterChanged()
{
const SD3DAdapterInfo* adInfo = (const SD3DAdapterInfo*)comboBoxSelected( IDC_ADAPTER_COMBO );
if( adInfo == NULL )
return;
mSettings.mSettings[mSettings.mMode].adapterInfo = adInfo;
// update device combo box
comboBoxClear( IDC_DEVICE_COMBO );
for( int idi = 0; idi < adInfo->deviceInfos.size(); ++idi ) {
const SD3DDeviceInfo* devInfo = adInfo->deviceInfos[idi];
comboBoxAdd( IDC_DEVICE_COMBO, devInfo, gD3DDevTypeToString( devInfo->deviceType ) );
if( devInfo->deviceType == mSettings.getDevType() )
comboBoxSelect( IDC_DEVICE_COMBO, devInfo );
}
if( !comboBoxSomethingSelected( IDC_DEVICE_COMBO ) && comboBoxCount( IDC_DEVICE_COMBO ) > 0 )
comboBoxSelectIndex( IDC_DEVICE_COMBO, 0 );
}
/**
* Respond to a change of selected device by resetting the fullscreen/windowed
* radio buttons. Updating these buttons will trigger updates of the rest of the dialog.
*/
void CD3DSettingsDialog::deviceChanged()
{
const SD3DDeviceInfo* devInfo = (const SD3DDeviceInfo*)comboBoxSelected( IDC_DEVICE_COMBO );
if( devInfo == NULL )
return;
mSettings.mSettings[mSettings.mMode].deviceInfo = devInfo;
// update fullscreen/windowed radio buttons
bool hasWindowedCombo = false;
bool hasFullscreenCombo = false;
for( int idc = 0; idc < devInfo->deviceCombos.size(); ++idc ) {
const SD3DDeviceCombo* devCombo = devInfo->deviceCombos[idc];
if( devCombo->isWindowed )
hasWindowedCombo = true;
else
hasFullscreenCombo = true;
};
EnableWindow( GetDlgItem( mDlg, IDC_WINDOW ), hasWindowedCombo );
EnableWindow( GetDlgItem( mDlg, IDC_FULLSCREEN ), hasFullscreenCombo );
if( mSettings.mMode == CD3DSettings::WINDOWED && hasWindowedCombo )
CheckRadioButton( mDlg, IDC_WINDOW, IDC_FULLSCREEN, IDC_WINDOW );
else
CheckRadioButton( mDlg, IDC_WINDOW, IDC_FULLSCREEN, IDC_FULLSCREEN );
windowedFullscreenChanged();
}
/**
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -