diff options
| author | Jason Maskell <[email protected]> | 2016-05-09 10:39:54 +0200 |
|---|---|---|
| committer | Jason Maskell <[email protected]> | 2016-05-09 10:39:54 +0200 |
| commit | 79b3462799c28af8ba586349bd671b1b56e72353 (patch) | |
| tree | 3b06e36c390254c0dc7f3733a0d32af213d87293 /sample/d3d11/common/DXUTmisc.cpp | |
| download | waveworks_archive-79b3462799c28af8ba586349bd671b1b56e72353.tar.xz waveworks_archive-79b3462799c28af8ba586349bd671b1b56e72353.zip | |
Initial commit with PS4 and XBone stuff trimmed.
Diffstat (limited to 'sample/d3d11/common/DXUTmisc.cpp')
| -rw-r--r-- | sample/d3d11/common/DXUTmisc.cpp | 1785 |
1 files changed, 1785 insertions, 0 deletions
diff --git a/sample/d3d11/common/DXUTmisc.cpp b/sample/d3d11/common/DXUTmisc.cpp new file mode 100644 index 0000000..f76ee92 --- /dev/null +++ b/sample/d3d11/common/DXUTmisc.cpp @@ -0,0 +1,1785 @@ +//-------------------------------------------------------------------------------------- +// File: DXUTMisc.cpp +// +// Shortcut macros and functions for using DX objects +// +// Copyright (c) Microsoft Corporation. All rights reserved +//-------------------------------------------------------------------------------------- +#include "dxut.h" +#include <xinput.h> +#define DXUT_GAMEPAD_TRIGGER_THRESHOLD 30 +#undef min // use __min instead +#undef max // use __max instead + +CDXUTTimer* WINAPI DXUTGetGlobalTimer() +{ + // Using an accessor function gives control of the construction order + static CDXUTTimer timer; + return &timer; +} + + +//-------------------------------------------------------------------------------------- +CDXUTTimer::CDXUTTimer() +{ + m_bTimerStopped = true; + m_llQPFTicksPerSec = 0; + + m_llStopTime = 0; + m_llLastElapsedTime = 0; + m_llBaseTime = 0; + + // Use QueryPerformanceFrequency to get the frequency of the counter + LARGE_INTEGER qwTicksPerSec = { 0 }; + QueryPerformanceFrequency( &qwTicksPerSec ); + m_llQPFTicksPerSec = qwTicksPerSec.QuadPart; +} + + +//-------------------------------------------------------------------------------------- +void CDXUTTimer::Reset() +{ + LARGE_INTEGER qwTime = GetAdjustedCurrentTime(); + + m_llBaseTime = qwTime.QuadPart; + m_llLastElapsedTime = qwTime.QuadPart; + m_llStopTime = 0; + m_bTimerStopped = FALSE; +} + + +//-------------------------------------------------------------------------------------- +void CDXUTTimer::Start() +{ + // Get the current time + LARGE_INTEGER qwTime = { 0 }; + QueryPerformanceCounter( &qwTime ); + + if( m_bTimerStopped ) + m_llBaseTime += qwTime.QuadPart - m_llStopTime; + m_llStopTime = 0; + m_llLastElapsedTime = qwTime.QuadPart; + m_bTimerStopped = FALSE; +} + + +//-------------------------------------------------------------------------------------- +void CDXUTTimer::Stop() +{ + if( !m_bTimerStopped ) + { + LARGE_INTEGER qwTime = { 0 }; + QueryPerformanceCounter( &qwTime ); + m_llStopTime = qwTime.QuadPart; + m_llLastElapsedTime = qwTime.QuadPart; + m_bTimerStopped = TRUE; + } +} + + +//-------------------------------------------------------------------------------------- +void CDXUTTimer::Advance() +{ + m_llStopTime += m_llQPFTicksPerSec / 10; +} + + +//-------------------------------------------------------------------------------------- +double CDXUTTimer::GetAbsoluteTime() +{ + LARGE_INTEGER qwTime = { 0 }; + QueryPerformanceCounter( &qwTime ); + + double fTime = qwTime.QuadPart / ( double )m_llQPFTicksPerSec; + + return fTime; +} + + +//-------------------------------------------------------------------------------------- +double CDXUTTimer::GetTime() +{ + LARGE_INTEGER qwTime = GetAdjustedCurrentTime(); + + double fAppTime = ( double )( qwTime.QuadPart - m_llBaseTime ) / ( double )m_llQPFTicksPerSec; + + return fAppTime; +} + + +//-------------------------------------------------------------------------------------- +void CDXUTTimer::GetTimeValues( double* pfTime, double* pfAbsoluteTime, float* pfElapsedTime ) +{ + assert( pfTime && pfAbsoluteTime && pfElapsedTime ); + + LARGE_INTEGER qwTime = GetAdjustedCurrentTime(); + + float fElapsedTime = (float) ((double) ( qwTime.QuadPart - m_llLastElapsedTime ) / (double) m_llQPFTicksPerSec); + m_llLastElapsedTime = qwTime.QuadPart; + + // Clamp the timer to non-negative values to ensure the timer is accurate. + // fElapsedTime can be outside this range if processor goes into a + // power save mode or we somehow get shuffled to another processor. + // However, the main thread should call SetThreadAffinityMask to ensure that + // we don't get shuffled to another processor. Other worker threads should NOT call + // SetThreadAffinityMask, but use a shared copy of the timer data gathered from + // the main thread. + if( fElapsedTime < 0.0f ) + fElapsedTime = 0.0f; + + *pfAbsoluteTime = qwTime.QuadPart / ( double )m_llQPFTicksPerSec; + *pfTime = ( qwTime.QuadPart - m_llBaseTime ) / ( double )m_llQPFTicksPerSec; + *pfElapsedTime = fElapsedTime; +} + + +//-------------------------------------------------------------------------------------- +float CDXUTTimer::GetElapsedTime() +{ + LARGE_INTEGER qwTime = GetAdjustedCurrentTime(); + + double fElapsedTime = (float) ((double) ( qwTime.QuadPart - m_llLastElapsedTime ) / (double) m_llQPFTicksPerSec); + m_llLastElapsedTime = qwTime.QuadPart; + + // See the explanation about clamping in CDXUTTimer::GetTimeValues() + if( fElapsedTime < 0.0f ) + fElapsedTime = 0.0f; + + return ( float )fElapsedTime; +} + + +//-------------------------------------------------------------------------------------- +// If stopped, returns time when stopped otherwise returns current time +//-------------------------------------------------------------------------------------- +LARGE_INTEGER CDXUTTimer::GetAdjustedCurrentTime() +{ + LARGE_INTEGER qwTime; + if( m_llStopTime != 0 ) + qwTime.QuadPart = m_llStopTime; + else + QueryPerformanceCounter( &qwTime ); + return qwTime; +} + +//-------------------------------------------------------------------------------------- +bool CDXUTTimer::IsStopped() +{ + return m_bTimerStopped; +} + +//-------------------------------------------------------------------------------------- +// Limit the current thread to one processor (the current one). This ensures that timing code +// runs on only one processor, and will not suffer any ill effects from power management. +// See "Game Timing and Multicore Processors" for more details +//-------------------------------------------------------------------------------------- +void CDXUTTimer::LimitThreadAffinityToCurrentProc() +{ + HANDLE hCurrentProcess = GetCurrentProcess(); + + // Get the processor affinity mask for this process + DWORD_PTR dwProcessAffinityMask = 0; + DWORD_PTR dwSystemAffinityMask = 0; + + if( GetProcessAffinityMask( hCurrentProcess, &dwProcessAffinityMask, &dwSystemAffinityMask ) != 0 && + dwProcessAffinityMask ) + { + // Find the lowest processor that our process is allows to run against + DWORD_PTR dwAffinityMask = ( dwProcessAffinityMask & ( ( ~dwProcessAffinityMask ) + 1 ) ); + + // Set this as the processor that our thread must always run against + // This must be a subset of the process affinity mask + HANDLE hCurrentThread = GetCurrentThread(); + if( INVALID_HANDLE_VALUE != hCurrentThread ) + { + SetThreadAffinityMask( hCurrentThread, dwAffinityMask ); + CloseHandle( hCurrentThread ); + } + } + + CloseHandle( hCurrentProcess ); +} + + +//-------------------------------------------------------------------------------------- +// Returns the string for the given D3DFORMAT. +//-------------------------------------------------------------------------------------- +LPCWSTR WINAPI DXUTD3DFormatToString( D3DFORMAT format, bool bWithPrefix ) +{ + WCHAR* pstr = NULL; + switch( format ) + { + case D3DFMT_UNKNOWN: + pstr = L"D3DFMT_UNKNOWN"; break; + case D3DFMT_R8G8B8: + pstr = L"D3DFMT_R8G8B8"; break; + case D3DFMT_A8R8G8B8: + pstr = L"D3DFMT_A8R8G8B8"; break; + case D3DFMT_X8R8G8B8: + pstr = L"D3DFMT_X8R8G8B8"; break; + case D3DFMT_R5G6B5: + pstr = L"D3DFMT_R5G6B5"; break; + case D3DFMT_X1R5G5B5: + pstr = L"D3DFMT_X1R5G5B5"; break; + case D3DFMT_A1R5G5B5: + pstr = L"D3DFMT_A1R5G5B5"; break; + case D3DFMT_A4R4G4B4: + pstr = L"D3DFMT_A4R4G4B4"; break; + case D3DFMT_R3G3B2: + pstr = L"D3DFMT_R3G3B2"; break; + case D3DFMT_A8: + pstr = L"D3DFMT_A8"; break; + case D3DFMT_A8R3G3B2: + pstr = L"D3DFMT_A8R3G3B2"; break; + case D3DFMT_X4R4G4B4: + pstr = L"D3DFMT_X4R4G4B4"; break; + case D3DFMT_A2B10G10R10: + pstr = L"D3DFMT_A2B10G10R10"; break; + case D3DFMT_A8B8G8R8: + pstr = L"D3DFMT_A8B8G8R8"; break; + case D3DFMT_X8B8G8R8: + pstr = L"D3DFMT_X8B8G8R8"; break; + case D3DFMT_G16R16: + pstr = L"D3DFMT_G16R16"; break; + case D3DFMT_A2R10G10B10: + pstr = L"D3DFMT_A2R10G10B10"; break; + case D3DFMT_A16B16G16R16: + pstr = L"D3DFMT_A16B16G16R16"; break; + case D3DFMT_A8P8: + pstr = L"D3DFMT_A8P8"; break; + case D3DFMT_P8: + pstr = L"D3DFMT_P8"; break; + case D3DFMT_L8: + pstr = L"D3DFMT_L8"; break; + case D3DFMT_A8L8: + pstr = L"D3DFMT_A8L8"; break; + case D3DFMT_A4L4: + pstr = L"D3DFMT_A4L4"; break; + case D3DFMT_V8U8: + pstr = L"D3DFMT_V8U8"; break; + case D3DFMT_L6V5U5: + pstr = L"D3DFMT_L6V5U5"; break; + case D3DFMT_X8L8V8U8: + pstr = L"D3DFMT_X8L8V8U8"; break; + case D3DFMT_Q8W8V8U8: + pstr = L"D3DFMT_Q8W8V8U8"; break; + case D3DFMT_V16U16: + pstr = L"D3DFMT_V16U16"; break; + case D3DFMT_A2W10V10U10: + pstr = L"D3DFMT_A2W10V10U10"; break; + case D3DFMT_UYVY: + pstr = L"D3DFMT_UYVY"; break; + case D3DFMT_YUY2: + pstr = L"D3DFMT_YUY2"; break; + case D3DFMT_DXT1: + pstr = L"D3DFMT_DXT1"; break; + case D3DFMT_DXT2: + pstr = L"D3DFMT_DXT2"; break; + case D3DFMT_DXT3: + pstr = L"D3DFMT_DXT3"; break; + case D3DFMT_DXT4: + pstr = L"D3DFMT_DXT4"; break; + case D3DFMT_DXT5: + pstr = L"D3DFMT_DXT5"; break; + case D3DFMT_D16_LOCKABLE: + pstr = L"D3DFMT_D16_LOCKABLE"; break; + case D3DFMT_D32: + pstr = L"D3DFMT_D32"; break; + case D3DFMT_D15S1: + pstr = L"D3DFMT_D15S1"; break; + case D3DFMT_D24S8: + pstr = L"D3DFMT_D24S8"; break; + case D3DFMT_D24X8: + pstr = L"D3DFMT_D24X8"; break; + case D3DFMT_D24X4S4: + pstr = L"D3DFMT_D24X4S4"; break; + case D3DFMT_D16: + pstr = L"D3DFMT_D16"; break; + case D3DFMT_L16: + pstr = L"D3DFMT_L16"; break; + case D3DFMT_VERTEXDATA: + pstr = L"D3DFMT_VERTEXDATA"; break; + case D3DFMT_INDEX16: + pstr = L"D3DFMT_INDEX16"; break; + case D3DFMT_INDEX32: + pstr = L"D3DFMT_INDEX32"; break; + case D3DFMT_Q16W16V16U16: + pstr = L"D3DFMT_Q16W16V16U16"; break; + case D3DFMT_MULTI2_ARGB8: + pstr = L"D3DFMT_MULTI2_ARGB8"; break; + case D3DFMT_R16F: + pstr = L"D3DFMT_R16F"; break; + case D3DFMT_G16R16F: + pstr = L"D3DFMT_G16R16F"; break; + case D3DFMT_A16B16G16R16F: + pstr = L"D3DFMT_A16B16G16R16F"; break; + case D3DFMT_R32F: + pstr = L"D3DFMT_R32F"; break; + case D3DFMT_G32R32F: + pstr = L"D3DFMT_G32R32F"; break; + case D3DFMT_A32B32G32R32F: + pstr = L"D3DFMT_A32B32G32R32F"; break; + case D3DFMT_CxV8U8: + pstr = L"D3DFMT_CxV8U8"; break; + default: + pstr = L"Unknown format"; break; + } + if( bWithPrefix || wcsstr( pstr, L"D3DFMT_" ) == NULL ) + return pstr; + else + return pstr + lstrlen( L"D3DFMT_" ); +} + + +//-------------------------------------------------------------------------------------- +// Returns the string for the given DXGI_FORMAT. +//-------------------------------------------------------------------------------------- +LPCWSTR WINAPI DXUTDXGIFormatToString( DXGI_FORMAT format, bool bWithPrefix ) +{ + WCHAR* pstr = NULL; + switch( format ) + { + case DXGI_FORMAT_R32G32B32A32_TYPELESS: + pstr = L"DXGI_FORMAT_R32G32B32A32_TYPELESS"; break; + case DXGI_FORMAT_R32G32B32A32_FLOAT: + pstr = L"DXGI_FORMAT_R32G32B32A32_FLOAT"; break; + case DXGI_FORMAT_R32G32B32A32_UINT: + pstr = L"DXGI_FORMAT_R32G32B32A32_UINT"; break; + case DXGI_FORMAT_R32G32B32A32_SINT: + pstr = L"DXGI_FORMAT_R32G32B32A32_SINT"; break; + case DXGI_FORMAT_R32G32B32_TYPELESS: + pstr = L"DXGI_FORMAT_R32G32B32_TYPELESS"; break; + case DXGI_FORMAT_R32G32B32_FLOAT: + pstr = L"DXGI_FORMAT_R32G32B32_FLOAT"; break; + case DXGI_FORMAT_R32G32B32_UINT: + pstr = L"DXGI_FORMAT_R32G32B32_UINT"; break; + case DXGI_FORMAT_R32G32B32_SINT: + pstr = L"DXGI_FORMAT_R32G32B32_SINT"; break; + case DXGI_FORMAT_R16G16B16A16_TYPELESS: + pstr = L"DXGI_FORMAT_R16G16B16A16_TYPELESS"; break; + case DXGI_FORMAT_R16G16B16A16_FLOAT: + pstr = L"DXGI_FORMAT_R16G16B16A16_FLOAT"; break; + case DXGI_FORMAT_R16G16B16A16_UNORM: + pstr = L"DXGI_FORMAT_R16G16B16A16_UNORM"; break; + case DXGI_FORMAT_R16G16B16A16_UINT: + pstr = L"DXGI_FORMAT_R16G16B16A16_UINT"; break; + case DXGI_FORMAT_R16G16B16A16_SNORM: + pstr = L"DXGI_FORMAT_R16G16B16A16_SNORM"; break; + case DXGI_FORMAT_R16G16B16A16_SINT: + pstr = L"DXGI_FORMAT_R16G16B16A16_SINT"; break; + case DXGI_FORMAT_R32G32_TYPELESS: + pstr = L"DXGI_FORMAT_R32G32_TYPELESS"; break; + case DXGI_FORMAT_R32G32_FLOAT: + pstr = L"DXGI_FORMAT_R32G32_FLOAT"; break; + case DXGI_FORMAT_R32G32_UINT: + pstr = L"DXGI_FORMAT_R32G32_UINT"; break; + case DXGI_FORMAT_R32G32_SINT: + pstr = L"DXGI_FORMAT_R32G32_SINT"; break; + case DXGI_FORMAT_R32G8X24_TYPELESS: + pstr = L"DXGI_FORMAT_R32G8X24_TYPELESS"; break; + case DXGI_FORMAT_D32_FLOAT_S8X24_UINT: + pstr = L"DXGI_FORMAT_D32_FLOAT_S8X24_UINT"; break; + case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS: + pstr = L"DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS"; break; + case DXGI_FORMAT_X32_TYPELESS_G8X24_UINT: + pstr = L"DXGI_FORMAT_X32_TYPELESS_G8X24_UINT"; break; + case DXGI_FORMAT_R10G10B10A2_TYPELESS: + pstr = L"DXGI_FORMAT_R10G10B10A2_TYPELESS"; break; + case DXGI_FORMAT_R10G10B10A2_UNORM: + pstr = L"DXGI_FORMAT_R10G10B10A2_UNORM"; break; + case DXGI_FORMAT_R10G10B10A2_UINT: + pstr = L"DXGI_FORMAT_R10G10B10A2_UINT"; break; + case DXGI_FORMAT_R11G11B10_FLOAT: + pstr = L"DXGI_FORMAT_R11G11B10_FLOAT"; break; + case DXGI_FORMAT_R8G8B8A8_TYPELESS: + pstr = L"DXGI_FORMAT_R8G8B8A8_TYPELESS"; break; + case DXGI_FORMAT_R8G8B8A8_UNORM: + pstr = L"DXGI_FORMAT_R8G8B8A8_UNORM"; break; + case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: + pstr = L"DXGI_FORMAT_R8G8B8A8_UNORM_SRGB"; break; + case DXGI_FORMAT_R8G8B8A8_UINT: + pstr = L"DXGI_FORMAT_R8G8B8A8_UINT"; break; + case DXGI_FORMAT_R8G8B8A8_SNORM: + pstr = L"DXGI_FORMAT_R8G8B8A8_SNORM"; break; + case DXGI_FORMAT_R8G8B8A8_SINT: + pstr = L"DXGI_FORMAT_R8G8B8A8_SINT"; break; + case DXGI_FORMAT_R16G16_TYPELESS: + pstr = L"DXGI_FORMAT_R16G16_TYPELESS"; break; + case DXGI_FORMAT_R16G16_FLOAT: + pstr = L"DXGI_FORMAT_R16G16_FLOAT"; break; + case DXGI_FORMAT_R16G16_UNORM: + pstr = L"DXGI_FORMAT_R16G16_UNORM"; break; + case DXGI_FORMAT_R16G16_UINT: + pstr = L"DXGI_FORMAT_R16G16_UINT"; break; + case DXGI_FORMAT_R16G16_SNORM: + pstr = L"DXGI_FORMAT_R16G16_SNORM"; break; + case DXGI_FORMAT_R16G16_SINT: + pstr = L"DXGI_FORMAT_R16G16_SINT"; break; + case DXGI_FORMAT_R32_TYPELESS: + pstr = L"DXGI_FORMAT_R32_TYPELESS"; break; + case DXGI_FORMAT_D32_FLOAT: + pstr = L"DXGI_FORMAT_D32_FLOAT"; break; + case DXGI_FORMAT_R32_FLOAT: + pstr = L"DXGI_FORMAT_R32_FLOAT"; break; + case DXGI_FORMAT_R32_UINT: + pstr = L"DXGI_FORMAT_R32_UINT"; break; + case DXGI_FORMAT_R32_SINT: + pstr = L"DXGI_FORMAT_R32_SINT"; break; + case DXGI_FORMAT_R24G8_TYPELESS: + pstr = L"DXGI_FORMAT_R24G8_TYPELESS"; break; + case DXGI_FORMAT_D24_UNORM_S8_UINT: + pstr = L"DXGI_FORMAT_D24_UNORM_S8_UINT"; break; + case DXGI_FORMAT_R24_UNORM_X8_TYPELESS: + pstr = L"DXGI_FORMAT_R24_UNORM_X8_TYPELESS"; break; + case DXGI_FORMAT_X24_TYPELESS_G8_UINT: + pstr = L"DXGI_FORMAT_X24_TYPELESS_G8_UINT"; break; + case DXGI_FORMAT_R8G8_TYPELESS: + pstr = L"DXGI_FORMAT_R8G8_TYPELESS"; break; + case DXGI_FORMAT_R8G8_UNORM: + pstr = L"DXGI_FORMAT_R8G8_UNORM"; break; + case DXGI_FORMAT_R8G8_UINT: + pstr = L"DXGI_FORMAT_R8G8_UINT"; break; + case DXGI_FORMAT_R8G8_SNORM: + pstr = L"DXGI_FORMAT_R8G8_SNORM"; break; + case DXGI_FORMAT_R8G8_SINT: + pstr = L"DXGI_FORMAT_R8G8_SINT"; break; + case DXGI_FORMAT_R16_TYPELESS: + pstr = L"DXGI_FORMAT_R16_TYPELESS"; break; + case DXGI_FORMAT_R16_FLOAT: + pstr = L"DXGI_FORMAT_R16_FLOAT"; break; + case DXGI_FORMAT_D16_UNORM: + pstr = L"DXGI_FORMAT_D16_UNORM"; break; + case DXGI_FORMAT_R16_UNORM: + pstr = L"DXGI_FORMAT_R16_UNORM"; break; + case DXGI_FORMAT_R16_UINT: + pstr = L"DXGI_FORMAT_R16_UINT"; break; + case DXGI_FORMAT_R16_SNORM: + pstr = L"DXGI_FORMAT_R16_SNORM"; break; + case DXGI_FORMAT_R16_SINT: + pstr = L"DXGI_FORMAT_R16_SINT"; break; + case DXGI_FORMAT_R8_TYPELESS: + pstr = L"DXGI_FORMAT_R8_TYPELESS"; break; + case DXGI_FORMAT_R8_UNORM: + pstr = L"DXGI_FORMAT_R8_UNORM"; break; + case DXGI_FORMAT_R8_UINT: + pstr = L"DXGI_FORMAT_R8_UINT"; break; + case DXGI_FORMAT_R8_SNORM: + pstr = L"DXGI_FORMAT_R8_SNORM"; break; + case DXGI_FORMAT_R8_SINT: + pstr = L"DXGI_FORMAT_R8_SINT"; break; + case DXGI_FORMAT_A8_UNORM: + pstr = L"DXGI_FORMAT_A8_UNORM"; break; + case DXGI_FORMAT_R1_UNORM: + pstr = L"DXGI_FORMAT_R1_UNORM"; break; + case DXGI_FORMAT_R9G9B9E5_SHAREDEXP: + pstr = L"DXGI_FORMAT_R9G9B9E5_SHAREDEXP"; break; + case DXGI_FORMAT_R8G8_B8G8_UNORM: + pstr = L"DXGI_FORMAT_R8G8_B8G8_UNORM"; break; + case DXGI_FORMAT_G8R8_G8B8_UNORM: + pstr = L"DXGI_FORMAT_G8R8_G8B8_UNORM"; break; + case DXGI_FORMAT_BC1_TYPELESS: + pstr = L"DXGI_FORMAT_BC1_TYPELESS"; break; + case DXGI_FORMAT_BC1_UNORM: + pstr = L"DXGI_FORMAT_BC1_UNORM"; break; + case DXGI_FORMAT_BC1_UNORM_SRGB: + pstr = L"DXGI_FORMAT_BC1_UNORM_SRGB"; break; + case DXGI_FORMAT_BC2_TYPELESS: + pstr = L"DXGI_FORMAT_BC2_TYPELESS"; break; + case DXGI_FORMAT_BC2_UNORM: + pstr = L"DXGI_FORMAT_BC2_UNORM"; break; + case DXGI_FORMAT_BC2_UNORM_SRGB: + pstr = L"DXGI_FORMAT_BC2_UNORM_SRGB"; break; + case DXGI_FORMAT_BC3_TYPELESS: + pstr = L"DXGI_FORMAT_BC3_TYPELESS"; break; + case DXGI_FORMAT_BC3_UNORM: + pstr = L"DXGI_FORMAT_BC3_UNORM"; break; + case DXGI_FORMAT_BC3_UNORM_SRGB: + pstr = L"DXGI_FORMAT_BC3_UNORM_SRGB"; break; + case DXGI_FORMAT_BC4_TYPELESS: + pstr = L"DXGI_FORMAT_BC4_TYPELESS"; break; + case DXGI_FORMAT_BC4_UNORM: + pstr = L"DXGI_FORMAT_BC4_UNORM"; break; + case DXGI_FORMAT_BC4_SNORM: + pstr = L"DXGI_FORMAT_BC4_SNORM"; break; + case DXGI_FORMAT_BC5_TYPELESS: + pstr = L"DXGI_FORMAT_BC5_TYPELESS"; break; + case DXGI_FORMAT_BC5_UNORM: + pstr = L"DXGI_FORMAT_BC5_UNORM"; break; + case DXGI_FORMAT_BC5_SNORM: + pstr = L"DXGI_FORMAT_BC5_SNORM"; break; + case DXGI_FORMAT_B5G6R5_UNORM: + pstr = L"DXGI_FORMAT_B5G6R5_UNORM"; break; + case DXGI_FORMAT_B5G5R5A1_UNORM: + pstr = L"DXGI_FORMAT_B5G5R5A1_UNORM"; break; + case DXGI_FORMAT_B8G8R8A8_UNORM: + pstr = L"DXGI_FORMAT_B8G8R8A8_UNORM"; break; + default: + pstr = L"Unknown format"; break; + } + if( bWithPrefix || wcsstr( pstr, L"DXGI_FORMAT_" ) == NULL ) + return pstr; + else + return pstr + lstrlen( L"DXGI_FORMAT_" ); +} + + +//-------------------------------------------------------------------------------------- +// Outputs to the debug stream a formatted Unicode string with a variable-argument list. +//-------------------------------------------------------------------------------------- +VOID WINAPI DXUTOutputDebugStringW( LPCWSTR strMsg, ... ) +{ +#if defined(DEBUG) || defined(_DEBUG) + WCHAR strBuffer[512]; + + va_list args; + va_start(args, strMsg); + vswprintf_s( strBuffer, 512, strMsg, args ); + strBuffer[511] = L'\0'; + va_end(args); + + OutputDebugString( strBuffer ); +#else + UNREFERENCED_PARAMETER( strMsg ); +#endif +} + + +//-------------------------------------------------------------------------------------- +// Outputs to the debug stream a formatted MBCS string with a variable-argument list. +//-------------------------------------------------------------------------------------- +VOID WINAPI DXUTOutputDebugStringA( LPCSTR strMsg, ... ) +{ +#if defined(DEBUG) || defined(_DEBUG) + CHAR strBuffer[512]; + + va_list args; + va_start(args, strMsg); + sprintf_s( strBuffer, 512, strMsg, args ); + strBuffer[511] = '\0'; + va_end(args); + + OutputDebugStringA( strBuffer ); +#else + UNREFERENCED_PARAMETER( strMsg ); +#endif +} + + +//-------------------------------------------------------------------------------------- +// Direct3D9 dynamic linking support -- calls top-level D3D9 APIs with graceful +// failure if APIs are not present. +//-------------------------------------------------------------------------------------- + +// Function prototypes +typedef IDirect3D9* (WINAPI * LPDIRECT3DCREATE9) (UINT); +typedef INT (WINAPI * LPD3DPERF_BEGINEVENT)(D3DCOLOR, LPCWSTR); +typedef INT (WINAPI * LPD3DPERF_ENDEVENT)(void); +typedef VOID (WINAPI * LPD3DPERF_SETMARKER)(D3DCOLOR, LPCWSTR); +typedef VOID (WINAPI * LPD3DPERF_SETREGION)(D3DCOLOR, LPCWSTR); +typedef BOOL (WINAPI * LPD3DPERF_QUERYREPEATFRAME)(void); +typedef VOID (WINAPI * LPD3DPERF_SETOPTIONS)( DWORD dwOptions ); +typedef DWORD (WINAPI * LPD3DPERF_GETSTATUS)( void ); +typedef HRESULT (WINAPI * LPCREATEDXGIFACTORY)(REFIID, void ** ); +typedef HRESULT (WINAPI * LPD3D11CREATEDEVICE)( IDXGIAdapter*, D3D_DRIVER_TYPE, HMODULE, UINT32, D3D_FEATURE_LEVEL*, UINT, UINT32, ID3D11Device**, D3D_FEATURE_LEVEL*, ID3D11DeviceContext** ); + +// Module and function pointers +static HMODULE s_hModD3D9 = NULL; +static LPDIRECT3DCREATE9 s_DynamicDirect3DCreate9 = NULL; +static LPD3DPERF_BEGINEVENT s_DynamicD3DPERF_BeginEvent = NULL; +static LPD3DPERF_ENDEVENT s_DynamicD3DPERF_EndEvent = NULL; +static LPD3DPERF_SETMARKER s_DynamicD3DPERF_SetMarker = NULL; +static LPD3DPERF_SETREGION s_DynamicD3DPERF_SetRegion = NULL; +static LPD3DPERF_QUERYREPEATFRAME s_DynamicD3DPERF_QueryRepeatFrame = NULL; +static LPD3DPERF_SETOPTIONS s_DynamicD3DPERF_SetOptions = NULL; +static LPD3DPERF_GETSTATUS s_DynamicD3DPERF_GetStatus = NULL; +static HMODULE s_hModDXGI = NULL; +static LPCREATEDXGIFACTORY s_DynamicCreateDXGIFactory = NULL; +static HMODULE s_hModD3D11 = NULL; +static LPD3D11CREATEDEVICE s_DynamicD3D11CreateDevice = NULL; + +// Ensure function pointers are initialized +static bool DXUT_EnsureD3D9APIs( void ) +{ + // If the module is non-NULL, this function has already been called. Note + // that this doesn't guarantee that all ProcAddresses were found. + if( s_hModD3D9 != NULL ) + return true; + + // This may fail if Direct3D 9 isn't installed + s_hModD3D9 = LoadLibrary( L"d3d9.dll" ); + if( s_hModD3D9 != NULL ) + { + s_DynamicDirect3DCreate9 = (LPDIRECT3DCREATE9)GetProcAddress( s_hModD3D9, "Direct3DCreate9" ); + s_DynamicD3DPERF_BeginEvent = (LPD3DPERF_BEGINEVENT)GetProcAddress( s_hModD3D9, "D3DPERF_BeginEvent" ); + s_DynamicD3DPERF_EndEvent = (LPD3DPERF_ENDEVENT)GetProcAddress( s_hModD3D9, "D3DPERF_EndEvent" ); + s_DynamicD3DPERF_SetMarker = (LPD3DPERF_SETMARKER)GetProcAddress( s_hModD3D9, "D3DPERF_SetMarker" ); + s_DynamicD3DPERF_SetRegion = (LPD3DPERF_SETREGION)GetProcAddress( s_hModD3D9, "D3DPERF_SetRegion" ); + s_DynamicD3DPERF_QueryRepeatFrame = (LPD3DPERF_QUERYREPEATFRAME)GetProcAddress( s_hModD3D9, "D3DPERF_QueryRepeatFrame" ); + s_DynamicD3DPERF_SetOptions = (LPD3DPERF_SETOPTIONS)GetProcAddress( s_hModD3D9, "D3DPERF_SetOptions" ); + s_DynamicD3DPERF_GetStatus = (LPD3DPERF_GETSTATUS)GetProcAddress( s_hModD3D9, "D3DPERF_GetStatus" ); + } + + return s_hModD3D9 != NULL; +} + +bool DXUT_EnsureD3D11APIs( void ) +{ + // If both modules are non-NULL, this function has already been called. Note + // that this doesn't guarantee that all ProcAddresses were found. + if( s_hModD3D11 != NULL && s_hModDXGI != NULL ) + return true; + + // This may fail if Direct3D 11 isn't installed + s_hModD3D11 = LoadLibrary( L"d3d11.dll" ); + if( s_hModD3D11 != NULL ) + { + s_DynamicD3D11CreateDevice = ( LPD3D11CREATEDEVICE )GetProcAddress( s_hModD3D11, "D3D11CreateDevice" ); + } + + if( !s_DynamicCreateDXGIFactory ) + { + s_hModDXGI = LoadLibrary( L"dxgi.dll" ); + if( s_hModDXGI ) + { + s_DynamicCreateDXGIFactory = ( LPCREATEDXGIFACTORY )GetProcAddress( s_hModDXGI, "CreateDXGIFactory1" ); + } + + return ( s_hModDXGI != NULL ) && ( s_hModD3D11 != NULL ); + } + + return ( s_hModD3D11 != NULL ); +} + +IDirect3D9* WINAPI DXUT_Dynamic_Direct3DCreate9( UINT SDKVersion ) +{ + if( DXUT_EnsureD3D9APIs() && s_DynamicDirect3DCreate9 != NULL ) + return s_DynamicDirect3DCreate9( SDKVersion ); + else + return NULL; +} + +int WINAPI DXUT_Dynamic_D3DPERF_BeginEvent( D3DCOLOR col, LPCWSTR wszName ) +{ + if( DXUT_EnsureD3D9APIs() && s_DynamicD3DPERF_BeginEvent != NULL ) + return s_DynamicD3DPERF_BeginEvent( col, wszName ); + else + return -1; +} + +int WINAPI DXUT_Dynamic_D3DPERF_EndEvent( void ) +{ + if( DXUT_EnsureD3D9APIs() && s_DynamicD3DPERF_EndEvent != NULL ) + return s_DynamicD3DPERF_EndEvent(); + else + return -1; +} + +void WINAPI DXUT_Dynamic_D3DPERF_SetMarker( D3DCOLOR col, LPCWSTR wszName ) +{ + if( DXUT_EnsureD3D9APIs() && s_DynamicD3DPERF_SetMarker != NULL ) + s_DynamicD3DPERF_SetMarker( col, wszName ); +} + +void WINAPI DXUT_Dynamic_D3DPERF_SetRegion( D3DCOLOR col, LPCWSTR wszName ) +{ + if( DXUT_EnsureD3D9APIs() && s_DynamicD3DPERF_SetRegion != NULL ) + s_DynamicD3DPERF_SetRegion( col, wszName ); +} + +BOOL WINAPI DXUT_Dynamic_D3DPERF_QueryRepeatFrame( void ) +{ + if( DXUT_EnsureD3D9APIs() && s_DynamicD3DPERF_QueryRepeatFrame != NULL ) + return s_DynamicD3DPERF_QueryRepeatFrame(); + else + return FALSE; +} + +void WINAPI DXUT_Dynamic_D3DPERF_SetOptions( DWORD dwOptions ) +{ + if( DXUT_EnsureD3D9APIs() && s_DynamicD3DPERF_SetOptions != NULL ) + s_DynamicD3DPERF_SetOptions( dwOptions ); +} + +DWORD WINAPI DXUT_Dynamic_D3DPERF_GetStatus( void ) +{ + if( DXUT_EnsureD3D9APIs() && s_DynamicD3DPERF_GetStatus != NULL ) + return s_DynamicD3DPERF_GetStatus(); + else + return 0; +} + +HRESULT WINAPI DXUT_Dynamic_CreateDXGIFactory1( REFIID rInterface, void** ppOut ) +{ + if( DXUT_EnsureD3D11APIs() && s_DynamicCreateDXGIFactory != NULL ) + return s_DynamicCreateDXGIFactory( rInterface, ppOut ); + else + return DXUTERR_NODIRECT3D11; +} + + + +HRESULT WINAPI DXUT_Dynamic_D3D11CreateDevice( IDXGIAdapter* pAdapter, + D3D_DRIVER_TYPE DriverType, + HMODULE Software, + UINT32 Flags, + D3D_FEATURE_LEVEL* pFeatureLevels, + UINT FeatureLevels, + UINT32 SDKVersion, + ID3D11Device** ppDevice, + D3D_FEATURE_LEVEL* pFeatureLevel, + ID3D11DeviceContext** ppImmediateContext ) +{ + if( DXUT_EnsureD3D11APIs() && s_DynamicD3D11CreateDevice != NULL ) + return s_DynamicD3D11CreateDevice( pAdapter, DriverType, Software, Flags, pFeatureLevels, FeatureLevels, + SDKVersion, ppDevice, pFeatureLevel, ppImmediateContext ); + else + return DXUTERR_NODIRECT3D11; +} + +//-------------------------------------------------------------------------------------- +// Trace a string description of a decl +//-------------------------------------------------------------------------------------- +void WINAPI DXUTTraceDecl( D3DVERTEXELEMENT9 decl[MAX_FVF_DECL_SIZE] ) +{ + int iDecl = 0; + for( iDecl = 0; iDecl < MAX_FVF_DECL_SIZE; iDecl++ ) + { + if( decl[iDecl].Stream == 0xFF ) + break; + + DXUTOutputDebugString( L"decl[%d]=Stream:%d, Offset:%d, %s, %s, %s, UsageIndex:%d\n", iDecl, + decl[iDecl].Stream, + decl[iDecl].Offset, + DXUTTraceD3DDECLTYPEtoString( decl[iDecl].Type ), + DXUTTraceD3DDECLMETHODtoString( decl[iDecl].Method ), + DXUTTraceD3DDECLUSAGEtoString( decl[iDecl].Usage ), + decl[iDecl].UsageIndex ); + } + + DXUTOutputDebugString( L"decl[%d]=D3DDECL_END\n", iDecl ); +} + +#define TRACE_ID(iD) case iD: return L#iD; + +//-------------------------------------------------------------------------------------- +WCHAR* WINAPI DXUTTraceWindowsMessage( UINT uMsg ) +{ + switch( uMsg ) + { + TRACE_ID(WM_NULL); + TRACE_ID(WM_CREATE); + TRACE_ID(WM_DESTROY); + TRACE_ID(WM_MOVE); + TRACE_ID(WM_SIZE); + TRACE_ID(WM_ACTIVATE); + TRACE_ID(WM_SETFOCUS); + TRACE_ID(WM_KILLFOCUS); + TRACE_ID(WM_ENABLE); + TRACE_ID(WM_SETREDRAW); + TRACE_ID(WM_SETTEXT); + TRACE_ID(WM_GETTEXT); + TRACE_ID(WM_GETTEXTLENGTH); + TRACE_ID(WM_PAINT); + TRACE_ID(WM_CLOSE); + TRACE_ID(WM_QUERYENDSESSION); + TRACE_ID(WM_QUERYOPEN); + TRACE_ID(WM_ENDSESSION); + TRACE_ID(WM_QUIT); + TRACE_ID(WM_ERASEBKGND); + TRACE_ID(WM_SYSCOLORCHANGE); + TRACE_ID(WM_SHOWWINDOW); + TRACE_ID(WM_WININICHANGE); + TRACE_ID(WM_DEVMODECHANGE); + TRACE_ID(WM_ACTIVATEAPP); + TRACE_ID(WM_FONTCHANGE); + TRACE_ID(WM_TIMECHANGE); + TRACE_ID(WM_CANCELMODE); + TRACE_ID(WM_SETCURSOR); + TRACE_ID(WM_MOUSEACTIVATE); + TRACE_ID(WM_CHILDACTIVATE); + TRACE_ID(WM_QUEUESYNC); + TRACE_ID(WM_GETMINMAXINFO); + TRACE_ID(WM_PAINTICON); + TRACE_ID(WM_ICONERASEBKGND); + TRACE_ID(WM_NEXTDLGCTL); + TRACE_ID(WM_SPOOLERSTATUS); + TRACE_ID(WM_DRAWITEM); + TRACE_ID(WM_MEASUREITEM); + TRACE_ID(WM_DELETEITEM); + TRACE_ID(WM_VKEYTOITEM); + TRACE_ID(WM_CHARTOITEM); + TRACE_ID(WM_SETFONT); + TRACE_ID(WM_GETFONT); + TRACE_ID(WM_SETHOTKEY); + TRACE_ID(WM_GETHOTKEY); + TRACE_ID(WM_QUERYDRAGICON); + TRACE_ID(WM_COMPAREITEM); + TRACE_ID(WM_GETOBJECT); + TRACE_ID(WM_COMPACTING); + TRACE_ID(WM_COMMNOTIFY); + TRACE_ID(WM_WINDOWPOSCHANGING); + TRACE_ID(WM_WINDOWPOSCHANGED); + TRACE_ID(WM_POWER); + TRACE_ID(WM_COPYDATA); + TRACE_ID(WM_CANCELJOURNAL); + TRACE_ID(WM_NOTIFY); + TRACE_ID(WM_INPUTLANGCHANGEREQUEST); + TRACE_ID(WM_INPUTLANGCHANGE); + TRACE_ID(WM_TCARD); + TRACE_ID(WM_HELP); + TRACE_ID(WM_USERCHANGED); + TRACE_ID(WM_NOTIFYFORMAT); + TRACE_ID(WM_CONTEXTMENU); + TRACE_ID(WM_STYLECHANGING); + TRACE_ID(WM_STYLECHANGED); + TRACE_ID(WM_DISPLAYCHANGE); + TRACE_ID(WM_GETICON); + TRACE_ID(WM_SETICON); + TRACE_ID(WM_NCCREATE); + TRACE_ID(WM_NCDESTROY); + TRACE_ID(WM_NCCALCSIZE); + TRACE_ID(WM_NCHITTEST); + TRACE_ID(WM_NCPAINT); + TRACE_ID(WM_NCACTIVATE); + TRACE_ID(WM_GETDLGCODE); + TRACE_ID(WM_SYNCPAINT); + TRACE_ID(WM_NCMOUSEMOVE); + TRACE_ID(WM_NCLBUTTONDOWN); + TRACE_ID(WM_NCLBUTTONUP); + TRACE_ID(WM_NCLBUTTONDBLCLK); + TRACE_ID(WM_NCRBUTTONDOWN); + TRACE_ID(WM_NCRBUTTONUP); + TRACE_ID(WM_NCRBUTTONDBLCLK); + TRACE_ID(WM_NCMBUTTONDOWN); + TRACE_ID(WM_NCMBUTTONUP); + TRACE_ID(WM_NCMBUTTONDBLCLK); + TRACE_ID(WM_NCXBUTTONDOWN); + TRACE_ID(WM_NCXBUTTONUP); + TRACE_ID(WM_NCXBUTTONDBLCLK); + TRACE_ID(WM_INPUT); + TRACE_ID(WM_KEYDOWN); + TRACE_ID(WM_KEYUP); + TRACE_ID(WM_CHAR); + TRACE_ID(WM_DEADCHAR); + TRACE_ID(WM_SYSKEYDOWN); + TRACE_ID(WM_SYSKEYUP); + TRACE_ID(WM_SYSCHAR); + TRACE_ID(WM_SYSDEADCHAR); + TRACE_ID(WM_UNICHAR); + TRACE_ID(WM_IME_STARTCOMPOSITION); + TRACE_ID(WM_IME_ENDCOMPOSITION); + TRACE_ID(WM_IME_COMPOSITION); + TRACE_ID(WM_INITDIALOG); + TRACE_ID(WM_COMMAND); + TRACE_ID(WM_SYSCOMMAND); + TRACE_ID(WM_TIMER); + TRACE_ID(WM_HSCROLL); + TRACE_ID(WM_VSCROLL); + TRACE_ID(WM_INITMENU); + TRACE_ID(WM_INITMENUPOPUP); + TRACE_ID(WM_MENUSELECT); + TRACE_ID(WM_MENUCHAR); + TRACE_ID(WM_ENTERIDLE); + TRACE_ID(WM_MENURBUTTONUP); + TRACE_ID(WM_MENUDRAG); + TRACE_ID(WM_MENUGETOBJECT); + TRACE_ID(WM_UNINITMENUPOPUP); + TRACE_ID(WM_MENUCOMMAND); + TRACE_ID(WM_CHANGEUISTATE); + TRACE_ID(WM_UPDATEUISTATE); + TRACE_ID(WM_QUERYUISTATE); + TRACE_ID(WM_CTLCOLORMSGBOX); + TRACE_ID(WM_CTLCOLOREDIT); + TRACE_ID(WM_CTLCOLORLISTBOX); + TRACE_ID(WM_CTLCOLORBTN); + TRACE_ID(WM_CTLCOLORDLG); + TRACE_ID(WM_CTLCOLORSCROLLBAR); + TRACE_ID(WM_CTLCOLORSTATIC); + TRACE_ID(MN_GETHMENU); + TRACE_ID(WM_MOUSEMOVE); + TRACE_ID(WM_LBUTTONDOWN); + TRACE_ID(WM_LBUTTONUP); + TRACE_ID(WM_LBUTTONDBLCLK); + TRACE_ID(WM_RBUTTONDOWN); + TRACE_ID(WM_RBUTTONUP); + TRACE_ID(WM_RBUTTONDBLCLK); + TRACE_ID(WM_MBUTTONDOWN); + TRACE_ID(WM_MBUTTONUP); + TRACE_ID(WM_MBUTTONDBLCLK); + TRACE_ID(WM_MOUSEWHEEL); + TRACE_ID(WM_XBUTTONDOWN); + TRACE_ID(WM_XBUTTONUP); + TRACE_ID(WM_XBUTTONDBLCLK); + TRACE_ID(WM_PARENTNOTIFY); + TRACE_ID(WM_ENTERMENULOOP); + TRACE_ID(WM_EXITMENULOOP); + TRACE_ID(WM_NEXTMENU); + TRACE_ID(WM_SIZING); + TRACE_ID(WM_CAPTURECHANGED); + TRACE_ID(WM_MOVING); + TRACE_ID(WM_POWERBROADCAST); + TRACE_ID(WM_DEVICECHANGE); + TRACE_ID(WM_MDICREATE); + TRACE_ID(WM_MDIDESTROY); + TRACE_ID(WM_MDIACTIVATE); + TRACE_ID(WM_MDIRESTORE); + TRACE_ID(WM_MDINEXT); + TRACE_ID(WM_MDIMAXIMIZE); + TRACE_ID(WM_MDITILE); + TRACE_ID(WM_MDICASCADE); + TRACE_ID(WM_MDIICONARRANGE); + TRACE_ID(WM_MDIGETACTIVE); + TRACE_ID(WM_MDISETMENU); + TRACE_ID(WM_ENTERSIZEMOVE); + TRACE_ID(WM_EXITSIZEMOVE); + TRACE_ID(WM_DROPFILES); + TRACE_ID(WM_MDIREFRESHMENU); + TRACE_ID(WM_IME_SETCONTEXT); + TRACE_ID(WM_IME_NOTIFY); + TRACE_ID(WM_IME_CONTROL); + TRACE_ID(WM_IME_COMPOSITIONFULL); + TRACE_ID(WM_IME_SELECT); + TRACE_ID(WM_IME_CHAR); + TRACE_ID(WM_IME_REQUEST); + TRACE_ID(WM_IME_KEYDOWN); + TRACE_ID(WM_IME_KEYUP); + TRACE_ID(WM_MOUSEHOVER); + TRACE_ID(WM_MOUSELEAVE); + TRACE_ID(WM_NCMOUSEHOVER); + TRACE_ID(WM_NCMOUSELEAVE); + TRACE_ID(WM_WTSSESSION_CHANGE); + TRACE_ID(WM_TABLET_FIRST); + TRACE_ID(WM_TABLET_LAST); + TRACE_ID(WM_CUT); + TRACE_ID(WM_COPY); + TRACE_ID(WM_PASTE); + TRACE_ID(WM_CLEAR); + TRACE_ID(WM_UNDO); + TRACE_ID(WM_RENDERFORMAT); + TRACE_ID(WM_RENDERALLFORMATS); + TRACE_ID(WM_DESTROYCLIPBOARD); + TRACE_ID(WM_DRAWCLIPBOARD); + TRACE_ID(WM_PAINTCLIPBOARD); + TRACE_ID(WM_VSCROLLCLIPBOARD); + TRACE_ID(WM_SIZECLIPBOARD); + TRACE_ID(WM_ASKCBFORMATNAME); + TRACE_ID(WM_CHANGECBCHAIN); + TRACE_ID(WM_HSCROLLCLIPBOARD); + TRACE_ID(WM_QUERYNEWPALETTE); + TRACE_ID(WM_PALETTEISCHANGING); + TRACE_ID(WM_PALETTECHANGED); + TRACE_ID(WM_HOTKEY); + TRACE_ID(WM_PRINT); + TRACE_ID(WM_PRINTCLIENT); + TRACE_ID(WM_APPCOMMAND); + TRACE_ID(WM_THEMECHANGED); + TRACE_ID(WM_HANDHELDFIRST); + TRACE_ID(WM_HANDHELDLAST); + TRACE_ID(WM_AFXFIRST); + TRACE_ID(WM_AFXLAST); + TRACE_ID(WM_PENWINFIRST); + TRACE_ID(WM_PENWINLAST); + TRACE_ID(WM_APP); + default: + return L"Unknown"; + } +} + + +//-------------------------------------------------------------------------------------- +WCHAR* WINAPI DXUTTraceD3DDECLTYPEtoString( BYTE t ) +{ + switch( t ) + { + case D3DDECLTYPE_FLOAT1: + return L"D3DDECLTYPE_FLOAT1"; + case D3DDECLTYPE_FLOAT2: + return L"D3DDECLTYPE_FLOAT2"; + case D3DDECLTYPE_FLOAT3: + return L"D3DDECLTYPE_FLOAT3"; + case D3DDECLTYPE_FLOAT4: + return L"D3DDECLTYPE_FLOAT4"; + case D3DDECLTYPE_D3DCOLOR: + return L"D3DDECLTYPE_D3DCOLOR"; + case D3DDECLTYPE_UBYTE4: + return L"D3DDECLTYPE_UBYTE4"; + case D3DDECLTYPE_SHORT2: + return L"D3DDECLTYPE_SHORT2"; + case D3DDECLTYPE_SHORT4: + return L"D3DDECLTYPE_SHORT4"; + case D3DDECLTYPE_UBYTE4N: + return L"D3DDECLTYPE_UBYTE4N"; + case D3DDECLTYPE_SHORT2N: + return L"D3DDECLTYPE_SHORT2N"; + case D3DDECLTYPE_SHORT4N: + return L"D3DDECLTYPE_SHORT4N"; + case D3DDECLTYPE_USHORT2N: + return L"D3DDECLTYPE_USHORT2N"; + case D3DDECLTYPE_USHORT4N: + return L"D3DDECLTYPE_USHORT4N"; + case D3DDECLTYPE_UDEC3: + return L"D3DDECLTYPE_UDEC3"; + case D3DDECLTYPE_DEC3N: + return L"D3DDECLTYPE_DEC3N"; + case D3DDECLTYPE_FLOAT16_2: + return L"D3DDECLTYPE_FLOAT16_2"; + case D3DDECLTYPE_FLOAT16_4: + return L"D3DDECLTYPE_FLOAT16_4"; + case D3DDECLTYPE_UNUSED: + return L"D3DDECLTYPE_UNUSED"; + default: + return L"D3DDECLTYPE Unknown"; + } +} + +WCHAR* WINAPI DXUTTraceD3DDECLMETHODtoString( BYTE m ) +{ + switch( m ) + { + case D3DDECLMETHOD_DEFAULT: + return L"D3DDECLMETHOD_DEFAULT"; + case D3DDECLMETHOD_PARTIALU: + return L"D3DDECLMETHOD_PARTIALU"; + case D3DDECLMETHOD_PARTIALV: + return L"D3DDECLMETHOD_PARTIALV"; + case D3DDECLMETHOD_CROSSUV: + return L"D3DDECLMETHOD_CROSSUV"; + case D3DDECLMETHOD_UV: + return L"D3DDECLMETHOD_UV"; + case D3DDECLMETHOD_LOOKUP: + return L"D3DDECLMETHOD_LOOKUP"; + case D3DDECLMETHOD_LOOKUPPRESAMPLED: + return L"D3DDECLMETHOD_LOOKUPPRESAMPLED"; + default: + return L"D3DDECLMETHOD Unknown"; + } +} + +WCHAR* WINAPI DXUTTraceD3DDECLUSAGEtoString( BYTE u ) +{ + switch( u ) + { + case D3DDECLUSAGE_POSITION: + return L"D3DDECLUSAGE_POSITION"; + case D3DDECLUSAGE_BLENDWEIGHT: + return L"D3DDECLUSAGE_BLENDWEIGHT"; + case D3DDECLUSAGE_BLENDINDICES: + return L"D3DDECLUSAGE_BLENDINDICES"; + case D3DDECLUSAGE_NORMAL: + return L"D3DDECLUSAGE_NORMAL"; + case D3DDECLUSAGE_PSIZE: + return L"D3DDECLUSAGE_PSIZE"; + case D3DDECLUSAGE_TEXCOORD: + return L"D3DDECLUSAGE_TEXCOORD"; + case D3DDECLUSAGE_TANGENT: + return L"D3DDECLUSAGE_TANGENT"; + case D3DDECLUSAGE_BINORMAL: + return L"D3DDECLUSAGE_BINORMAL"; + case D3DDECLUSAGE_TESSFACTOR: + return L"D3DDECLUSAGE_TESSFACTOR"; + case D3DDECLUSAGE_POSITIONT: + return L"D3DDECLUSAGE_POSITIONT"; + case D3DDECLUSAGE_COLOR: + return L"D3DDECLUSAGE_COLOR"; + case D3DDECLUSAGE_FOG: + return L"D3DDECLUSAGE_FOG"; + case D3DDECLUSAGE_DEPTH: + return L"D3DDECLUSAGE_DEPTH"; + case D3DDECLUSAGE_SAMPLE: + return L"D3DDECLUSAGE_SAMPLE"; + default: + return L"D3DDECLUSAGE Unknown"; + } +} + + +//-------------------------------------------------------------------------------------- +// Multimon API handling for OSes with or without multimon API support +//-------------------------------------------------------------------------------------- +#define DXUT_PRIMARY_MONITOR ((HMONITOR)0x12340042) +typedef HMONITOR ( WINAPI* LPMONITORFROMWINDOW )( HWND, DWORD ); +typedef BOOL ( WINAPI* LPGETMONITORINFO )( HMONITOR, LPMONITORINFO ); +typedef HMONITOR ( WINAPI* LPMONITORFROMRECT )( LPCRECT lprcScreenCoords, DWORD dwFlags ); + +BOOL WINAPI DXUTGetMonitorInfo( HMONITOR hMonitor, LPMONITORINFO lpMonitorInfo ) +{ + static bool s_bInited = false; + static LPGETMONITORINFO s_pFnGetMonitorInfo = NULL; + if( !s_bInited ) + { + s_bInited = true; + HMODULE hUser32 = GetModuleHandle( L"USER32" ); + if( hUser32 ) + { + OSVERSIONINFOA osvi = + { + 0 + }; osvi.dwOSVersionInfoSize = sizeof( osvi ); GetVersionExA( ( OSVERSIONINFOA* )&osvi ); + bool bNT = ( VER_PLATFORM_WIN32_NT == osvi.dwPlatformId ); + s_pFnGetMonitorInfo = ( LPGETMONITORINFO )( bNT ? GetProcAddress( hUser32, + "GetMonitorInfoW" ) : + GetProcAddress( hUser32, "GetMonitorInfoA" ) ); + } + } + + if( s_pFnGetMonitorInfo ) + return s_pFnGetMonitorInfo( hMonitor, lpMonitorInfo ); + + RECT rcWork; + if( ( hMonitor == DXUT_PRIMARY_MONITOR ) && lpMonitorInfo && ( lpMonitorInfo->cbSize >= sizeof( MONITORINFO ) ) && + SystemParametersInfoA( SPI_GETWORKAREA, 0, &rcWork, 0 ) ) + { + lpMonitorInfo->rcMonitor.left = 0; + lpMonitorInfo->rcMonitor.top = 0; + lpMonitorInfo->rcMonitor.right = GetSystemMetrics( SM_CXSCREEN ); + lpMonitorInfo->rcMonitor.bottom = GetSystemMetrics( SM_CYSCREEN ); + lpMonitorInfo->rcWork = rcWork; + lpMonitorInfo->dwFlags = MONITORINFOF_PRIMARY; + return TRUE; + } + return FALSE; +} + + +HMONITOR WINAPI DXUTMonitorFromWindow( HWND hWnd, DWORD dwFlags ) +{ + static bool s_bInited = false; + static LPMONITORFROMWINDOW s_pFnGetMonitorFromWindow = NULL; + if( !s_bInited ) + { + s_bInited = true; + HMODULE hUser32 = GetModuleHandle( L"USER32" ); + if( hUser32 ) s_pFnGetMonitorFromWindow = ( LPMONITORFROMWINDOW )GetProcAddress( hUser32, + "MonitorFromWindow" ); + } + + if( s_pFnGetMonitorFromWindow ) + return s_pFnGetMonitorFromWindow( hWnd, dwFlags ); + else + return DXUT_PRIMARY_MONITOR; +} + + +HMONITOR WINAPI DXUTMonitorFromRect( LPCRECT lprcScreenCoords, DWORD dwFlags ) +{ + static bool s_bInited = false; + static LPMONITORFROMRECT s_pFnGetMonitorFromRect = NULL; + if( !s_bInited ) + { + s_bInited = true; + HMODULE hUser32 = GetModuleHandle( L"USER32" ); + if( hUser32 ) s_pFnGetMonitorFromRect = ( LPMONITORFROMRECT )GetProcAddress( hUser32, "MonitorFromRect" ); + } + + if( s_pFnGetMonitorFromRect ) + return s_pFnGetMonitorFromRect( lprcScreenCoords, dwFlags ); + else + return DXUT_PRIMARY_MONITOR; +} + + +//-------------------------------------------------------------------------------------- +// Get the desktop resolution of an adapter. This isn't the same as the current resolution +// from GetAdapterDisplayMode since the device might be fullscreen +//-------------------------------------------------------------------------------------- +void WINAPI DXUTGetDesktopResolution( UINT AdapterOrdinal, UINT* pWidth, UINT* pHeight ) +{ + DXUTDeviceSettings DeviceSettings = DXUTGetDeviceSettings(); + + WCHAR strDeviceName[256] = {0}; + DEVMODE devMode; + ZeroMemory( &devMode, sizeof( DEVMODE ) ); + devMode.dmSize = sizeof( DEVMODE ); + if( DeviceSettings.ver == DXUT_D3D9_DEVICE ) + { + CD3D9Enumeration* pd3dEnum = DXUTGetD3D9Enumeration(); + CD3D9EnumAdapterInfo* pAdapterInfo = pd3dEnum->GetAdapterInfo( AdapterOrdinal ); + if( pAdapterInfo ) + { + MultiByteToWideChar( CP_ACP, 0, pAdapterInfo->AdapterIdentifier.DeviceName, -1, strDeviceName, 256 ); + strDeviceName[255] = 0; + } + } + else + { + CD3D11Enumeration* pd3dEnum = DXUTGetD3D11Enumeration(); + CD3D11EnumOutputInfo* pOutputInfo = pd3dEnum->GetOutputInfo( AdapterOrdinal, DeviceSettings.d3d11.Output ); + if( pOutputInfo ) + { + wcscpy_s( strDeviceName, 256, pOutputInfo->Desc.DeviceName ); + } + } + + EnumDisplaySettings( strDeviceName, ENUM_REGISTRY_SETTINGS, &devMode ); + if( pWidth ) + *pWidth = devMode.dmPelsWidth; + if( pHeight ) + *pHeight = devMode.dmPelsHeight; +} + + +//-------------------------------------------------------------------------------------- +// Display error msg box to help debug +//-------------------------------------------------------------------------------------- +HRESULT WINAPI DXUTTrace( const WCHAR* strFile, DWORD dwLine, HRESULT hr, + const WCHAR* strMsg, bool bPopMsgBox ) +{ + bool bShowMsgBoxOnError = DXUTGetShowMsgBoxOnError(); + if( bPopMsgBox && bShowMsgBoxOnError == false ) + bPopMsgBox = false; + + return DXTrace( strFile, dwLine, hr, strMsg, bPopMsgBox ); +} + + +//-------------------------------------------------------------------------------------- + +//-------------------------------------------------------------------------------------- +void WINAPI DXUTConvertDeviceSettings11to9( DXUTD3D11DeviceSettings* pIn, DXUTD3D9DeviceSettings* pOut ) +{ + pOut->AdapterOrdinal = pIn->AdapterOrdinal; + + if( pIn->DriverType == D3D_DRIVER_TYPE_HARDWARE ) + pOut->DeviceType = D3DDEVTYPE_HAL; + else if( pIn->DriverType == D3D_DRIVER_TYPE_REFERENCE ) + pOut->DeviceType = D3DDEVTYPE_REF; + else if( pIn->DriverType == D3D_DRIVER_TYPE_NULL ) + pOut->DeviceType = D3DDEVTYPE_NULLREF; + + pOut->AdapterFormat = ConvertFormatDXGIToD3D9( pIn->sd.BufferDesc.Format ); + pOut->BehaviorFlags = D3DCREATE_HARDWARE_VERTEXPROCESSING; + pOut->pp.BackBufferWidth = pIn->sd.BufferDesc.Width; + pOut->pp.BackBufferHeight = pIn->sd.BufferDesc.Height; + pOut->pp.BackBufferFormat = ConvertFormatDXGIToD3D9( pIn->sd.BufferDesc.Format ); + pOut->pp.BackBufferCount = pIn->sd.BufferCount; + pOut->pp.MultiSampleType = ( D3DMULTISAMPLE_TYPE )pIn->sd.SampleDesc.Count; + pOut->pp.MultiSampleQuality = pIn->sd.SampleDesc.Quality; + pOut->pp.SwapEffect = D3DSWAPEFFECT_DISCARD; + pOut->pp.hDeviceWindow = pIn->sd.OutputWindow; + pOut->pp.Windowed = pIn->sd.Windowed; + pOut->pp.EnableAutoDepthStencil = true; + pOut->pp.AutoDepthStencilFormat = D3DFMT_D24FS8; + pOut->pp.Flags = 0; + if( pIn->sd.BufferDesc.RefreshRate.Denominator == 0 ) + pOut->pp.FullScreen_RefreshRateInHz = 60; + else + pOut->pp.FullScreen_RefreshRateInHz = pIn->sd.BufferDesc.RefreshRate.Numerator / + pIn->sd.BufferDesc.RefreshRate.Denominator; + + switch( pIn->SyncInterval ) + { + case 0: + pOut->pp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; break; + case 2: + pOut->pp.PresentationInterval = D3DPRESENT_INTERVAL_TWO; break; + case 3: + pOut->pp.PresentationInterval = D3DPRESENT_INTERVAL_THREE; break; + case 4: + pOut->pp.PresentationInterval = D3DPRESENT_INTERVAL_FOUR; break; + + case 1: + default: + pOut->pp.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT; + break; + } +} + + +//-------------------------------------------------------------------------------------- +void WINAPI DXUTConvertDeviceSettings9to11( DXUTD3D9DeviceSettings* pIn, DXUTD3D11DeviceSettings* pOut ) +{ + pOut->AdapterOrdinal = pIn->AdapterOrdinal; + + if( pIn->DeviceType == D3DDEVTYPE_HAL ) + pOut->DriverType = D3D_DRIVER_TYPE_HARDWARE; + else if( pIn->DeviceType == D3DDEVTYPE_REF ) + pOut->DriverType = D3D_DRIVER_TYPE_REFERENCE; + else if( pIn->DeviceType == D3DDEVTYPE_NULLREF ) + pOut->DriverType = D3D_DRIVER_TYPE_NULL; + + pOut->Output = 0; + + pOut->sd.BufferDesc.Width = pIn->pp.BackBufferWidth; + pOut->sd.BufferDesc.Height = pIn->pp.BackBufferHeight; + pOut->sd.BufferDesc.RefreshRate.Numerator = pIn->pp.FullScreen_RefreshRateInHz; + pOut->sd.BufferDesc.RefreshRate.Denominator = 1; + pOut->sd.BufferDesc.Format = ConvertFormatD3D9ToDXGI( pIn->pp.BackBufferFormat ); + + if( pIn->pp.MultiSampleType == D3DMULTISAMPLE_NONMASKABLE ) + { + pOut->sd.SampleDesc.Count = pIn->pp.MultiSampleQuality; + pOut->sd.SampleDesc.Quality = 0; + } + else + { + pOut->sd.SampleDesc.Count = pIn->pp.MultiSampleType; + pOut->sd.SampleDesc.Quality = pIn->pp.MultiSampleQuality; + } + + pOut->sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; + pOut->sd.BufferCount = pIn->pp.BackBufferCount; + pOut->sd.OutputWindow = pIn->pp.hDeviceWindow; + pOut->sd.Windowed = pIn->pp.Windowed; + +#if defined(DEBUG) || defined(_DEBUG) + pOut->CreateFlags = D3D11_CREATE_DEVICE_DEBUG; +#else + pOut->CreateFlags = 0; +#endif + + switch( pIn->pp.PresentationInterval ) + { + case D3DPRESENT_INTERVAL_IMMEDIATE: + pOut->SyncInterval = 0; break; + case D3DPRESENT_INTERVAL_ONE: + pOut->SyncInterval = 1; break; + case D3DPRESENT_INTERVAL_TWO: + pOut->SyncInterval = 2; break; + case D3DPRESENT_INTERVAL_THREE: + pOut->SyncInterval = 3; break; + case D3DPRESENT_INTERVAL_FOUR: + pOut->SyncInterval = 4; break; + + case D3DPRESENT_INTERVAL_DEFAULT: + default: + pOut->SyncInterval = 1; + break; + } + + pOut->PresentFlags = 0; +} + + + +DXGI_FORMAT WINAPI ConvertFormatD3D9ToDXGI( D3DFORMAT fmt ) +{ + switch( fmt ) + { + case D3DFMT_UNKNOWN: + return DXGI_FORMAT_UNKNOWN; + case D3DFMT_R8G8B8: + case D3DFMT_A8R8G8B8: + case D3DFMT_X8R8G8B8: + return DXGI_FORMAT_R8G8B8A8_UNORM; + case D3DFMT_R5G6B5: + return DXGI_FORMAT_B5G6R5_UNORM; + case D3DFMT_X1R5G5B5: + case D3DFMT_A1R5G5B5: + return DXGI_FORMAT_B5G5R5A1_UNORM; + case D3DFMT_A4R4G4B4: + return DXGI_FORMAT_R8G8B8A8_UNORM; + case D3DFMT_R3G3B2: + return DXGI_FORMAT_R8G8B8A8_UNORM; + case D3DFMT_A8: + return DXGI_FORMAT_A8_UNORM; + case D3DFMT_A8R3G3B2: + return DXGI_FORMAT_R8G8B8A8_UNORM; + case D3DFMT_X4R4G4B4: + return DXGI_FORMAT_R8G8B8A8_UNORM; + case D3DFMT_A2B10G10R10: + return DXGI_FORMAT_R10G10B10A2_UNORM; + case D3DFMT_A8B8G8R8: + case D3DFMT_X8B8G8R8: + return DXGI_FORMAT_B8G8R8A8_UNORM; + case D3DFMT_G16R16: + return DXGI_FORMAT_R16G16_UNORM; + case D3DFMT_A2R10G10B10: + return DXGI_FORMAT_R10G10B10A2_UNORM; + case D3DFMT_A16B16G16R16: + return DXGI_FORMAT_R16G16B16A16_UNORM; + case D3DFMT_R16F: + return DXGI_FORMAT_R16_FLOAT; + case D3DFMT_G16R16F: + return DXGI_FORMAT_R16G16_FLOAT; + case D3DFMT_A16B16G16R16F: + return DXGI_FORMAT_R16G16B16A16_FLOAT; + case D3DFMT_R32F: + return DXGI_FORMAT_R32_FLOAT; + case D3DFMT_G32R32F: + return DXGI_FORMAT_R32G32_FLOAT; + case D3DFMT_A32B32G32R32F: + return DXGI_FORMAT_R32G32B32A32_FLOAT; + } + return DXGI_FORMAT_UNKNOWN; +} + + +D3DFORMAT WINAPI ConvertFormatDXGIToD3D9( DXGI_FORMAT fmt ) +{ + switch( fmt ) + { + case DXGI_FORMAT_UNKNOWN: + return D3DFMT_UNKNOWN; + case DXGI_FORMAT_R8G8B8A8_UNORM: + return D3DFMT_A8R8G8B8; + case DXGI_FORMAT_B5G6R5_UNORM: + return D3DFMT_R5G6B5; + case DXGI_FORMAT_B5G5R5A1_UNORM: + return D3DFMT_A1R5G5B5; + case DXGI_FORMAT_A8_UNORM: + return D3DFMT_A8; + case DXGI_FORMAT_R10G10B10A2_UNORM: + return D3DFMT_A2B10G10R10; + case DXGI_FORMAT_B8G8R8A8_UNORM: + return D3DFMT_A8B8G8R8; + case DXGI_FORMAT_R16G16_UNORM: + return D3DFMT_G16R16; + case DXGI_FORMAT_R16G16B16A16_UNORM: + return D3DFMT_A16B16G16R16; + case DXGI_FORMAT_R16_FLOAT: + return D3DFMT_R16F; + case DXGI_FORMAT_R16G16_FLOAT: + return D3DFMT_G16R16F; + case DXGI_FORMAT_R16G16B16A16_FLOAT: + return D3DFMT_A16B16G16R16F; + case DXGI_FORMAT_R32_FLOAT: + return D3DFMT_R32F; + case DXGI_FORMAT_R32G32_FLOAT: + return D3DFMT_G32R32F; + case DXGI_FORMAT_R32G32B32A32_FLOAT: + return D3DFMT_A32B32G32R32F; + } + return D3DFMT_UNKNOWN; +} + +//-------------------------------------------------------------------------------------- +IDirect3DDevice9* WINAPI DXUTCreateRefDevice9( HWND hWnd, bool bNullRef ) +{ + HRESULT hr; + IDirect3D9* pD3D = DXUT_Dynamic_Direct3DCreate9( D3D_SDK_VERSION ); + if( NULL == pD3D ) + return NULL; + + D3DDISPLAYMODE Mode; + pD3D->GetAdapterDisplayMode( 0, &Mode ); + + D3DPRESENT_PARAMETERS pp; + ZeroMemory( &pp, sizeof( D3DPRESENT_PARAMETERS ) ); + pp.BackBufferWidth = 1; + pp.BackBufferHeight = 1; + pp.BackBufferFormat = Mode.Format; + pp.BackBufferCount = 1; + pp.SwapEffect = D3DSWAPEFFECT_COPY; + pp.Windowed = TRUE; + pp.hDeviceWindow = hWnd; + + IDirect3DDevice9* pd3dDevice = NULL; + hr = pD3D->CreateDevice( D3DADAPTER_DEFAULT, bNullRef ? D3DDEVTYPE_NULLREF : D3DDEVTYPE_REF, + hWnd, D3DCREATE_HARDWARE_VERTEXPROCESSING, &pp, &pd3dDevice ); + + SAFE_RELEASE( pD3D ); + return pd3dDevice; +} + + +//-------------------------------------------------------------------------------------- +// Helper function to launch the Media Center UI after the program terminates +//-------------------------------------------------------------------------------------- +bool DXUTReLaunchMediaCenter() +{ + // Get the path to Media Center + WCHAR szExpandedPath[MAX_PATH]; + if( !ExpandEnvironmentStrings( L"%SystemRoot%\\ehome\\ehshell.exe", szExpandedPath, MAX_PATH ) ) + return false; + + // Skip if ehshell.exe doesn't exist + if( GetFileAttributes( szExpandedPath ) == 0xFFFFFFFF ) + return false; + + // Launch ehshell.exe + INT_PTR result = ( INT_PTR )ShellExecute( NULL, TEXT( "open" ), szExpandedPath, NULL, NULL, SW_SHOWNORMAL ); + return ( result > 32 ); +} + +typedef DWORD ( WINAPI* LPXINPUTGETSTATE )( DWORD dwUserIndex, XINPUT_STATE* pState ); +typedef DWORD ( WINAPI* LPXINPUTSETSTATE )( DWORD dwUserIndex, XINPUT_VIBRATION* pVibration ); +typedef DWORD ( WINAPI* LPXINPUTGETCAPABILITIES )( DWORD dwUserIndex, DWORD dwFlags, + XINPUT_CAPABILITIES* pCapabilities ); +typedef void ( WINAPI* LPXINPUTENABLE )( BOOL bEnable ); + +//-------------------------------------------------------------------------------------- +// Does extra processing on XInput data to make it slightly more convenient to use +//-------------------------------------------------------------------------------------- +HRESULT DXUTGetGamepadState( DWORD dwPort, DXUT_GAMEPAD* pGamePad, bool bThumbstickDeadZone, + bool bSnapThumbstickToCardinals ) +{ + if( dwPort >= DXUT_MAX_CONTROLLERS || pGamePad == NULL ) + return E_FAIL; + + static LPXINPUTGETSTATE s_pXInputGetState = NULL; + static LPXINPUTGETCAPABILITIES s_pXInputGetCapabilities = NULL; + if( NULL == s_pXInputGetState || NULL == s_pXInputGetCapabilities ) + { + HINSTANCE hInst = LoadLibrary( XINPUT_DLL ); + if( hInst ) + { + s_pXInputGetState = ( LPXINPUTGETSTATE )GetProcAddress( hInst, "XInputGetState" ); + s_pXInputGetCapabilities = ( LPXINPUTGETCAPABILITIES )GetProcAddress( hInst, "XInputGetCapabilities" ); + } + } + if( s_pXInputGetState == NULL ) + return E_FAIL; + + XINPUT_STATE InputState; + DWORD dwResult = s_pXInputGetState( dwPort, &InputState ); + + // Track insertion and removals + BOOL bWasConnected = pGamePad->bConnected; + pGamePad->bConnected = ( dwResult == ERROR_SUCCESS ); + pGamePad->bRemoved = ( bWasConnected && !pGamePad->bConnected ); + pGamePad->bInserted = ( !bWasConnected && pGamePad->bConnected ); + + // Don't update rest of the state if not connected + if( !pGamePad->bConnected ) + return S_OK; + + // Store the capabilities of the device + if( pGamePad->bInserted ) + { + ZeroMemory( pGamePad, sizeof( DXUT_GAMEPAD ) ); + pGamePad->bConnected = true; + pGamePad->bInserted = true; + if( s_pXInputGetCapabilities ) + s_pXInputGetCapabilities( dwPort, XINPUT_DEVTYPE_GAMEPAD, &pGamePad->caps ); + } + + // Copy gamepad to local structure (assumes that XINPUT_GAMEPAD at the front in CONTROLER_STATE) + memcpy( pGamePad, &InputState.Gamepad, sizeof( XINPUT_GAMEPAD ) ); + + if( bSnapThumbstickToCardinals ) + { + // Apply deadzone to each axis independantly to slightly snap to up/down/left/right + if( pGamePad->sThumbLX < XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE && + pGamePad->sThumbLX > -XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE ) + pGamePad->sThumbLX = 0; + if( pGamePad->sThumbLY < XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE && + pGamePad->sThumbLY > -XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE ) + pGamePad->sThumbLY = 0; + if( pGamePad->sThumbRX < XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE && + pGamePad->sThumbRX > -XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE ) + pGamePad->sThumbRX = 0; + if( pGamePad->sThumbRY < XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE && + pGamePad->sThumbRY > -XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE ) + pGamePad->sThumbRY = 0; + } + else if( bThumbstickDeadZone ) + { + // Apply deadzone if centered + if( ( pGamePad->sThumbLX < XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE && + pGamePad->sThumbLX > -XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE ) && + ( pGamePad->sThumbLY < XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE && + pGamePad->sThumbLY > -XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE ) ) + { + pGamePad->sThumbLX = 0; + pGamePad->sThumbLY = 0; + } + if( ( pGamePad->sThumbRX < XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE && + pGamePad->sThumbRX > -XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE ) && + ( pGamePad->sThumbRY < XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE && + pGamePad->sThumbRY > -XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE ) ) + { + pGamePad->sThumbRX = 0; + pGamePad->sThumbRY = 0; + } + } + + // Convert [-1,+1] range + pGamePad->fThumbLX = pGamePad->sThumbLX / 32767.0f; + pGamePad->fThumbLY = pGamePad->sThumbLY / 32767.0f; + pGamePad->fThumbRX = pGamePad->sThumbRX / 32767.0f; + pGamePad->fThumbRY = pGamePad->sThumbRY / 32767.0f; + + // Get the boolean buttons that have been pressed since the last call. + // Each button is represented by one bit. + pGamePad->wPressedButtons = ( pGamePad->wLastButtons ^ pGamePad->wButtons ) & pGamePad->wButtons; + pGamePad->wLastButtons = pGamePad->wButtons; + + // Figure out if the left trigger has been pressed or released + bool bPressed = ( pGamePad->bLeftTrigger > DXUT_GAMEPAD_TRIGGER_THRESHOLD ); + pGamePad->bPressedLeftTrigger = ( bPressed ) ? !pGamePad->bLastLeftTrigger : false; + pGamePad->bLastLeftTrigger = bPressed; + + // Figure out if the right trigger has been pressed or released + bPressed = ( pGamePad->bRightTrigger > DXUT_GAMEPAD_TRIGGER_THRESHOLD ); + pGamePad->bPressedRightTrigger = ( bPressed ) ? !pGamePad->bLastRightTrigger : false; + pGamePad->bLastRightTrigger = bPressed; + + return S_OK; +} + + +//-------------------------------------------------------------------------------------- +// Don't pause the game or deactive the window without first stopping rumble otherwise +// the controller will continue to rumble +//-------------------------------------------------------------------------------------- +void DXUTEnableXInput( bool bEnable ) +{ + static LPXINPUTENABLE s_pXInputEnable = NULL; + if( NULL == s_pXInputEnable ) + { + HINSTANCE hInst = LoadLibrary( XINPUT_DLL ); + if( hInst ) + s_pXInputEnable = ( LPXINPUTENABLE )GetProcAddress( hInst, "XInputEnable" ); + } + + if( s_pXInputEnable ) + s_pXInputEnable( bEnable ); +} + + +//-------------------------------------------------------------------------------------- +// Don't pause the game or deactive the window without first stopping rumble otherwise +// the controller will continue to rumble +//-------------------------------------------------------------------------------------- +HRESULT DXUTStopRumbleOnAllControllers() +{ + static LPXINPUTSETSTATE s_pXInputSetState = NULL; + if( NULL == s_pXInputSetState ) + { + HINSTANCE hInst = LoadLibrary( XINPUT_DLL ); + if( hInst ) + s_pXInputSetState = ( LPXINPUTSETSTATE )GetProcAddress( hInst, "XInputSetState" ); + } + if( s_pXInputSetState == NULL ) + return E_FAIL; + + XINPUT_VIBRATION vibration; + vibration.wLeftMotorSpeed = 0; + vibration.wRightMotorSpeed = 0; + for( int iUserIndex = 0; iUserIndex < DXUT_MAX_CONTROLLERS; iUserIndex++ ) + s_pXInputSetState( iUserIndex, &vibration ); + + return S_OK; +} + +//-------------------------------------------------------------------------------------- +// Helper functions to create SRGB formats from typeless formats and vice versa +//-------------------------------------------------------------------------------------- +DXGI_FORMAT MAKE_SRGB( DXGI_FORMAT format ) +{ + if( !DXUTIsInGammaCorrectMode() ) + return format; + + switch( format ) + { + case DXGI_FORMAT_R8G8B8A8_TYPELESS: + case DXGI_FORMAT_R8G8B8A8_UNORM: + case DXGI_FORMAT_R8G8B8A8_UINT: + case DXGI_FORMAT_R8G8B8A8_SNORM: + case DXGI_FORMAT_R8G8B8A8_SINT: + return DXGI_FORMAT_R8G8B8A8_UNORM_SRGB; + + case DXGI_FORMAT_BC1_TYPELESS: + case DXGI_FORMAT_BC1_UNORM: + return DXGI_FORMAT_BC1_UNORM_SRGB; + case DXGI_FORMAT_BC2_TYPELESS: + case DXGI_FORMAT_BC2_UNORM: + return DXGI_FORMAT_BC2_UNORM_SRGB; + case DXGI_FORMAT_BC3_TYPELESS: + case DXGI_FORMAT_BC3_UNORM: + return DXGI_FORMAT_BC3_UNORM_SRGB; + + }; + + return format; +} + +//-------------------------------------------------------------------------------------- +DXGI_FORMAT MAKE_TYPELESS( DXGI_FORMAT format ) +{ + if( !DXUTIsInGammaCorrectMode() ) + return format; + + switch( format ) + { + case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: + case DXGI_FORMAT_R8G8B8A8_UNORM: + case DXGI_FORMAT_R8G8B8A8_UINT: + case DXGI_FORMAT_R8G8B8A8_SNORM: + case DXGI_FORMAT_R8G8B8A8_SINT: + return DXGI_FORMAT_R8G8B8A8_TYPELESS; + + case DXGI_FORMAT_BC1_UNORM_SRGB: + case DXGI_FORMAT_BC1_UNORM: + return DXGI_FORMAT_BC1_TYPELESS; + case DXGI_FORMAT_BC2_UNORM_SRGB: + case DXGI_FORMAT_BC2_UNORM: + return DXGI_FORMAT_BC2_TYPELESS; + case DXGI_FORMAT_BC3_UNORM_SRGB: + case DXGI_FORMAT_BC3_UNORM: + return DXGI_FORMAT_BC3_TYPELESS; + }; + + return format; +} + +//-------------------------------------------------------------------------------------- +HRESULT DXUTSnapD3D9Screenshot( LPCTSTR szFileName ) +{ + HRESULT hr = S_OK; + IDirect3DDevice9* pDev = DXUTGetD3D9Device(); + if( !pDev ) + return E_FAIL; + + IDirect3DSurface9* pBackBuffer = NULL; + V_RETURN( pDev->GetBackBuffer( 0, 0, D3DBACKBUFFER_TYPE_MONO, &pBackBuffer ) ); + + return D3DXSaveSurfaceToFile( szFileName, D3DXIFF_BMP, pBackBuffer, NULL, NULL ); +} + + + + +//-------------------------------------------------------------------------------------- +HRESULT DXUTSnapD3D11Screenshot( LPCTSTR szFileName, D3DX11_IMAGE_FILE_FORMAT iff ) +{ + IDXGISwapChain *pSwap = DXUTGetDXGISwapChain(); + + if (!pSwap) + return E_FAIL; + + ID3D11Texture2D* pBackBuffer; + HRESULT hr = pSwap->GetBuffer( 0, __uuidof( *pBackBuffer ), ( LPVOID* )&pBackBuffer ); + if (hr != S_OK) + return hr; + + ID3D11DeviceContext *dc = DXUTGetD3D11DeviceContext(); + if (!dc) { + SAFE_RELEASE(pBackBuffer); + return E_FAIL; + } + ID3D11Device *pDevice = DXUTGetD3D11Device(); + if (!dc) { + SAFE_RELEASE(pBackBuffer); + return E_FAIL; + } + + D3D11_TEXTURE2D_DESC dsc; + pBackBuffer->GetDesc(&dsc); + D3D11_RESOURCE_DIMENSION dim; + pBackBuffer->GetType(&dim); + // special case msaa textures + ID3D11Texture2D *pCompatableTexture = pBackBuffer; + if ( dsc.SampleDesc.Count > 1) { + D3D11_TEXTURE2D_DESC dsc_new = dsc; + dsc_new.SampleDesc.Count = 1; + dsc_new.SampleDesc.Quality = 0; + dsc_new.Usage = D3D11_USAGE_DEFAULT; + dsc_new.BindFlags = 0; + dsc_new.CPUAccessFlags = 0; + ID3D11Texture2D *resolveTexture; + hr = pDevice->CreateTexture2D(&dsc_new, NULL, &resolveTexture); + dc->ResolveSubresource(resolveTexture, 0, pBackBuffer, 0, dsc.Format); + pCompatableTexture = resolveTexture; + pCompatableTexture->GetDesc(&dsc); + } + + hr = D3DX11SaveTextureToFileW(dc, pCompatableTexture, iff, szFileName); + + + SAFE_RELEASE(pBackBuffer); + SAFE_RELEASE(pCompatableTexture); + + return hr; + +} |