📄 zfxd3d_enum.cpp
字号:
// File: ZFXD3D_enum.cpp
#include "resource.h" // control id's
#include "ZFX.h" // return values and stuff
#include "ZFXD3D.h" // class definition
extern bool g_bLF;
// some common backbuffer formats
const UINT g_nFormats_B=9;
const D3DFORMAT g_fmtBackBuffer[] = {
D3DFMT_R8G8B8, D3DFMT_A8R8G8B8,
D3DFMT_X8R8G8B8, D3DFMT_R5G6B5,
D3DFMT_A1R5G5B5, D3DFMT_X1R5G5B5,
D3DFMT_X4R4G4B4, D3DFMT_A4R4G4B4,
D3DFMT_A2B10G10R10
};
// some good multisample modes, list best ones last
const UINT g_nMS = 8;
const D3DMULTISAMPLE_TYPE g_msType[] = {
D3DMULTISAMPLE_NONE,
D3DMULTISAMPLE_2_SAMPLES,
D3DMULTISAMPLE_3_SAMPLES,
D3DMULTISAMPLE_4_SAMPLES,
D3DMULTISAMPLE_5_SAMPLES,
D3DMULTISAMPLE_6_SAMPLES,
D3DMULTISAMPLE_7_SAMPLES,
D3DMULTISAMPLE_8_SAMPLES,
};
// F U N C T I O N S ///////////////////////////////////////////////
/**
* Enumerates all available display modes and fills the given combo
* boxes with corresponding values.
* -> IN: HWND - combobox to receive available adapters
* HWND - combobox used for display modes
* HWND - combobox used for device types
* HWND - combobox used for adapter formats
* HWND - combobox used for backbuffer formats
* HWND - radiobutton windowed
* HWND - radiobutton fullscreen
* FILE - already open log file
*/
HRESULT ZFXD3DEnum::Enum(HWND hAdapter, HWND hMode,
HWND hDevice, HWND hAdapterFmt,
HWND hBackFmt, HWND hWnd,
HWND hFull, FILE *pLog) {
HRESULT hr;
if (pLog) m_pLog = pLog;
// create main Direct3D object
m_pD3D = Direct3DCreate9(D3D_SDK_VERSION);
if(m_pD3D == NULL){
return ZFX_CREATEAPI;
}
// save handles to comboboxes
m_hADAPTER = hAdapter;
m_hMODE = hMode;
m_hDEVICE = hDevice;
m_hADAPTERFMT = hAdapterFmt;
m_hBACKFMT = hBackFmt;
m_hWND = hWnd;
m_hFULL = hFull;
// nothing yet
m_dwNumAdapters = 0;
// set misc values
m_nMinWidth = 800;
m_nMinHeight = 600;
m_nMinBits = 16;
// set allowed bpp formats
m_fmtAdapter[0] = D3DFMT_X8R8G8B8; // 32 Bit
m_fmtAdapter[1] = D3DFMT_X1R5G5B5; // 15 Bit
m_fmtAdapter[2] = D3DFMT_R5G6B5; // 16 Bit
m_nNumFmt = 3;
// get current adapters display mode
if (FAILED(m_pD3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &m_dspmd))) {
if (m_pLog) {
fprintf(m_pLog, "Enum: GetAdapterDisplayMode() failed \n");
fflush(m_pLog);
}
}
// enumerate available adapters
hr = EnumAdapters();
// we don't need this for now
m_pD3D->Release();
m_pD3D = NULL;
if(FAILED(hr) || !hAdapter)
return ZFX_FAIL;
if (m_dwNumAdapters == 0)
return ZFX_NOTCOMPATIBLE;
// list the found graphics adapter
SendMessage(m_hADAPTER,CB_RESETCONTENT,0,0);
for (UINT a=0; a<m_dwNumAdapters; a++) {
AddItem(m_hADAPTER, m_xAdapterInfo[a].
d3dAdapterIdentifier.Description,
&m_xAdapterInfo[a]);
}
// treat enum like adapter change
SendMessage(m_hADAPTER, CB_SETCURSEL, (WPARAM)0, 0);
ChangedAdapter();
// select first entry from each combo
SendMessage(m_hADAPTER, CB_SETCURSEL, (WPARAM)0, 0);
SendMessage(m_hMODE, CB_SETCURSEL, (WPARAM)0, 0);
SendMessage(m_hDEVICE, CB_SETCURSEL, (WPARAM)0, 0);
SendMessage(m_hBACKFMT, CB_SETCURSEL, (WPARAM)0, 0);
SendMessage(m_hADAPTERFMT, CB_SETCURSEL, (WPARAM)0, 0);
return ZFX_OK;
} // Enum
/*----------------------------------------------------------------*/
/**
* Three helper function for combobox-convenience.
*/
void* GetSelectedItem(HWND hWnd) {
WPARAM nI = (WPARAM)((int)(DWORD)SendMessage(hWnd,CB_GETCURSEL,0,0));
return ((void*)SendMessage(hWnd,CB_GETITEMDATA,nI,0));
}
/*----------------------------------------------------------------*/
void AddItem(HWND hWnd, char *ch, void *pData) {
WPARAM nI = (WPARAM)((int)(DWORD)SendMessage(hWnd,CB_ADDSTRING,0,(LPARAM)ch));
SendMessage(hWnd,CB_SETITEMDATA, nI, (LPARAM)pData);
}
/*----------------------------------------------------------------*/
bool ContainsString(HWND hWnd, char *ch) {
int n = (int)SendMessage(hWnd, CB_GETCOUNT, 0, 0);
char buffer[200];
for(int nIndex=0; nIndex<n; nIndex++) {
SendMessage(hWnd, CB_GETLBTEXT, (WPARAM)nIndex, (LPARAM)buffer);
if (lstrcmp(buffer, ch) == 0)
return true;
}
return false;
}
/*----------------------------------------------------------------*/
/**
* Ask the Comboboxes for the final settings.
*/
void ZFXD3DEnum::GetSelections(ZFXDEVICEINFO *pD, D3DDISPLAYMODE *dspmd,
D3DFORMAT *fmtA, D3DFORMAT *fmtB) {
if (pD)
memcpy(pD, GetSelectedItem(m_hDEVICE), sizeof(ZFXDEVICEINFO));
if (fmtA)
memcpy(fmtA, GetSelectedItem(m_hADAPTERFMT), sizeof(D3DFORMAT));
if (fmtB)
memcpy(fmtB, GetSelectedItem(m_hBACKFMT), sizeof(D3DFORMAT));
if (dspmd) {
D3DDISPLAYMODE *pDspmd = (D3DDISPLAYMODE*)GetSelectedItem(m_hMODE);
// fullscreen mode
if (pDspmd) memcpy(dspmd, pDspmd, sizeof(D3DDISPLAYMODE));
// windowed mode
else
memcpy(dspmd, &m_dspmd, sizeof(D3DDISPLAYMODE));
}
} // GetSelections
/*----------------------------------------------------------------*/
/**
* Call when adapter selection changed. This will reset device
* combobox, list devices for new adapter, and call ChangedDevice().
*/
void ZFXD3DEnum::ChangedAdapter(void) {
ZFXADAPTERINFO *pA=NULL;
// delete content of device combobox
SendMessage(m_hDEVICE, CB_RESETCONTENT, 0, 0);
pA = (ZFXADAPTERINFO *)GetSelectedItem(m_hADAPTER);
for (UINT d=0; d<pA->nNumDevs; d++) {
AddItem(m_hDEVICE, D3DDevTypeToString(pA->d3dDevs[d].
d3dDevType), &pA->d3dDevs[d]);
}
SendMessage(m_hDEVICE, CB_SETCURSEL, (WPARAM)0, 0);
// treat as if device slectio changed
ChangedDevice();
} // ChangedAdapter
/*----------------------------------------------------------------*/
/**
* Call when device selection changed. This will reset radio button
* states for windowed/fullscreen mode and call ChangedWindowMode().
*/
void ZFXD3DEnum::ChangedDevice(void) {
ZFXDEVICEINFO *pD=NULL;
bool bWindowed=false,
bFullscreen=false;
pD = (ZFXDEVICEINFO *)GetSelectedItem(m_hDEVICE);
// check if windowed/fullscreen mode possible
for (UINT c=0; c<pD->nNumCombo; c++) {
if (pD->d3dCombo[c].bWindowed)
bWindowed = true;
else
bFullscreen = true;
}
// active radio buttons accordingliy
EnableWindow(m_hWND, bWindowed);
EnableWindow(m_hFULL, bFullscreen);
if (!bWindowed && (SendMessage(m_hWND,BM_GETCHECK,0,0)==BST_CHECKED))
SendMessage(m_hFULL, BM_SETCHECK, BST_CHECKED, 0);
// treat as if radio button changed
ChangedWindowMode();
} // ChangedDevice
/*----------------------------------------------------------------*/
/**
* Call when window/fullscreen selection changed. Will relist adapter-
* format and mode combobox and call ChangedAdapterFmt().
*/
void ZFXD3DEnum::ChangedWindowMode(void) {
ZFXADAPTERINFO *pA=NULL;
ZFXDEVICEINFO *pD=NULL;
ZFXCOMBOINFO *pC=NULL;
char buffer[100];
pA = (ZFXADAPTERINFO *)GetSelectedItem(m_hADAPTER);
pD = (ZFXDEVICEINFO *)GetSelectedItem(m_hDEVICE);
// clear'em out
SendMessage(m_hADAPTERFMT, CB_RESETCONTENT, 0, 0);
SendMessage(m_hMODE, CB_RESETCONTENT, 0, 0);
// windowed mode?
if (SendMessage(m_hWND,BM_GETCHECK,0,0)==BST_CHECKED) {
// use current desktop format
AddItem(m_hADAPTERFMT, D3DFormatToString(m_dspmd.Format),
&m_dspmd.Format);
// use current desktop resolution
sprintf(buffer, "%d x %d", m_dspmd.Width, m_dspmd.Height);
SendMessage(m_hMODE, CB_ADDSTRING, 0, (LPARAM)buffer);
EnableWindow(m_hADAPTERFMT, false);
EnableWindow(m_hMODE, false);
}
else {
SendMessage(m_hADAPTERFMT, CB_RESETCONTENT, 0, 0);
SendMessage(m_hMODE, CB_RESETCONTENT, 0, 0);
EnableWindow(m_hADAPTERFMT, true);
EnableWindow(m_hMODE, true);
// list all combos for this device
for (UINT c=0; c<pD->nNumCombo; c++) {
pC = &pD->d3dCombo[c];
if (!ContainsString(m_hADAPTERFMT, D3DFormatToString(pC->fmtAdapter)))
AddItem(m_hADAPTERFMT,
D3DFormatToString(pC->fmtAdapter),
&pC->fmtAdapter);
} // for [combos]
}
// select first item each
SendMessage(m_hADAPTERFMT, CB_SETCURSEL, (WPARAM)0, 0);
SendMessage(m_hMODE, CB_SETCURSEL, (WPARAM)0, 0);
// treat as if adapter format changed
ChangedAdapterFmt();
} // ChangedWindowMode
/*----------------------------------------------------------------*/
/**
* Call when adapter format selection changed. Will relist mode and
* backbuffer-format combobox.
*/
void ZFXD3DEnum::ChangedAdapterFmt(void) {
ZFXADAPTERINFO *pA=NULL;
ZFXDEVICEINFO *pD=NULL;
ZFXCOMBOINFO *pC=NULL;
D3DDISPLAYMODE *dpsmd=NULL;
D3DFORMAT *pFmt=NULL;
char buffer[200];
bool bWindowed;
pA = (ZFXADAPTERINFO *)GetSelectedItem(m_hADAPTER);
pD = (ZFXDEVICEINFO *)GetSelectedItem(m_hDEVICE);
pFmt = (D3DFORMAT *)GetSelectedItem(m_hADAPTERFMT);
bWindowed = (SendMessage(m_hWND,BM_GETCHECK,0,0)==BST_CHECKED);
SendMessage(m_hBACKFMT, CB_RESETCONTENT, 0, 0);
// windowed mode?
if (!bWindowed) {
SendMessage(m_hMODE, CB_RESETCONTENT, 0, 0);
// loop through all available modes
for (UINT m=0; m<pA->nNumModes; m++) {
dpsmd = &pA->d3ddspmd[m];
sprintf(buffer, "%d x %d", dpsmd->Width, dpsmd->Height);
if (!ContainsString(m_hMODE, buffer)) {
AddItem(m_hMODE, buffer, &pA->d3ddspmd[m]);
}
} // for [modes]
// set backbuffer format to adapter format
AddItem(m_hBACKFMT,D3DFormatToString(*pFmt),&(*pFmt));
SendMessage(m_hMODE, CB_SETCURSEL, (WPARAM)0, 0);
} // [!windowed]
else {
for (UINT c=0; c<pD->nNumCombo; c++) {
pC = &pD->d3dCombo[c];
// if same window mode and adapter format
if ((bWindowed == pC->bWindowed) &&
(*pFmt == pC->fmtAdapter) ) {
if (!ContainsString(m_hBACKFMT,
D3DFormatToString(pC->fmtAdapter)))
AddItem(m_hBACKFMT,
D3DFormatToString(pC->fmtBackBuffer),
&pC->fmtBackBuffer);
}
}
}
SendMessage(m_hBACKFMT, CB_SETCURSEL, (WPARAM)0, 0);
} // ChangedAdapterFmt
/*----------------------------------------------------------------*/
static int __cdecl SortModesCallback(const void* arg1, const void* arg2) {
D3DDISPLAYMODE* pdm1 = (D3DDISPLAYMODE*)arg1;
D3DDISPLAYMODE* pdm2 = (D3DDISPLAYMODE*)arg2;
if (pdm1->Width > pdm2->Width)
return 1;
if (pdm1->Width < pdm2->Width)
return -1;
if (pdm1->Height > pdm2->Height)
return 1;
if (pdm1->Height < pdm2->Height)
return -1;
if (pdm1->Format > pdm2->Format)
return 1;
if (pdm1->Format < pdm2->Format)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -