Files
Client/GameTools/ZALLA3D BASECLASS/EnumD3D.cpp
LGram16 dd97ddec92 Restructure repository to include all source folders
Move git root from Client/ to src/ to track all source code:
- Client: Game client source (moved to Client/Client/)
- Server: Game server source
- GameTools: Development tools
- CryptoSource: Encryption utilities
- database: Database scripts
- Script: Game scripts
- rylCoder_16.02.2008_src: Legacy coder tools
- GMFont, Game: Additional resources

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-29 20:17:20 +09:00

567 lines
20 KiB
C++
Raw Blame History

// EnumD3D.cpp: implementation of the CEnumD3D class.
//
//////////////////////////////////////////////////////////////////////
#include "EnumD3D.h"
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
D3DAdapterInfo CEnumD3D::m_Adapters[10];
DWORD CEnumD3D::m_dwNumAdapters;
DWORD CEnumD3D::m_dwAdapter;
BOOL CEnumD3D::m_bWindowed;
LPDIRECT3D8 CEnumD3D::m_pD3D;
BOOL CEnumD3D::m_bUseDepthBuffer;
long CEnumD3D::m_dwMinDepthBits;
long CEnumD3D::m_dwMinStencilBits;
long CEnumD3D::m_nAdapter;
long CEnumD3D::m_nDevice;
long CEnumD3D::m_nMode;
int SortModesCallback( const VOID* arg1, const VOID* arg2 )
{
D3DDISPLAYMODE* p1 = (D3DDISPLAYMODE*)arg1;
D3DDISPLAYMODE* p2 = (D3DDISPLAYMODE*)arg2;
if( p1->Format > p2->Format ) return -1;
if( p1->Format < p2->Format ) return +1;
if( p1->Width < p2->Width ) return -1;
if( p1->Width > p2->Width ) return +1;
if( p1->Height < p2->Height ) return -1;
if( p1->Height > p2->Height ) return +1;
return 0;
}
CEnumD3D::CEnumD3D()
{
m_bUseDepthBuffer=true;
m_nAdapter=m_nDevice=m_nMode=0;
}
CEnumD3D::~CEnumD3D()
{
}
HRESULT CEnumD3D::Enum()
{
/*
const TCHAR* strDeviceDescs[] = { "HAL", "REF" };
const D3DDEVTYPE DeviceTypes[] = { D3DDEVTYPE_HAL, D3DDEVTYPE_REF };
LPDIRECT3D8 pd3d=Direct3DCreate8(D3D_SDK_VERSION);
List<D3DAdapterInfo> m_AdapterInfo;
const int cDeviceTypes=2;
for(int cAdapter=0;cAdapter<pd3d->GetAdapterCount();cAdapter++)
{
D3DAdapterInfo AddAdapter;
pd3d->GetAdapterIdentifier(cAdapter,0,&AddAdapter.d3dAdapterIdentifier);
pd3d->GetAdapterDisplayMode(cAdapter,&AddAdapter.d3ddmDesktop);
AddAdapter.dwCurrentDevice=0;
AddAdapter.dwNumDevices=0;
List<D3DDISPLAYMODE> ModeList;
List<D3DFORMAT> PixelFormatList;
int cTotalMode=pd3d->GetAdapterModeCount(cAdapter);
for(int cMode=0;cMode<cTotalMode;cMode++)
{
D3DDISPLAYMODE DisplayMode;
pd3d->EnumAdapterModes(cAdapter,cMode,&DisplayMode);
if(DisplayMode.Width < 640 || DisplayMode.Height<400)
continue;
for(int cAlreadyMode=0;cAlreadyMode<ModeList.num;cAlreadyMode)
{
if( ModeList[cAlreadyMode].Width == DisplayMode.Width &&
ModeList[cAlreadyMode].Height == DisplayMode.Height &&
ModeList[cAlreadyMode].Format == DisplayMode.Format)
{
break;
}
}
if(cAlreadyMode==ModeList.num)
{
ModeList.Add(DisplayMode);
PixelFormatList.AddUnique(DisplayMode.Format);
}
}
for(int cDevice=0;cDevice<2;cDevice++)
{
D3DDeviceInfo AddDevice;
AddDevice.DeviceType=DeviceTypes[cDevice];
pd3d->GetDeviceCaps(cAdapter,DeviceTypes[cDevice],&AddDevice.d3dCaps);
AddDevice.strDesc=strDeviceDescs[cDevice];
AddDevice.dwNumModes=0;
AddDevice.dwCurrentMode=0;
AddDevice.bCanDoWindowed=FALSE;
AddDevice.bWindowed=FALSE;
AddDevice.MultiSampleType=D3DMULTISAMPLE_NONE;
BOOL bFormatConfirmed[20];
DWORD dwBehavior[20];
D3DFORMAT fmtDepthStencil[20];
for(int cFormat=0;cFormat<PixelFormatList.num;cFormat++)
{
bFormatConfirmed[cFormat]=FALSE;
fmtDepthStencil[cFormat]=D3DFMT_UNKNOWN;
if(FAILED( pd3d->CheckDeviceType( cAdapter, AddDevice.DeviceType,PixelFormatList[cFormat],PixelFormatList[cFormat],FALSE)))
{
continue;
}
if(AddDevice.DeviceType=D3DDEVTYPE_HAL)
{
// 3D ī<><C4AB><EFBFBD><EFBFBD> <20>޷<EFBFBD><DEB7>ְ<EFBFBD>//
}
if( AddDevice.d3dCaps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT)
{
if( AddDevice.d3dCaps.DevCaps & D3DDEVCAPS_PUREDEVICE)
{
dwBehavior[cFormat]=D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_PUREDEVICE;
// Confirmed is true when ConfirmDevice's Return value Succeeded//
bFormatConfirmed[cFormat]=TRUE;
}
if(bFormatConfirmed[cFormat]==FALSE)
{
dwBehavior[cFormat]=D3DCREATE_HARDWARE_VERTEXPROCESSING;
// Confirmed is true when ConfirmDevice's Return value Succeeded//
bFormatConfirmed[cFormat]=TRUE;
}
if(bFormatConfirmed[cFormat]==FALSE)
{
dwBehavior[cFormat]=D3DCREATE_MIXED_VERTEXPROCESSING;
// Confirmed is true when ConfirmDevice's Return value Succeeded//
bFormatConfirmed[cFormat]=TRUE;
}
}
if(bFormatConfirmed[cFormat]==FALSE)
{
dwBehavior[cFormat]=D3DCREATE_SOFTWARE_VERTEXPROCESSING;
// Confirmed is true when ConfirmDevice's Return value Succeeded//
bFormatConfirmed[cFormat]=TRUE;
}
if( bFormatConfirmed[cFormat] && m_bUseDepthBuffer)
{
if(!FindDepthStencilFormat(cAdapter,AddDevice.DeviceType,PixelFormatList[cFormat],&fmtDepthStencil[cFormat]))
{
bFormatConfirmed[cFormat]=FALSE;
}
}
}
for(int cMode=0;cMode<ModeList.num;cMode++)
{
for(int cFormat=0;cFormat<PixelFormatList.num;cFormat++)
{
if( ModeList[cMode].Format == PixelFormatList[cFormat] )
{
if(bFormatConfirmed[cFormat]==TRUE)
{
AddDevice.modes[AddDevice.dwNumModes].Width=ModeList[cMode].Width;
AddDevice.modes[AddDevice.dwNumModes].Height=ModeList[cMode].Height;
AddDevice.modes[AddDevice.dwNumModes].Format=ModeList[cMode].Format;
AddDevice.modes[AddDevice.dwNumModes].dwBehavior=dwBehavior[cFormat];
AddDevice.modes[AddDevice.dwNumModes].DepthStencilFormat=fmtDepthStencil[cFormat];
AddDevice.dwNumModes++;
}
}
}
}
for(cMode=0;cMode<AddDevice.dwNumModes;cMode++)
{
if(AddDevice.modes[cMode].Width==640 && AddDevice.modes[cMode].Height==480)
{
AddDevice.dwCurrentMode=cMode;
if( AddDevice.modes[cMode].Format==D3DFMT_R5G6B5||
AddDevice.modes[cMode].Format==D3DFMT_X1R5G5B5||
AddDevice.modes[cMode].Format==D3DFMT_A1R5G5B5)
{
break;
}
}
}
if( bFormatConfirmed[0] && (AddDevice.d3dCaps.Caps2 & D3DCAPS2_CANRENDERWINDOWED) )
{
AddDevice.bCanDoWindowed = TRUE;
AddDevice.bWindowed = TRUE;
}
if( AddDevice.dwNumModes > 0 )
AddAdapter.dwNumDevices++;
}
m_AdapterInfo.Add(AddAdapter);
}
return S_OK;
*/
m_pD3D=Direct3DCreate8(D3D_SDK_VERSION);
const DWORD dwNumDeviceTypes = 2;
const TCHAR* strDeviceDescs[] = { "HAL", "REF" };
const D3DDEVTYPE DeviceTypes[] = { D3DDEVTYPE_HAL, D3DDEVTYPE_REF };
BOOL bHALExists = FALSE;
BOOL bHALIsWindowedCompatible = FALSE;
BOOL bHALIsDesktopCompatible = FALSE;
BOOL bHALIsSampleCompatible = FALSE;
// Loop through all the adapters on the system (usually, there's just one
// unless more than one graphics card is present).
m_dwNumAdapters=0;
for( UINT iAdapter = 0; iAdapter < m_pD3D->GetAdapterCount(); iAdapter++ )
{
// Fill in adapter info
D3DAdapterInfo* pAdapter = &m_Adapters[m_dwNumAdapters];
m_pD3D->GetAdapterIdentifier( iAdapter, 0, &pAdapter->d3dAdapterIdentifier );
m_pD3D->GetAdapterDisplayMode( iAdapter, &pAdapter->d3ddmDesktop );
pAdapter->dwNumDevices = 0;
pAdapter->dwCurrentDevice = 0;
// Enumerate all display modes on this adapter
D3DDISPLAYMODE modes[100];
D3DFORMAT formats[20];
DWORD dwNumFormats = 0;
DWORD dwNumModes = 0;
DWORD dwNumAdapterModes = m_pD3D->GetAdapterModeCount( iAdapter );
// Add the adapter's current desktop format to the list of formats
formats[dwNumFormats++] = pAdapter->d3ddmDesktop.Format;
for( UINT iMode = 0; iMode < dwNumAdapterModes; iMode++ )
{
// Get the display mode attributes
D3DDISPLAYMODE DisplayMode;
m_pD3D->EnumAdapterModes( iAdapter, iMode, &DisplayMode );
// Filter out low-resolution modes
if( DisplayMode.Width < 640 || DisplayMode.Height < 400 )
continue;
// Check if the mode already exists (to filter out refresh rates)
for( DWORD m=0L; m<dwNumModes; m++ )
{
if( ( modes[m].Width == DisplayMode.Width ) &&
( modes[m].Height == DisplayMode.Height ) &&
( modes[m].Format == DisplayMode.Format ) )
break;
}
// If we found a new mode, add it to the list of modes
if( m == dwNumModes )
{
modes[dwNumModes].Width = DisplayMode.Width;
modes[dwNumModes].Height = DisplayMode.Height;
modes[dwNumModes].Format = DisplayMode.Format;
modes[dwNumModes].RefreshRate = 0;
dwNumModes++;
// Check if the mode's format already exists
for( DWORD f=0; f<dwNumFormats; f++ )
{
if( DisplayMode.Format == formats[f] )
break;
}
// If the format is new, add it to the list
if( f== dwNumFormats )
formats[dwNumFormats++] = DisplayMode.Format;
}
}
// Sort the list of display modes (by format, then width, then height)
qsort( modes, dwNumModes, sizeof(D3DDISPLAYMODE), SortModesCallback );
// Add devices to adapter
for( UINT iDevice = 0; iDevice < dwNumDeviceTypes; iDevice++ )
{
// Fill in device info
D3DDeviceInfo* pDevice;
pDevice = &pAdapter->devices[pAdapter->dwNumDevices];
pDevice->DeviceType = DeviceTypes[iDevice];
m_pD3D->GetDeviceCaps( iAdapter, DeviceTypes[iDevice], &pDevice->d3dCaps );
pDevice->strDesc = strDeviceDescs[iDevice];
pDevice->dwNumModes = 0;
pDevice->dwCurrentMode = 0;
pDevice->bCanDoWindowed = FALSE;
pDevice->bWindowed = FALSE;
pDevice->MultiSampleType = D3DMULTISAMPLE_NONE;
// Examine each format supported by the adapter to see if it will
// work with this device and meets the needs of the application.
BOOL bFormatConfirmed[20];
DWORD dwBehavior[20];
D3DFORMAT fmtDepthStencil[20];
for( DWORD f=0; f<dwNumFormats; f++ )
{
bFormatConfirmed[f] = FALSE;
fmtDepthStencil[f] = D3DFMT_UNKNOWN;
// Skip formats that cannot be used as render targets on this device
if( FAILED( m_pD3D->CheckDeviceType( iAdapter, pDevice->DeviceType,
formats[f], formats[f], FALSE ) ) )
continue;
if( pDevice->DeviceType == D3DDEVTYPE_HAL )
{
// This system has a HAL device
bHALExists = TRUE;
if( pDevice->d3dCaps.Caps2 & D3DCAPS2_CANRENDERWINDOWED )
{
// HAL can run in a window for some mode
bHALIsWindowedCompatible = TRUE;
if( f == 0 )
{
// HAL can run in a window for the current desktop mode
bHALIsDesktopCompatible = TRUE;
}
}
}
// Confirm the device/format for HW vertex processing
if( pDevice->d3dCaps.DevCaps&D3DDEVCAPS_HWTRANSFORMANDLIGHT )
{
if( pDevice->d3dCaps.DevCaps&D3DDEVCAPS_PUREDEVICE )
{
/*
dwBehavior[f] = D3DCREATE_HARDWARE_VERTEXPROCESSING |
D3DCREATE_PUREDEVICE;
*/
dwBehavior[f] = D3DCREATE_HARDWARE_VERTEXPROCESSING;
if( SUCCEEDED( ConfirmDevice( &pDevice->d3dCaps, dwBehavior[f],
formats[f] ) ) )
bFormatConfirmed[f] = FALSE;
}
if ( FALSE == bFormatConfirmed[f] )
{
dwBehavior[f] = D3DCREATE_HARDWARE_VERTEXPROCESSING;
if( SUCCEEDED( ConfirmDevice( &pDevice->d3dCaps, dwBehavior[f],
formats[f] ) ) )
bFormatConfirmed[f] = TRUE;
}
if ( FALSE == bFormatConfirmed[f] )
{
dwBehavior[f] = D3DCREATE_MIXED_VERTEXPROCESSING;
if( SUCCEEDED( ConfirmDevice( &pDevice->d3dCaps, dwBehavior[f],
formats[f] ) ) )
bFormatConfirmed[f] = TRUE;
}
}
// Confirm the device/format for SW vertex processing
if( FALSE == bFormatConfirmed[f] )
{
dwBehavior[f] = D3DCREATE_SOFTWARE_VERTEXPROCESSING;
if( SUCCEEDED( ConfirmDevice( &pDevice->d3dCaps, dwBehavior[f],
formats[f] ) ) )
bFormatConfirmed[f] = TRUE;
}
// Find a suitable depth/stencil buffer format for this device/format
if( bFormatConfirmed[f])
{
if( !FindDepthStencilFormat( iAdapter, pDevice->DeviceType,
formats[f], &fmtDepthStencil[f] ) )
{
bFormatConfirmed[f] = FALSE;
}
}
}
// Add all enumerated display modes with confirmed formats to the
// device's list of valid modes
for( DWORD m=0L; m<dwNumModes; m++ )
{
for( DWORD f=0; f<dwNumFormats; f++ )
{
if( modes[m].Format == formats[f] )
{
if( bFormatConfirmed[f] == TRUE )
{
// Add this mode to the device's list of valid modes
pDevice->modes[pDevice->dwNumModes].Width = modes[m].Width;
pDevice->modes[pDevice->dwNumModes].Height = modes[m].Height;
pDevice->modes[pDevice->dwNumModes].Format = modes[m].Format;
pDevice->modes[pDevice->dwNumModes].dwBehavior = dwBehavior[f];
pDevice->modes[pDevice->dwNumModes].DepthStencilFormat = fmtDepthStencil[f];
pDevice->dwNumModes++;
if( pDevice->DeviceType == D3DDEVTYPE_HAL )
bHALIsSampleCompatible = TRUE;
}
}
}
}
// Select any 640x480 mode for default (but prefer a 16-bit mode)
for( m=0; m<pDevice->dwNumModes; m++ )
{
if( pDevice->modes[m].Width==640 && pDevice->modes[m].Height==480 )
{
pDevice->dwCurrentMode = m;
if( pDevice->modes[m].Format == D3DFMT_R5G6B5 ||
pDevice->modes[m].Format == D3DFMT_X1R5G5B5 ||
pDevice->modes[m].Format == D3DFMT_A1R5G5B5 )
{
break;
}
}
}
// Check if the device is compatible with the desktop display mode
// (which was added initially as formats[0])
if( bFormatConfirmed[0] && (pDevice->d3dCaps.Caps2 & D3DCAPS2_CANRENDERWINDOWED) )
{
pDevice->bCanDoWindowed = TRUE;
pDevice->bWindowed = TRUE;
}
// If valid modes were found, keep this device
if( pDevice->dwNumModes > 0 )
pAdapter->dwNumDevices++;
}
// If valid devices were found, keep this adapter
if( pAdapter->dwNumDevices > 0 )
m_dwNumAdapters++;
}
// Return an error if no compatible devices were found
if( 0L == m_dwNumAdapters )
return S_OK;
// Pick a default device that can render into a window
// (This code assumes that the HAL device comes before the REF
// device in the device array).
m_pD3D->Release();
for( DWORD a=0; a<m_dwNumAdapters; a++ )
{
for( DWORD d=0; d < m_Adapters[a].dwNumDevices; d++ )
{
if( m_Adapters[a].devices[d].bWindowed )
{
m_Adapters[a].dwCurrentDevice = d;
m_dwAdapter = a;
m_bWindowed = TRUE;
return S_OK;
}
}
}
return S_OK;
}
BOOL CEnumD3D::FindDepthStencilFormat(UINT iAdapter, D3DDEVTYPE DeviceType, D3DFORMAT TargetFormat, D3DFORMAT *pDepthStencilFormat)
{
if( m_dwMinDepthBits <= 16 && m_dwMinStencilBits == 0 )
{
if( SUCCEEDED( m_pD3D->CheckDeviceFormat( iAdapter, DeviceType,
TargetFormat, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, D3DFMT_D16 ) ) )
{
if( SUCCEEDED( m_pD3D->CheckDepthStencilMatch( iAdapter, DeviceType,
TargetFormat, TargetFormat, D3DFMT_D16 ) ) )
{
*pDepthStencilFormat = D3DFMT_D16;
return TRUE;
}
}
}
if( m_dwMinDepthBits <= 15 && m_dwMinStencilBits <= 1 )
{
if( SUCCEEDED( m_pD3D->CheckDeviceFormat( iAdapter, DeviceType,
TargetFormat, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, D3DFMT_D15S1 ) ) )
{
if( SUCCEEDED( m_pD3D->CheckDepthStencilMatch( iAdapter, DeviceType,
TargetFormat, TargetFormat, D3DFMT_D15S1 ) ) )
{
*pDepthStencilFormat = D3DFMT_D15S1;
return TRUE;
}
}
}
if( m_dwMinDepthBits <= 24 && m_dwMinStencilBits == 0 )
{
if( SUCCEEDED( m_pD3D->CheckDeviceFormat( iAdapter, DeviceType,
TargetFormat, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, D3DFMT_D24X8 ) ) )
{
if( SUCCEEDED( m_pD3D->CheckDepthStencilMatch( iAdapter, DeviceType,
TargetFormat, TargetFormat, D3DFMT_D24X8 ) ) )
{
*pDepthStencilFormat = D3DFMT_D24X8;
return TRUE;
}
}
}
if( m_dwMinDepthBits <= 24 && m_dwMinStencilBits <= 8 )
{
if( SUCCEEDED( m_pD3D->CheckDeviceFormat( iAdapter, DeviceType,
TargetFormat, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, D3DFMT_D24S8 ) ) )
{
if( SUCCEEDED( m_pD3D->CheckDepthStencilMatch( iAdapter, DeviceType,
TargetFormat, TargetFormat, D3DFMT_D24S8 ) ) )
{
*pDepthStencilFormat = D3DFMT_D24S8;
return TRUE;
}
}
}
if( m_dwMinDepthBits <= 24 && m_dwMinStencilBits <= 4 )
{
if( SUCCEEDED( m_pD3D->CheckDeviceFormat( iAdapter, DeviceType,
TargetFormat, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, D3DFMT_D24X4S4 ) ) )
{
if( SUCCEEDED( m_pD3D->CheckDepthStencilMatch( iAdapter, DeviceType,
TargetFormat, TargetFormat, D3DFMT_D24X4S4 ) ) )
{
*pDepthStencilFormat = D3DFMT_D24X4S4;
return TRUE;
}
}
}
if( m_dwMinDepthBits <= 32 && m_dwMinStencilBits == 0 )
{
if( SUCCEEDED( m_pD3D->CheckDeviceFormat( iAdapter, DeviceType,
TargetFormat, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, D3DFMT_D32 ) ) )
{
if( SUCCEEDED( m_pD3D->CheckDepthStencilMatch( iAdapter, DeviceType,
TargetFormat, TargetFormat, D3DFMT_D32 ) ) )
{
*pDepthStencilFormat = D3DFMT_D32;
return TRUE;
}
}
}
return FALSE;
}
HRESULT CEnumD3D::ConfirmDevice(D3DCAPS8 *, DWORD, D3DFORMAT)
{
return S_OK;
}