Quantcast
Channel: Games for Windows and the DirectX SDK
Viewing all 60 articles
Browse latest View live

"Who moved my [Windows Media] Cheese"?

$
0
0

Since the release of Windows XP Service Pack 2, support for the Windows Media codec (WMV) has been built into the OS, so developers have come to rely on it being there particularly for DirectShow playback of cutscenes or video textures. On Windows Vista, we introduced the Windows Media Foundation APIs as well. Much like the core of DirectX becoming part of the OS, these components being present on all modern versions of Windows simplifies the deployment story for applications.

Alas, the European Union and the Korea Fair Trade Commission has made that story a bit more complicated...

For games that make use of the Windows Media codec (WMV), Windows Media Foundation, Windows Media Player, the WMP ActiveX control, or other aspects of the Windows Media Format SDK Runtime, you will need to provide some guideance for users with the N or KN editions of Windows.

For Windows 7, there are two options for restoring these components to the system

  • The Windows Media Feature Pack (KB 968211) installs all the Windows Media components. This is required for applications that make use of the Windows Media Foundation, Windows Media Player, or the WMP ActiveX Control.

 -or-

  • The Windows Media Format Feature Pack (KB 968212) installs the Windows Media Format SDK Runtime support for the WMV codec. This is sufficient for applications that use the WMV codec throught DirectShow. Note that these components are also included in the KB 968211 update.

For Windows Vista or Windows XP N editions, installing Windows Media Player is the easist way to restore this functionality.

Putting a note about these editions in your release notes or on your support website should be sufficient. If, however, you are looking for a way to programmatically detect N or KN editions, you should first use existing techniques for trying to use the feature but gracefully handle it not being available (i.e. try to create the COM object or use explicit linking via LoadLibrary). Only if that fails should you look at generating a message to the user. For Win32 desktop applications, you could then use the GetProductInfo function (KN editions identify as N editions that are localized to the Korean language) when handling the error case to verify that is the likley problem. Note this function is only available on Windows Vista or later, so you should use explicit linking for that API as well if you are trying to maintain code compatability with Windows XP. While there are in fact Windows XP N Editions, they were sold in very low numbers so you are unlikely to have any significant number of users in this situation.

This reliance on Windows Media components is not limited to just gamers, so it is likely that most users will already have installed one of these updates to enable other applications to function. With fresh installs of the OS, pariticularly if you are explicitly testing with the N or KN editions of Windows, it is important to apply the appropriate Feature Pack.

Windows 8.x: There is a Media Feature Pack for N and KN versions of Windows 8 (KB 2703761) and Media Feature Pack for Windows 8.1 N and Windows 8.1 KN Editions (KB 2835517) available. Note that both Window Vista and Windows 7 N and KN editions excluded MFPLAT.DLL, but for Windows 8.x there is a stub present for systems without the Media Feature Pack installed that returns E_NOTIMPL when you call MFStartup. This simplifies handling for Windows Store apps which cannot make use of explicit linking to system DLLs.

Windows 10: There is a Media feature pack for Windows 10 N and Windows 10 KN editions (KB 3010081) and Media Feature Pack for Windows 10 N and Windows 10 KN editions (November 2015) (KB 3099229) available.

 


Desktop Games on Windows 8.x

$
0
0

Developers working on games for Windows are already familiar with the DirectX SDK. Important changes to the DirectX family of technologies are included in the new Windows SDK, which is the new home for the DirectX SDK. Be sure to read “Where is the DirectX SDK?” for the details.

Windows 8.1: Note that these guidelines also apply for Win32 Desktop games running on Windows 8.1. The Windows and Windows Server compatibility cookbook has been updated with notes about Windows 8.1. Pay particular attention to the OS version detection behavior change, as well as the new 200% high-DPI scaling mode. Also note that in Windows 8.1 DirectPlay is now a distinct Windows feature that is off by default.

Windows 10 Technical Preview: Be sure to read the Windows 8.1 guidance as it also applies to Windows 10. Note that there is an additional <compatibly> GUID for the new version (see Manifest Madness) , and VerifyVersionInfo is now subject to the same manifest-based behavior as GetVersion(Ex).

Game Compatibility Guidelines

With a new release of Windows, publishers and developers want to ensure customers running Windows 8.x continue to have a great experience running their current catalog of games for Windows 7. Developers interested in Windows 8.x software certification program should be sure to read the latest version of those requirements, which can also allow you to have your Desktop application listed in the Windows Store. The older Games for Windows Technical Requirements and Test Requirements documents are still applicable best practices for desktop Win32 games on Windows 8.x. There are some additional things to keep in mind when your game is run on a Windows 8.x machine.

  • The Games Explorer UI is not visible. All games registered with the Game Explorer are surfaced as tiles in the Metro UI, but much of the metadata associated with the title is no longer visible. You still use GDFMaker (latest version is in the Windows 8.1 SDK) to author the data, and use the existing mechanisms for deploying it. Continue to test your GE registration using Windows 7, verify the Start menu tile shows up when installed on Windows 8.x, and use the GDF Validator tool to check for known problems with the authored GDF content. [TR 1.1]

 

  • Registration with the Game Explorer APIs continues to be the mechanism for registering your game with Windows Parental Controls. The Windows SDK version of GDFMaker should be run on an up-to-date copy of Windows 7 or Windows 8.x to ensure it can populate all currently supported rating systems. Note that this copy of GDFMaker requires .NET 4.0. The latest version of the Gameux Install Helper sample is available on MSDN Code GalleryNote the recent changes to the supported rating systems with Windows 8.x and Windows 7 [TR 1.2]

 

  • There are now three choices for using the XINPUT API depending on your requirements: XINPUT 1.4 is built into Windows 8.x (useable by both Windows Store apps and desktop Win32 applications), XINPUT 9.1.0 for simplified common-controller usage across all versions of Windows without any redistribution package, and the existing DirectX SDK version XINPUT 1.3 which requires DirectSetup to deploy. [TR 1.4]

 

  • High-DPI scenarios are becoming more common. Be sure to test your application with 125% and 150% scaling, and populate the EXEs manifest with <dpiAware>true</dpiAware>. Windows 8.1 includes a 200% scaling option as well, and the recommended full-screen Direct3D game manifest element is now <dpiAware>True/PM</dpiAware>[TR 1.8]

 

  • Only a limited set of desktop Win32 applications are supported on Windows RT (aka Windows on ARM). Games that run on Windows 7 can and should run correctly on Windows 8.x x86 and x64 systems. [TR 2.2]

 

  • Ensure any OS checks are done correctly. Windows 8 is version “6.2”, and will pass the current ‘minimum bar’ tests recommended for game deployment. Windows 8.1 is version "6.3", but note that GetVersion(Ex) APIs are now deprecated and have new appcompat behavior by default. With Windows 10  VersionVersionInfo has a similar behavior, and the OS has a version of "10.0" (it was "6.4" the early Technical Previews). [TR 2.5]

 

  • The “DirectX End-User Redistribution” package will run successfully on a Windows 8.x machine to deploy D3DX9, D3DX10, D3DX11, XINPUT 1.3, XAUDIO 2.7, XACTEngine, etc. as it does on Windows 7.  There is, however, a known issue with DirectSetup on systems with only .NET 4.0 installed due to the deployment handling of the legacy Managed DirectX 1.1 assemblies. This applies to both Windows 8.x (which comes with .NET 4.5 by default) and ‘fresh’ Windows XP systems with the .NET 4.0 runtime installed but not any version of .NET prior to that. While Windows 8.x has an application compatibility behavior to resolve this automatically (which requires network access), we recommend that games continuing to deploy DirectSetup update to the DirectX SDK (June 2010) refreshed version of the REDIST files. As always, be sure to understand if you really need to use DirectSetup at all for your title, and if you do trim it down to the minimum required set of CABs. [TR 3.4]

 

  • Games that require the .NET “2.0” compatible runtime (2.0, 3.0, 3.5) should continue to use existing deployment mechanisms. These will trigger an application compatibility behavior on Windows 8.x to enable the .NET 3.5 runtime automatically (which requires network access). However, we recommend that .NET developers move to the .NET 4.0 runtime. Note that the legacy Managed DirectX 1.1 assemblies are not compatible with the .NET 4.x runtime. Also, the .NET 1.1 framework is not supported on either Windows 7 or Windows 8.x. [TR 3.4]

 

  • Use of an ‘autorunner’ or other pre-install technology that relies on .NET is not recommended. Only .NET 2.0 compatible runtimes can be assumed present on Windows Vista and Windows 7, and only the .NET 4.0 compatible runtime is present on Windows 8.x by default. [TR 3.7]

 

  • There is an updated Application Verifier for Windows 8. This is included as part of the Windows 8.x SDK. It is recommended you test with all the Basics tests including the new COM, Exceptions, Leak, RPC, SRWLock, and Threadpool. [TR 4.2]

In addition to the existing Windows 7 best practices, you should review the Windows 8 and Windows Server 2012 Compatibility Cookbook for detailed application compatibility notes on various Windows technologies. In particular, you should review the topics

Recommendations for desktop Win32 Titles

In addition to learning about the new Windows Store app model (a.k.a. Metro style apps), here are some important things to consider when creating Windows game titles for Windows 7 and for the desktop of Windows 8.

  • Invest in the Direct3D 11 graphics API. The Direct3D 11 API provides a broad range of hardware support through the 9.x feature levels on Windows 8, Windows 7, and Windows Vista machines with DirectX 11 installed. Continuing to rely on the legacy Direct3D 9 poses a number of challenges including limited access to debugging support, and limited driver support. Windows 8 Hardware Certification Requirements will ensure that that the majority of desktop form-factor x86/x64 machines will have Feature Level 10.0 or later device support. Windows Store apps must use the Direct3D 11 API and cannot use the Direct3D 9 API.

 

  • Minimize or eliminate dependencies on legacy technology. D3DX9, D3DX10, and D3DX11 are deprecated components. There are a number of recommended replacement technologies that should be used instead: DirectXMath, DirectXTK, DirectXTex, DirectXMesh. XACT is also deprecated. No version of D3DX is supported for Windows Store apps. DirectInput and DirectSound are not available for Windows Store apps or on the Windows RT platform. For a full list of D3DX replacements, see this post.

 

  • Minimize or eliminate the dependencies on the “DirectSetup” redistribution package. “DirectX” technologies are included with the Windows OS, and these are never updated by the use of the “DirectX End-User Runtime” packages. Solutions for removing the remaining dependencies exist and should be adopted. The latest D3DCompiler and D3DSCX from the new Windows SDK can be deployed “application local” with desktop applications without requiring a redistribution package. Note these DLLs may not be redistributed with Windows Store apps. 

 

  • Adopt C++11 compilers, standard libraries, and features. Visual Studio 2010 and Visual Studio 2012 (aka VS 11) support modern C++ constructs which can eliminate direct dependences on some legacy APIs, improve the portability of the code, and can provide a bridge to Windows Store apps. See the Visual C++ Team Blog for more information. Also be sure to enable compiler security features such as /SAFESEH, /NXCOMPAT, and /DYNAMICBASE which are required for the Windows 8 certifications for both Windows Store apps and Win32 desktop apps.

Update: This page has been updated on October 25, 2012 for Windows 8 GA (was originally written for Windows 8 Consumer Preview).

Related:Dual-use Coding Techniques for Games, DirectX SDKs of a certain age, Manifest Madness

XAudio2 and Windows 8

$
0
0

The Windows 8 Consumer Preview includes version 2.8 of the XAudio2 game audio API built in, and this API is fully supported for both Windows Store apps (including x86, x64, and Windows on ARM) and desktop Win32 applications. The full details of the differences compared to XAudio2 2.7 which shipped in the DirectX SDK (June 2010) release are addressed on MSDN. The headers and libraries for XAudio 2.8 are included in the Windows SDK 8.0 that is part of Visual Studio 11 Beta.

Update: This information also applies to Windows 8 RTM, Visual Studio 2012 RTM, Windows 8.1, and Visual Studio 2013.

Windows phone: Windows phone 8 supports XAudio 2.8 as well.

REDIST: For XAudio 2.8 or later on Windows 8 and Windows RT, no redistribution is required since XAudio 2.8 is included with the OS. For XAudio 2.7 on any version of Windows, use the legacy DirectX SDK REDIST.

Since XAudio2 version 2.8 is not available on Windows 7, Win32 desktop games that support older versions of Windows will need to continue to use XAudio 2.7. In general it is fairly easy to write code that successfully complies both for "Windows 8 only" which is the case for Windows Store apps and for 'down-level', but requires you mix both the Windows SDK 8.0 and DirectX SDK headers (see "Where is the DirectX SDK?").

  • When building an application that is 'down-level' using headers in the Windows 8.0 SDK, be sure to explicitly select the correct 'minimum' _WIN32_WINNT value. For Windows 8, that is 0x0602 (which is the default when building code with Visual Studio 2012 and for all Windows Store apps). For Windows 7 use 0x0601, and for Windows Vista use 0x0600. Typically this is done as part of the project configuration via Preprocessor Definitions.

If you set _WIN32_WINNT correctly and try building with the Windows 8.x SDK version of xaudio2.h headers, you'll get an error letting you know that you have to use the DirectX SDK version of that header. You should follow the instructions on MSDN to use the Windows 8.x SDK headers and libraries, listing the DXSDK_DIR paths in VC++ Directories after the Windows SDK header/libs, and explicitly link to the headers in the 'default' location--environment variables in #include statements doesn't work--where you need older versions to support older versions of Windows. 

  • The DirectX SDK version of XAudio2 used CoCreateInstance and was registered with COM, and required an explicit Initialize method to be called. The DirectX SDK  'xaudio2.h' header contained a wrapper inline function XAudio2Create that did this to simplify portability with the Xbox 360 version. For the Windows 8 version, you don't use COM creation and instead call the XAudio2Create function and link with "xaudio2.lib". For the DirectX SDK, you must explicitly enable the debugging support if desired, but the XAUDIO2_DEBUG_ENGINE flag doesn't exist for the Windows 8 version.  Note: If using the xAPOs XAudio2CreateVolumeMeter or XAudio2CreateReverb from the xaudio2fx.h header, they have the same link requirement for XAudio 2.8.
 #if (_WIN32_WINNT >= 0x0602 /*_WIN32_WINNT_WIN8*/)
#include <xaudio2.h>
#pragma comment(lib,"xaudio2.lib")
#else
#include <C:\Program Files (x86)\Microsoft DirectX SDK (June 2010)\Include\xaudio2.h>
#endif
#pragma comment(lib,"ole32.lib")

CoInitializeEx( nullptr, 0 );

UINT32 flags = 0;
#if (_WIN32_WINNT < 0x0602 /*_WIN32_WINNT_WIN8*/) && defined(_DEBUG)
flags |= XAUDIO2_DEBUG_ENGINE;
#endif

hr = XAudio2Create( &pXAudio2, flags );
if( FAILED( hr ) ) {
...
}
#if (_WIN32_WINNT >= 0x0602 /*_WIN32_WINNT_WIN8*/) && defined(_DEBUG)
// To see the debug output, you need to view ETW logs for this application:
// Go to Control Panel, Administrative Tools, Event Viewer.
// View->Show Analytic and Debug Logs.
// Applications and Services Logs / Microsoft / Windows / XAudio2.
// Right click on Microsoft Windows XAudio2 debug logging, Properties, then Enable Logging, and hit OK
XAUDIO2_DEBUG_CONFIGURATION debug ={0};
debug.TraceMask = XAUDIO2_LOG_ERRORS | XAUDIO2_LOG_WARNINGS;
pXAudio2->SetDebugConfiguration( &debug, 0 );
#endif
  • Any calls to IXAudio2::GetDeviceCount() or IXAudio2::GetDeviceDetails() must be guarded since these APIs do not exist in the Windows 8 version. For Windows 8, all explicit device enumeration is done using WinRT APIs. If using the default audio device, the same code will compile for both as the default parameters in both versions do the same thing. If doing an explicit device selection, you must code two versions. The Windows 8 version requires a szDeviceId that is an LPWSTR. The XAudio 2.7 version requires a UINT32 DeviceIndex. Note this Windows 8 version is not the ideal usage since it forces the device enumeration to be synchronous. 

#if (_WIN32_WINNT >= 0x0602 /*_WIN32_WINNT_WIN8*/)

 using Windows::Devices::Enumeration::DeviceClass;
using Windows::Devices::Enumeration::DeviceInformation;
using Windows::Devices::Enumeration::DeviceInformationCollection;

auto operation = DeviceInformation::FindAllAsync(DeviceClass::AudioRender);
while (operation->Status != Windows::Foundation::AsyncStatus::Completed)
;

DeviceInformationCollection^ devices = operation->GetResults();

for (unsigned i=0; i < devices->Size; ++i)
{
using Windows::Devices::Enumeration::DeviceInformation;

DeviceInformation^ d = devices->GetAt(i);
// display name is d->Name->Data()
// device id is d->Id->Data() used for creating the mastering voice
}

#else

 UINT32 dCount = 0;
hr = pXAudio2->GetDeviceCount( &dCount );
if (FAILED(hr) )
...

for( UINT32 index=0; index < dCount; ++index )
{
XAUDIO2_DEVICE_DETAILS details;
hr = pXAudio2->GetDeviceDetails( index, &details );
if (FAILED(hr))
break;

// display name is details.DisplayName
// internal device ID is details.DeviceID
// the 'index' is used for creating the mastering voice
}

#endif

  • When creating the mastering voice, the two versions take very similar inputs. If using mostly default values, the same code can compile under both conditions. Otherwise, there are two differences: (1) The Windows 8 version takes a szDeviceId for specifying the device to use, while the XAudio 2.7 version uses a DeviceIndex (2) The Windows 8 version takes one additional parameter for registering the output with the correct AUDIO_STREAM_CATEGORY.
 #if (_WIN32_WINNT >= 0x0602 /*_WIN32_WINNT_WIN8*/)

hr = pXAudio2->CreateMasteringVoice( &pMasteringVoice, XAUDIO2_DEFAULT_CHANNELS, XAUDIO2_DEFAULT_SAMPLERATE, 0, deviceID, NULL, AudioCategory_GameEffects );

#else

hr = pXAudio2->CreateMasteringVoice( &pMasteringVoice, XAUDIO2_DEFAULT_CHANNELS, XAUDIO2_DEFAULT_SAMPLERATE, 0, deviceIndex, NULL );

#endif
  • If you are using X3DAudio you will need the mastering voice's 'channel mask'. If using the XAudio 2.7 version, you get this information back from IXAudio2::GetDeviceDetails. Since that method is not used for the Windows 8 version, you obtain that information from the mastering voice instead. You likely need the number of channels as well. For the XAudio 2.7 version you need to link to x3daudio.lib, but for the Windows 8 version it is included in xaudio2.lib.
 #if (_WIN32_WINNT >= 0x0602 /*_WIN32_WINNT_WIN8*/)
#include <x3daudio.h>
#pragma comment(lib,"xaudio2.lib")
#else
#include <C:\Program Files (x86)\Microsoft DirectX SDK (June 2010)\include\x3daudio.h>
#pragma comment(lib,"x3daudio.lib")
#endif

#if (_WIN32_WINNT >= 0x0602 /*_WIN32_WINNT_WIN8*/)

DWORD dwChannelMask;
pMasteringVoice->GetChannelMask( &dwChannelMask );

XAUDIO2_VOICE_DETAILS vdetails;
pMasteringVoice->GetVoiceDetails( &vdetails );
UINT32 nChannels = vdetails.InputChannels;

#else

XAUDIO2_DEVICE_DETAILS details;
hr = pXAudio2->GetDeviceDetails( deviceIndex, &details );
if ( FAILED(hr) )
...

DWORD dwChannelMask = details.OutputFormat.dwChannelMask;
UINT32 nChannels = details.OutputFormat.Format.nChannels;

#endif

X3DAUDIO_HANDLE x3DInstance;
X3DAudioInitialize( dwChannelMask, X3DAUDIO_SPEED_OF_SOUND, x3DInstance );
  • The xAPO function CreateFX in XAudio 2.8 takes an optional initial parameters structure. When using the xAPO CreateFX with XAudio 2.7, you cannot pass the initial parameters until you bind to a voice and use SetEffectParameters and need to link to xapofx.lib.
 #if (_WIN32_WINNT >= 0x0602 /*_WIN32_WINNT_WIN8*/)
#include <xapofx.h>
#pragma comment(lib,"xaudio2.lib")
#else
#include <C:\Program Files (x86)\Microsoft DirectX SDK (June 2010)\include\xapofx.h>
#pragma comment(lib,"xapofx.lib")
#endif

IUnknown* effect = nullptr;
#if (_WIN32_WINNT >= 0x0602 /*_WIN32_WINNT_WIN8*/)
hr = CreateFX( _uuidof(...), &effect, &params, sizeof(params) );
#else
hr = CreateFX( _uuidof(...), &effect );
...
voice->SetEffectParameters( 0, &params, sizeof(params) );
#endif
  • From here the rest of XAudio2 API calls should be the same. The only further difference is that the Windows 8 version will not process audio data compressed using 'xWMA', but it does support both PCM and ADPCM data that would work with XAudio 2.7. For advanced compression options for the Windows 8 version, the solution is to use Media Foundation to do the decompression and then pass the resulting data to XAudio 2.8 which is demonstrated in the Windows Store app XAudio2 Audio Stream Effect sample and the XAudio2MFStream sample.

See Learning XAudio2, XAudio2 Win32 Samples, DirectXTK for Audio, Known Issues: XAudio 2.7

WIndows Server 2012: Note that XAudio 2.8 is not included in Windows Server 2012.

Windows phone 8: Windows phone 8 development uses XAudio 2.8.

Xbox One: Xbox One development uses XAudio 2.8 with additional support for xWMA. Xbox One XDK developers can also make use of XMA2.

Windows 10: Windows 10 SDK includes XAudio 2.9 which assumes you are building with _WIN32_WINT=0x0A00 when linking against xaudio2.lib. To continue to use XAudio 2.8, build with _WIN32_WINNT=0x0602 or _WIN32_WINNT=0x0603 and link against xaudio2_8.lib. See MSDN for more information about XAudio 2.9.

XINPUT and Windows 8

$
0
0

The Windows 8 Consumer Preview includes version 1.4 of the XInput API for use with Xbox 360 Common Controller compatible game devices, and this API is fully supported for both Windows Store apps (including x86, x64, and Windows on ARM) and desktop Win32 applications. The full details of the differences compared to XInput 1.3 which shipped in the DirectX SDK (June 2010) release are addressed on MSDN. The headers and libraries for Xinput 1.4 are included in the Windows SDK 8.0 that is part Visual Studio 11 Beta. Windows 8 also includes an updated driver for these devices, XUSB22.SYS.

Update: This information also applies to Windows 8 Release Preview / RTM and Visual Studio 2012 RC / RTM. XINPUT 1.4 is supported on Windows RT as well.

REDIST: For XInput 1.4 on Windows 8 and Windows RT, no redistribution is required since XInput 1.4 is included with the OS. For XInput 9.1.0 on Windows Vista, Windows 7, or WIndows 8, no redistribution is required since XInput 9.1.0 is included with the OS. For XInput 1.3 on any version of Windows, use the legacy DirectX SDK REDIST.

Since Xinput version 1.4 is not available on Windows 7, Win32 desktop games that support older versions of Windows can use either XInput 1.3 or the still supported older XInput 9.1.0 which is included in Windows Vista, Windows 7, and Windows 8.

  • When building an application that is 'down-level' using headers in the Windows 8.0 SDK, be sure to explicitly select the correct 'minimum' _WIN32_WINNT value. For Windows 8, that is 0x0602 (which is the default when building code with Visual Studio 2012 and for all Windows Store apps). For Windows 7 use 0x0601, and for Windows Vista use 0x0600. Typically this is done as part of the project configuration via Preprocessor Definitions.

If you set _WIN32_WINNT correctly and try building with the Windows 8.0 SDK version of the xinput.h header, you will be using XInput 1.4 if set to 0x0602, or XInput 9.1.0 otherwise. If using XInput 1.4, you should link with XINPUT.LIB. If using XInput 9.1.0, link with XINPUT9_1_0.LIB instead.

If your usage of XInput is limited to basic gamepad functionality via XInputGetState and XInputSetState, then XInput 9.1.0 may be all the functionailty you require and is supported on a broad range of Windows OSes without the need to use the DirectSetup redistribution package. A few things to note about XInput 9.1.0 are that XInputGetCapabilities returns a fixed set of values regardless of the attached device (notably including the subtype), and this version of XInput does not support headset audio functionality.

The following code will compile using all three versions of XInput:

 #include <xinput.h>

XINPUT_STATE state;
memset( &state, 0, sizeof(XINPUT_STATE) );

if( XInputGetState( 0, &state ) == ERROR_SUCCESS )
{
// Controller is connected
if ( state.Gamepad.wButtons & XINPUT_GAMEPAD_A )
{
// Button A is pressed
}

XINPUT_VIBRATION motor;
memset( &motor, 0, sizeof(XINPUT_VIBRATION) );

if ( state.Gamepad.bLeftTrigger > XINPUT_GAMEPAD_TRIGGER_THRESHOLD )
{
motor.wLeftMotorSpeed = state.Gamepad.bLeftTrigger << 8;
}

if ( state.Gamepad.bRightTrigger > XINPUT_GAMEPAD_TRIGGER_THRESHOLD )
{
motor.wRightMotorSpeed = state.Gamepad.bRightTrigger << 8;
}

XInputSetState( 0, &motor );

}
else
{
// Controller is not connected, shouldn't recheck it for a few seconds
}

If using the XInput 1.3 solution, You should follow the instructions on MSDN to use the Windows 8.0 SDK headers and libraries where possible and explicitly link to the DXSDK_DIR for the headers where you need older versions to support older versions of Windows. (see "Where is the DirectX SDK?").

In a future post, I'll address the details of using XInput 1.4's audio features, and how to implement similiar behavior down-level using XInput 1.3. XInput 9.1.0 doesn't support audio features.

Note: The Windows 7.1 SDK includes the xinput.h header and xinput.lib import library for the the Xinput 9.1.0 version as well. XInput 9.1.0 can be deployed on Windows XP using the legacy DirectX SDK's REDIST (aka DirectSetup).

Windows Server: Note that XInput is not included in Windows Server 2012. XInput 9.1.0 is also not present on Windows Server 2008 or 2012.

Xbox One Controller: The Xbox One controller is not supported by the XUSB21.SYS (Windows 7) or XUSB22.SYS (Windows 8.x) driver. There is a X1USB1.SYS driver now available which does support the Xbox One Controller for XINPUT when using a micro-USB cable--the Xbox One controller is not compatible with the Xbox 360 Wireless Receiver for Windows.

Windows 10: To continue to use XInput 1.4 with universal Windows apps, be sure to link with xinputuap.lib rather than xinput.lib. Alternatively, you can make direct use of the new Windows.Gaming.Input API or the GamePad class in DirectX Tool Kit.

Related:XInput Win32 Samples, Game controller sample

XINPUT and XAudio2

$
0
0

In an earlier post, I covered how to use XInput with the release of the Windows 8 Consumer Preview. In this post, I'll discuss how to make use of headset audio for the Xbox 360 Common Controller.

Update: This advice also applies to the Windows 8 Release Preview / RTM and Visual Studio 2012 RC / RTM.

XInput 1.4 and XAudio2.8 in the Windows 8 Consumer Preview are designed to integrate well together. The code for creating an XAudio2 device for the headset on a Xbox 360 Common Controller is fairly simple as both are designed to return and consume WinRT style device identifiers:

 #if (_WIN32_WINNT >= 0x0602 /*_WIN32_WINNT_WIN8*/)
WCHAR renderID[256] = {0};
WCHAR captureID[256] = {0};
UINT renderCount = 256;
UINT captureCount = 256;

XInputGetAudioDeviceIds( 0, renderID, &renderCount, captureID, &captureCount );

IXAudio2* pXAudio2 = nullptr;
if ( *renderID != 0 && SUCCEEDED( XAudio2Create( &pXAudio2, 0 ) ) )
{
IXAudio2MasteringVoice* pMasteringVoice = nullptr;
if ( SUCCEEDED( pXAudio2->CreateMasteringVoice( &pMasteringVoice, 0, 0, 0, renderID ) ) )
{
#else

The older XInput 1.3 was designed to work with DirectSound and returns DirectSound device GUIDs.

 GUID render = {0};
GUID capture = {0};
XInputGetDSoundAudioDeviceGuids( 0, &render, &capture );

Using XInput 1.3 with XAudio 2.7 together is a little more work:

 WCHAR renderID[256] = {0};
DSoundtoMMEndpoint( render, renderID, 256, false );


WCHAR captureID[256] = {0};
DSoundtoMMEndpoint( capture, captureID, 256, true );

IXAudio2* pXAudio2 = nullptr;
if ( SUCCEEDED( XAudio2Create( &pXAudio2, 0 ) ) )
{
UINT count = 0;
pXAudio2->GetDeviceCount( &count );

UINT index = 0;
for( ; index < count; ++index )
{
XAUDIO2_DEVICE_DETAILS details;
pXAudio2->GetDeviceDetails( index, &details );

if ( ::_wcsnicmp( details.DeviceID, renderID, 256 ) == 0 )
break;
}

if ( index < count )
{
IXAudio2MasteringVoice* pMasteringVoice = nullptr;
if ( SUCCEEDED( pXAudio2->CreateMasteringVoice( &pMasteringVoice, 0, 0, 0, index ) ) )
{
 

This code assumes you are only supporting WIndows Vista or later which supports WASAPI. If you still need to support Windows XP, you need to add an additional comparison in the search loop over XAudio2 device details values in the code above. On Windows XP, the deviceID from XAudio2 is a DirectSound GUID, while on Windows Vista and later it is a WASAPI Audio Endpoint Device Identifier.

#if (_WIN32_WINNT < _WIN32_WINNT_VISTA)
WCHAR szDSGUID[40];
swprintf_s( szDSGUID, L"{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}\n",
render.Data1, render.Data2, render.Data3,
render.Data4[0], render.Data4[1], render.Data4[2], render.Data4[3],
render.Data4[4], render.Data4[5], render.Data4[6], render.Data4[7] );
#endif


...


#if (_WIN32_WINNT < _WIN32_WINNT_VISTA)
if ( ::_wcsnicmp( details.DeviceID, szDSGUID, 40 ) == 0 )
break;
#endif

 The key work here takes place in DSoundtoMMEndpoint using WASAPI APIs and properties. Note that this function assumes you already iniitalized COM via CoInitializeEx.

 bool DSoundtoMMEndpoint( const GUID& guid, WCHAR* id, size_t maxsize, bool capture )
{
if ( memcmp(&guid, &GUID_NULL, sizeof(GUID)) == 0 )
return false;


IMMDeviceEnumerator* pEnumerator = nullptr;
HRESULT hr = CoCreateInstance( __uuidof(MMDeviceEnumerator), NULL, CLSCTX_INPROC_SERVER, __uuidof(IMMDeviceEnumerator), (void**)&pEnumerator );
if ( SUCCEEDED( hr ) )
{
IMMDeviceCollection* pCollection = nullptr;
hr = pEnumerator->EnumAudioEndpoints( (capture) ? eCapture : eRender, DEVICE_STATE_ACTIVE, &pCollection );
if ( SUCCEEDED( hr ) )
{
WCHAR szDSGUID[40];
swprintf_s( szDSGUID, L"{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}\n",
guid.Data1, guid.Data2, guid.Data3,
guid.Data4[0], guid.Data4[1], guid.Data4[2], guid.Data4[3],
guid.Data4[4], guid.Data4[5], guid.Data4[6], guid.Data4[7] );


UINT count = 0;
pCollection->GetCount( &count );

UINT index = 0;
for( ; index < count; ++index )
{
IMMDevice* pDevice = nullptr;
hr = pCollection->Item( index, &pDevice );
if ( SUCCEEDED( hr ) )
{
IPropertyStore* pProps = nullptr;
hr = pDevice->OpenPropertyStore( STGM_READ, &pProps );
if ( SUCCEEDED( hr ) )
{
PROPVARIANT varName;
PropVariantInit(&varName);

hr = pProps->GetValue( PKEY_AudioEndpoint_GUID, &varName );
if ( SUCCEEDED( hr ) && ::_wcsnicmp( szDSGUID, varName.pwszVal, 38 ) == 0 )
{
LPWSTR pStrId = nullptr;
hr = pDevice->GetId( &pStrId );
if ( SUCCEEDED( hr ) )
{
wcscpy_s( id, maxsize, pStrId );
CoTaskMemFree( pStrId );
break;
}
}

PropVariantClear(&varName);

pProps->Release();
}

pDevice->Release();
}
}


if ( index >= count )
hr = E_FAIL;

pCollection->Release();
}

pEnumerator->Release();
}

return SUCCEEDED(hr);

}

The legacy XInput 9.1.0 doesn't support headset audio, so if you make use of audio features for XInput devices you'll have to use either the Windows 8 in box XInput 1.4 or the legacy DirectX SDK XInput 1.3 release.

In a future post I'll cover how to make use of the capture device given that XAudio2 doesn't support audio capture. We'll make use of the new MediaCapture API on Windows 8, and the venerable waveIn otherwise.

Windows 8.x and GDFs

$
0
0
Windows 8 includes numerous improvements as discussed on the Building Windows 8 blog, the DirectX 11.1 Runtime (including WARP support for feature levels 11.1 and 11.0), and for game developers and publishers it includes some important updates to the Windows Family Safety / Parental Controls system for game ratings (see also the Building Windows 8 blog entry on the topic).
  • Includes support for four new ratings systems:
    • COB-AU - Classification Operations Board (Australia)
    • DJCTQ - Department of Justice (Brazil)
    • FPB - Film and Publication Board (South Africa)
    • OFLC-NZ Office of Film and Literature Classification (New Zealand)
  • The artwork for PEGI has been updated and two new descriptors (“Online” and “Gambling”) have been added.
  • Support for PEGI (Finland) and OFLC (Australia) rating systems have been removed as these rating systems are now deprecated. Finland now uses PEGI (rather than their own variant), and Australia uses COB-AU.
  • The artwork for CSRR has been updated, the "PG" rating is deprecated, "PG12" and "PG15" rating levels have been added, and there are now 10 content descriptors.

Windows 7: These updates to the rating systems apply to Windows 7 as well when KB2773072 has been installed. PEGI (Finland) and OFLC (Australia) are present after the update, but are marked deprecated in the UI as end-users are encouraged to switch to the newer systems.

Windows 8.1: This release includes two changes to the rating systems:

  • PCBP - Russian Age Rating System (Russia) is now supported.
  • PEGI/BBFC is no longer supported (UK uses standard PEGI)

Windows 8:KB 2838466 updates Windows 8 with support for PCBP (Russian Age Rating System)

Windows Store apps: See MSDN for details on Age ratings and rating boards, as well as this post

Windows phone apps: See MSDN for details about Game ratings

Game Definition File (GDF) Tools

The DirectX SDK has historically been the shipping vehicle for the various Game Explorer tools. With the transition to the Windows SDK (see Where is the DirectX SDK?), these tools now have new homes:

Game Definition File Editor (GDFMaker.EXE) is in the Windows 8.x SDK (included with Visual Studio 2012 and available standalone). It is located in the x86 directory under the bin folder. This version of the tool uses the ratings systems descriptions available on the version of Windows it is run on, rather than including a local copy as the older DirectX SDK version did. This means you should run it on Windows 8 be able to populate all the latest ratings information, although the tool can be run on Windows 7 as well only showing the rating systems available for Windows 7. The Windows SDK version requires .NET 4.x as well. This tool is used to author GDF files for both Win32 desktop and Windows Store apps.

Windows 8.1 SDK: There's an updated version of GDFMaker.EXE (included with VS 2013 and available standalone) that resolves a problem when run on English but not EN-US systems.

Game Definition File Validator (GDFTrace.EXE) is available on MSDN Code Gallery and has been updated for these latest rating systems changes and can build without requiring the DirectX SDK  using Visual Studio 2010 or Visual Studio 2012.

Gameux Install Helper (GameuxInstallHelper.DLL) is available on MSDN Code Gallery. It has been updated from the DirectX SDK (June 2010) version and can build without requiring the DirectX SDK using Visual Studio 2010 or Visual Studio 2012. This utility is used for deploying Win32 desktop applications.

Update: These tools are also included in the DirectX SDK samples repo on GitHub.

Application Compatibility

For publishers and developers of games on Windows 7, be sure to read Desktop Games for Windows 8 Consumer Preview for recommendations on compatibility for existing Win32 desktop style applications as well as the official Compatibility Cookbook.

 

Visual Studio 2012 and Windows 8.0 SDK RTM are now available

$
0
0

The Windows SDK for Windows 8 (aka Windows 8.0 SDK) RTM version is now available on MSDN. See Where is the DirectX SDK? for details on DirectX content in the Windows 8.0 SDK. This includes the D3DCompiler_46.DLL release of the HLSL compiler, DirectXMath version 3.03, DirectX 11.1 headers/libs, and the GDF tools.

The Windows 8.0 SDK is included with Visual Studio 2012 (build 50727.1), which is now available on the web. See the Visual Studio and VC blog announcements for more information, as well as the ReadMe.You can find a list of compiler bugs fixed,Standard Library bugs fixed, and MFC bugs fixed for Visual Studio 2012 as well. As noted on the VC Blog, support for targeting Windows XP with VS 2012 and the Desktop Express edition will be coming soon. The Visual C++ 2012 CRT redistributable packages are on MS Downloads.

Note that the RTM version of Windows 8 (build 9200) is available for download for developers with an MSDN Subscription or TechNet Professional Subscription. General availability will be on October 26, 2012. For developers of Windows Store apps (a.k.a. Metro style apps), details on migrating your application to the RTM version are covered in this migration guide. There was a change to the CSRR rating system between the Release Preview and RTM as well.

Update:VS 2012 Express for Windows Desktop is now available. Support for Windows XP is available with VS 2012 Update 1. See also VS 2012 Update 2, VS 2012 Update 3, and VS 2013 and Windows 8.1 SDK RTM.

System requirements: The Windows SDK for Windows 8 can be installed on Windows 7 and Windows 8. It's the same system requirements as Visual Studio 2012 which includes the new Windows SDK. You need Windows 8 to develop Windows Store apps, but you can use Windows 7 and the Windows SDK 8.0 for development of Win32 desktop applications for Windows 8, Windows 7, Windows Vista, and their Windows Server equivalents.

VS 2010 users: You can use the property sheets as described in the Visual C++ Team blog post to use the Windows 8.0 SDK. The .props files are attached to this post as well. Note you cannot target Windows XP with the Windows 8.0 SDK.

The VS team's instructions omit including the "include\winrt" directory under the assumption that those are for Windows Store apps only, but that's not strictly true. At a minimum, having access to #include <wrl/client.h> provides you the extremely useful Microsoft::WRL::ComPtr smart-pointer that works perfectly fine in Win32 desktop apps and down-level systems.

Direct3D Debug support: Installing VS 2012 or the Windows 8.0 SDK also installs the Direct3D 10.x and Direct3D 11.x SDK Debug Layers on Windows 7, Windows 8.0, and the Server Equivalents for using D3Dxx_CREATE_DEVICE_DEBUG. Note that this is not the correct version for Windows 8.1, see Visual Studio 2013 and Windows 8.1 SDK RTM are now available.

Dual-use Coding Techniques for Games, part 1

$
0
0

Writing shared code for Windows Store, Xbox One, and Win32 desktop apps

Introduction

Apps written for the Windows Store make use of the Windows Runtime (WinRT) and a restricted subset of Win32 APIs located in the core API family. Traditional Win32 desktop apps have access to a larger desktop API family, but this is subject to various levels of OS support required for each function. These two taken together can make it challenging to write shared code libraries and helper functions that can successfully compile for both Windows Store apps and Win32 desktop applications supporting Windows Vista, Windows 7, and Windows 8.x.

In general, applications should be written to target either the Windows Store or the Win32 desktop. Windows Store apps make use of a distinct UI, input, system-integration, and presentation model which is not supported for Win32 desktop applications even on the Windows 8 Desktop. Targeting the Windows RT (a.k.a. Windows on ARM) platform requires writing a Window Store app, while targeting down-level platforms such as Windows Vista and Windows 7 require writing Win32 desktop apps. Trying to address both of these with the same EXE is not possible, and each will have significant platform-specific code.

The purpose of this series of posts is to talk about the overlap, and how developers creating shared libraries and game middleware can write C++ code that will successfully compile for both platforms.

Windows phone and Xbox One: This article also applies to Windows phone 8.x and Xbox One development using the XDK or ADK (see ID@Xbox)

Windows 10: The guidance here applies to universal Windows apps for Windows 10 as well.

Win32 desktop appWINAPI_FAMILY_DESKTOP_APP

Windows Store app

universal Windows apps for Windows 10

WINAPI_FAMILY_APP (Windows 8.0 SDK)
or WINAPI_FAMILY_PC_APP (Windows 8.1 SDK)
Windows phone 8WINAPI_FAMILY_PHONE_APP
Xbox One XDKWINAPI_FAMILY_TV_TITLE
Xbox One ADKWINAPI_FAMILY_TV_APP

Compiler Toolsets and SDK Selection

To author Windows Store apps, developers must use Visual Studio 2012 which includes the Windows 8.0 SDK. This same toolset can be used to target Win32 desktop apps for Windows 8 (Desktop), Windows 7, and Windows Vista. For this article, the focus is on using this compiler toolset.

Visual Studio 2013 is used to target Windows Store apps for Windows 8.1 and includes the Windows 8.1 SDK. Visual Studio 2015 is used to target universal Windows apps for Windows 10 when using the the Windows 10 SDK. These comparison tables have been updated to compare the C++11 features with the newer compilers.

Note that with careful coding, it is possible to also support Visual Studio 2010 with the Windows 8.x SDK for building Win32 desktop apps. In some specific cases some extra functionality is needed that is otherwise handled by Visual Studio 2012’s C++11 Standard Library, and this means restricting language feature use to VS 2010’s C++0x support and avoiding the use of C++/CX language extensions.

C++11 Language FeatureVS 2010VS 2012VS 2013VS 2015
nullptrüüüü
static_assertüüüü
override / final*üüüü
Lambda expressionsüüüü
Rvalue referencesüüüü
decltypeüüüü
autoüüüü
Strongly typed enumerations üüü
Forward declared enumerations üüü
Ranged-based for loops üüü
Variadic templates  üü
Uniform initialization and initializer lists  üü
Delegating constructors  üü
Raw string literals  üü
Explicit conversion operators  üü
Default template arguments for function templates  üü
Alias templates  üü
Defaulted functions  üü
Deleted functions  üü
Non-static data member initializers (NSDMIs)  üü
Attributes, constexpr, ref-qualifiers, inheriting constructors,
char16_t, char32_t, Unicode string literals,
user-defined literals, extended sizeof, inline namespaces,
unrestricted unions, noexcept, thread_local, magic statics,
Universal character names in literals
   ü
C99: __func__, long long   ü
Expression SFINAEûûûUpdate 1

* = In VS 2010, final was implemented as sealed. Also note that VS 2010 considers override to be a MSVC extension and generates warning C4481.

Use of the older standalone DirectX SDK is not recommended or supported for Windows Store apps. It includes many legacy technologies that are not supported for this platform, and thus their use complicates the goal of ‘dual-use’ coding. See the blog posts “Where is the DirectX SDK?”, "Where is the DirectX SDK (2013 Edition)?", "Where is the DirectX SDK (2015 Edition)?", and “DirectX SDKs of a certain age” for more information.

C++11 Standard Library

The majority of the C++11 Standard Library is supported for both Windows Store apps and Win32 desktop apps. This provides a large breadth of functionality that is common and safe to use for ‘dual-use’ scenarios.

C++11 header

VS 2010

VS 2012

VS 2013VS 2015
<array>, <memory>, <random>, <regex>,
<tuple>, <type_traits>,
<unordered_map>, <unordered_set>
üüüü
<stdint.h>, cstdintüüüü

unique_ptr<T>

üüüü
cbegin(), cend(), crbegin(), crend()üüüü
<forward_list>üüüü
<algorithm> and <exception> updates
  • find_if_not, copy_if, is_sorted,etc.
  • exception_ptr
üüüü
<allocators>üüüü
<codecvt>üüüü
<system_error>üüüü
emplace(), emplace_front(), emplace_back(), etc. üüü

<chrono>*

 üüü
<ratio> üüü
<scoped_allocator> üüü
<atomic>, <condition_variable>, <future>, <mutex>,
<thread>
 üüü
<intializer_list>  üü

std::make_unique<T> (C++14)

  üü
C99: <stdbool.h>, <complex.h> / <ccomplex>,
<fenv.h> / <cfenv>,
<inttypes.h> / <cinttypes>,<ctgmath>
  üü
C99: <uchar.h> / <cuchar>   ü
C99: <tgmath.h>, some printf format specifiers   ü

* = Note that VS 2012 / VS 2013's high_resolution_clock has some known issues. This is fixed in VS 2015.

 

The majority of Visual C++ functions in the C Runtime are available for Windows Store apps, but there are some specific headers which are not fully available.

Visual C++ headerNotes
agents.h
concrt.h

The majority of the Concurrency Runtime (ConcRT) is available.
There is, however, no support for the advanced scheduler (i.e. schedule groups, contexts)

concrtrm.h

The Concurrent Runtime (ConcRT) resource manager is not available to Windows Store apps.

conio.h

No functions in this header are available

ctype.h, cctype

isleadbyte and _isleadbyte_l are not available

direct.h

Only _mkdir, _rmdir, _wmkdir, and _wrmdir are available

io.h

_pipe is not available

locale.h, clocale

Obsolete locale functions are not available

malloc.h

_resetstkoflw is not available.

mbctype.h, mbstring.h

All multi-byte (_ismb, _mb*) functions are not available.

process.h

Most process and DLL related functions are not available.
exit and abort are the only functions available for Windows Store apps.

stdio.h, cstdio

_pclose, _popen, _wpopen functions are not available.

stdlib.h, cstdlib

POSIX/DOS-style environment variables and related functions & types are not supported for Windows Store apps.
There is also no equivalent for _seterromode, _beep, or _sleep.

tchar.h

The _MBCS mode is not supported for Windows Store apps. You can only use _UNICODE.

time.h, ctime

System-time functions (_getsystime, _setsystime) are not available.
Note you can use Win32 APIs for GetSystemTime and GetLocalTime, but not set the time in a Windows Store app.

wchar.h, cwchar

codeisleadbyte, _Isleadbyte_l, _wgetcwd, and _getddcwd are not supported.

wctype.h, cwctype

Obsolete is_wctype is not supported.

Update: If you are interesting in using Boost, take a look at this blog post

Machine Architectures

Windows Store apps should compile for Windows x86 (32-bit), Windows x64 (64-bit) native, and Windows RT (ARM). Win32 desktop apps should compile for Windows x86 and Windows x64 native. Most C/C++ code should work fine across all platforms if using platform-neutral types.

  • Use portable types. Use size_t, ptrdiff_t, and the various <stdint.h> (<cstdint>) types (i.e. int8_t, uint8_t, int16_t, uint16_t, int32_t, uint32_t, int64_t, uint64_t, intptr_t, and uintptr_t).

  • Group pointers in structures and classes. Most data types do not change size when moving to x64 native, but pointers become 8 bytes (known as the “LLP64” data model). The default pack setting for x64 is 16 rather than 8 to ensure structures are padded to a natural alignment including pointers. Mixing pointers with other data types in structures results in more padding than would happen if the pointers were grouped together.

  • Prefer C++ style casts. Use of const_cast<>, static_cast<>, and reinterpret_cast<> rather than C-style casts can help highlight potential pointer-truncation issues more easily.

  • Use maximum warnings (/Wall). A number of warnings that tend to highlight 64-bit portability issues include C4302 and C4826 are off by default. You can disable specific warnings to reduce ‘noise’ as they are identified by #pragma warning or /wd.

  • Use /analyze. Static code analysis will highlight a number of issues, particularly using the incorrect printf format specifications--note that VS 2015 does checkprintf format specifications even without using /analyze, but it is not as extensive.

Inline assembly is not supported for x64 native or ARM compilation, so it should be avoided generally. You can make use of intrinsics instead. Avoid using MMX™ intrinsics (i.e. those from the mmintrin.h header or that operate with the __m64 type) to ensure the same code works for both x86 and x64 native. For ARM, there is a full set of intrinsics available in armintr.h and arm_neon.h.

The ability to write standalone assembly for all machine architectures is not supported for Windows Store apps for Windows 8.0 and requires the VS 2013 toolset with the Windows Driver Kit 8.1. Use of standalone assembly is not recommended for 'dual-use' code.

When writing architecture-specific code, make use of the _M_IX86 (32-bit), _M_X64 (64-bit), and _M_ARM machine architecture defines for conditional compilation. All three are “Little Endian” platforms (Windows RT included).

Note: The VS 2012, VS 2013, and VS 2015 toolsets support x86, x64, and ARM. VS 2010 has no support for ARM targets.

Exception-Safe Coding

Windows Store apps make use of C++ exception handling and are compiled with /EHsc. Many Win32 desktop applications use HRESULTs and do not enable exception handling of any kind, although some do use it. Dual-use shared code can use HRESULTs or other error codes and leave the decision to use exception handling to the client code. (See DirectXTex for an example of this approach.) Alternatively, dual-use shared code can throw either C++ standard exceptions or Windows Store app Platform exceptions through specific compiler techniques. (See DirectXTK for an example of this approach.)

Since dual-use code can be used in the context of exception handling, it is strongly recommended that you make use of ‘exception-safe’ coding practices. C++ exception handling takes advantage of the language and ensures that objects are properly destructed when leaving scope normally or when processing an exception. When using the C++11 Standard Library, those containers are already written to be ‘exception-safe’.

The main area where this impacts ‘dual-use’ shared code and C++ code in general is when allocating resources. The guidance here is to never rely on calling delete, delete [], CloseHandle, Release, etc. directly but have the destructor of a class instance handle it automatically. This technique is known as Resource Acquisition Is Initialization (RAII). This ensures that the code will behave well both in normal operation and in the cases where exception handling is used. The C++11 Standard Library provides a number of classes that make implementing this pattern fairly straight-forward.

Traditional C++Exception-safe C++
MyObject *obj = new MyObject;

std::unique_ptr<MyObject> obj(new MyObject);

-or-

auto obj = std::make_unique<MyObject>();

Note: VS 2013 or later includes std::make_unique<T>, but it is not available in older toolsets.

-or-

std::shared_ptr<MyObject> obj = std::make_shared<MyObject>();

BYTE* buffer = new BYTE[ 2048 ];

std::array<uin8_t, 2048> buffer;

-or-

std::unique_ptr<uin8_t[]> buffer( new uint8_t[2048]; )

float* buffer = _aligned_malloc( 2048, 16 );struct aligned_deleter
{
void operator()(void* p)
{ _aligned_free(p); }
};

std::unique_ptr<float, aligned_deleter> buffer( _aligned_malloc(2048,16)) ;
HANDLE h = CreateFile(…);
if ( h == INVALID_HANDLE)
// error
struct handle_closer
{
void operator()(HANDLE h)
{
assert(h != INVALID_HANDLE_VALUE);
if (h) CloseHandle(h);
}
};

inline HANDLE safe_handle( HANDLE h )
{
return (h==INVALID_HANDLE_VALUE) ? 0:h;
}

std::unique_ptr<void, handle_closer>
hFile( safe_handle( CreateFile(…) ) );
if ( !hFile )
// error
CRITICAL_SECTION cs;
InitializeCriticalSection(&cs);
EnterCriticalSection(&cs);

LeaveCriticalSection(&cs);
std::mutex m;
{
std::lock_guard lock(m);
/* lock on m held until end of scope */
}
ID3D11InputLayout* inputLayout = NULL;

device->CreateInputLayout( …, &inputLayout );

SAFE_RELEASE(inputLayout);
#include <wrl/client.h>
 
using Microsoft::WRL::ComPtr;
ComPtr<ID3D11InputLayout> inputLayout;

device->CreateInputLayout(…, &inputLayout );

-or-

device->CreateInputLayout(…, inputLayout.ReleaseAndGetAddressOf() )

When building with the Windows 8.x SDK for both Win32 desktop applications and Windows Store apps you can use Windows Runtime Library’s ComPtr. This is similar to ATL’s CComPtr. See this page for more information.

When passing these objects to other functions, you can use .get() on the smart pointer on each call and pass the parameter as a raw pointer, or you can pass the smart pointer object directly. When using smart pointer objects as parameters, pass them by constant reference, similar to other STL containers, in order to avoid additional temporary copies and to avoid excessive reference count increment and decrement cycles.

The use of this ‘exception-safe’ pattern has the added benefit of ensuring you do not need to make use of explicit try / catch blocks in your code to handle resource cleanup. This contributes to keeping ‘dual-use’ code agnostic to the use of Exception Handling while still being ‘exception-safe’ when it is used.

Visual C++: If you call new, then by default it will throw a C++ exception for out-of-memory conditions per the C++ Standard. If you want to explicitly check for null instead, then you must use new (std::nothrow) instead. See this blog post as well.

ThrowIfFailed: Modern Microsoft samples make use of a helper ThrowIfFailed which generates a C++ exception if an HRESULT is a failure. This is intended as a 'fatal fast fail', and generally simplifies COM-based code handling. See this page for usage and implementation notes.

(continued in part 2)


Dual-use Coding Techniques for Games, part 2

$
0
0

Writing shared code for Windows Store and Win32 desktop apps

(continued from part 1)

Win32 APIs

The majority of the “core” API family are new Windows Runtime (WinRT) style APIs which are not available for down-level Win32 desktop applications. Therefore the overlap is in Win32 APIs that are available to both kinds of applications. In many cases, the Windows Store apps ‘core’ API family contains a Win32 API that is very recent. Therefore, a key technique for writing dual-use code properly is learning to leverage the _WIN32_WINNT control define for Windows Headers.

  • For Windows 8.1 support, _WIN32_WINNT is 0x0603 which is the default with the Windows 8.1 SDK / VS 2013 and is the value you expect to use for Windows Store apps for Windows 8.1 and Windows phone 8.1.

  • For Windows 8.x support, _WIN32_WINNT is 0x0602 which is the default with the Windows 8.0 SDK / VS 2012 and is the value you expect to use for Windows Store apps for Windows 8.0, Windows phone 8.0, and Xbox One.

  • For Windows 7 and Windows 8.x Win32 desktop support, _WIN32_WINNT should be 0x0601.

  • For Windows Vista, Windows 7, and Windows 8.x Win32 desktop support, _WIN32_WINNT should be 0x0600.

  • For Windows XP SP3 or Windows Server 2003 SP2, you must set _WIN32_WINNT to 0x0501 and use a Platform Toolset of "v110_xp" or "v120_xp" which selects the Windows 7.1 SDK that has limited DirectX integration. The Windows 8.x SDK does not support any platform prior to Windows Vista.

Windows 10: For Windows 10 support, _WIN32_WINNT is 0x0A00 which is the default with the Windows 10 SDK / VS 2015 and is the value you expect to use for universal Windows apps.

Note: There are defines for these version constants, but be aware of the mix of Windows SDK versions you are building your code against. For example, _WIN32_WINNT_WIN10 is only defined for Windows 10 SDK, _WIN32_WINNT_WINBLUE is missing from the Windows 8.0 SDK, and _WIN32_WINNT_WIN8 is not in the Windows 7.1 SDK. You can define your own symbol if it is not already defined, but particularly in 'public' headers the direct use of the version numbers is the most robust choice.

Note: For Win32 APIs, you should prefer the use of the standard _WIN32_WINNT control define to conditional compile for Windows Store apps rather than symbol trying to make use of WINAPI_FAMILY macros directly.

For example, for Windows Store apps CreateFile2 must be used which is a Windows 8 only API. For down-level support, you will want to use CreateFile.

 #if (_WIN32_WINNT >= 0x0602 /*_WIN32_WINNT_WIN8*/)

ScopedHandle hFile( safe_handle(
CreateFile2( szFile, GENERIC_READ, FILE_SHARE_READ,
OPEN_EXISTING, nullptr ) ) );

#else

ScopedHandle hFile( safe_handle(
CreateFile( szFile, GENERIC_READ, FILE_SHARE_READ, nullptr,
OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, nullptr ) ) );

#endif

if ( !hFile )
{
return HRESULT_FROM_WIN32( GetLastError() );
}

Note: There's one more detail in this particular case. For Windows Store apps, the typical default dwShareMode of 0 is likely to cause problems when you are trying to open a file for read-only access because ‘exclusive’ mode is only granted for files which the app has write privileges. If using a dwDesiredAccess of GENERIC_READ, you want to use dwShareMode of FILE_SHARE_READ as shown here.

Dual-use shared code should always make use of Unicode to support Windows Store apps (UNICODE and _UNICODE are defined) and is fully supported on down-level Win32 desktop apps. Universal use of Unicode and wchar_t is recommended, although TCHAR is still available if legacy ASCII/multi-byte support is required for some Win32 desktop scenario.

Here are a number of Win32 APIs that are available to Windows Store apps when using the latest version.

Older API“Core” Win32 API_WIN32_WINNT Required
GetDiskFreeSpaceGetDiskFreeSpaceEx 
GetFileAttributesGetFileAttributesEx 
FindFirstFileFindFirstFileEx 
LockFileLockFileEx 
MoveFileMoveFileEx 
SetFilePointerSetFilePointerEx 
UnlockFileUnlockFileEx 
WaitForMultipleObjects*WaitForMultipleObjectsEx 
WaitForSingleObject*WaitForSingleObjectEx 
CreateEvent*CreateEventEx0x0600 (Windows Vista)
CreateMutex*CreateMutexEx0x0600 (Windows Vista)
CreateSemaphore*CreateSemaphoreEx0x0600 (Windows Vista)
GetFileSize
GetFileSizeEx*
GetFileInformationByHandleEx0x0600 (Windows Vista)
GetTickCount
timeGetTime
GetTickCount640x0600 (Windows Vista)
InitializeCriticalSection*
InitializeCriticalSectionAndSpinCount*
InitializeCriticalSectionEx0x0600 (Windows Vista)
CopyFile, CopyFileExCopyFile20x0601 (Windows 7)
CoCreateInstance*
CoCreateInstanceEx*
CoCreateInstanceFromApp0x0602 (Windows 8)
CreateFileCreateFile20x0602 (Windows 8)
CreateFileMapping*CreateFileMappingFromApp0x0602 (Windows 8)
GetOverlappedResultGetOverlappedResultEx0x0602 (Windows 8)
MapViewOfFile*
MapViewOfFileEx
MapViewOfFileFromApp0x0602 (Windows 8)

Windows 10: The APIs denoted by * above were added back for universal Windows apps for Windows 10 to reduce porting changes.

Note: ReadFile and WriteFile are available for Windows Store apps and Windows phone 8, but ReadFileEx and WriteFileEx are not.

Here are some additional notes on Win32 APIs commonly used by games.

Win32 API

Description

CreateThread
SetThreadIdealProcessor
SetThreadPriority
Sleep(Ex)
TlsAlloc

Windows Store apps for Windows 8.0 do not support POSIX-style threading APIs. These applications must use the Windows Runtime (WinRT) ThreadPool API in Windows.System.Threading.

For dual-use coding, you can make use of the C++11 Standard Library threading support and/or the Concurrency Runtime (ConcRT) which is supported for both Windows Store apps and Win32 desktop apps.

Update: Windows Store apps for Windows 8.1 can now use these threading APIs as of VS 2013 Update 4. They are also supported for Windows phone 8.1, Xbox One apps, and universal Windows apps for Windows 10.

CreateProcess
GetCommandLine
GetEnvironmentStrings

Windows Store apps do not support POSIX-style process, command-line or environment variable APIs. These applications must use the Launcher class in the Windows.System namespace.

Note: Xbox One XDK supports some of these Win32 process APIs.

FindResource(Ex)
LoadResource
LockResource

etc.

Windows Store apps do not use Win32 style resource files. The recommendation is to include the required data as part of the AppX package and use standard file I/O to access them.

RegOpenKey(Ex)
RegQueryKey(Ex)
RegSetKey(Ex)

etc.

Windows Store apps do not use the Win32 registry. The recommendation is to store settings data in the application local directory using standard file I/O.

GlobalMemoryStatus(Ex)

There is no Windows Store app function available that will return physical or virtual memory information.

HeapAlloc

This is the standard memory allocation routine family is available for all applications.

LocalAlloc, GlobalAlloc are only available for Win32 desktop applications..

VirtualAlloc is not available for Windows 8.x Store apps or Windows phone 8.x apps.

Note: Xbox One XDK does support VirtualAlloc but does not allow EXECUTE page-level permission.

Windows 10: VirtualAlloc is supported for universal Windows apps for Windows 10 as a remap for the new VirtualAllocFromApp.

LoadLibrary(Ex)

Windows Store apps must use LoadPackagedLibrary and the target DLL must be present in the application package or listed in the AppX manifest. The target DLL must therefore pass the Windows App Certification Kit (WACK) tool validation.

You have to use implicit linking with system DLLs, although you can use /DELAYLOAD if desired.

LoadString

Windows Store apps do not use Win32 style resource files for localization. These applications use ResourceLoader in the Windows.ApplicationModel.Resources namespace. See MSDN for more details.

Dual-use shared code should avoid directly displaying strings and should leave localization to the client application.

GetLogicalProcessorInformation

Windows store apps can't call GLPI. They can use GetNativeSystemInfo to get a rough count of the number of logical processors.

OpenGL

OpenGL is not supported for Windows Store apps, Windows phone 8.x, Xbox One, or universal Windows apps for Windows 10.

Note: For OpenGL ES applications, you may find the Angle project useful.

QueryPerformanceCounter
QueryPeformanceFrequency

These functions are supported for all applications as the basis for high-resolution timers.

timeBeginPeriod
timeEndPeriod

Windows Store apps cannot change the global system timer resolution as this can negatively impact power-saving modes.

WinSock

The Windows Sockets 2 API is not available for Windows Store apps for Windows 8.0 and they must use the Windows Runtime (WinRT) API Windows.Networking.Sockets instead. TCP and UDP layer network communications are therefore not a good candidate for dual-use shared code, although an abstraction could be written with two different implementations.

Update: Windows Store apps for Windows 8.1 can now use WinSock 2.x as of VS 2013 Update 3. See this post. Winsock 2.x is also supported for Windows phone 8.x, Xbox One apps, and universal Windows apps for Windows 10. Note that this support requires an IP-neutral dual-stack implementation (i.e. not legacy IPv4 only)

DirectPlay is not supported for Windows Store apps, Windows phone 8.x, Xbox One, or universal Windows apps for Windows 10. DirectPlay is not recommended for Win32 desktop apps.

DirectX and Media Technologies

One of the reasons that dual-use shared code is possible for game technology is because many of the traditional DirectX Win32 APIs are available for Windows Store apps as well as down level for Win32 desktop apps.

DirectX TechnologyNotes
Direct3D 11.0, DXGI 1.1, Direct2D, and DirectWrite

These technologies are available for Windows Store apps, universal Windows apps for Windows 10, and Win32 desktop apps for Windows 10, Windows 8.x, Windows 7, and Windows Vista SP2+KB971644.

Direct3D 9 and Direct3D 10.x are not supported for Windows Store apps, Windows phone 8.x, universal Windows apps for Windows 10, or Xbox One.

Note: Windows phone 8.0 and Xbox One XDK do not support Direct2D or DirectWrite.

Direct3D 11.1, DXGI 1.2, improved Direct2D and DirectWrite

These technologies are available for Windows Store apps, universal Windows apps for Windows 10, and Win32 desktop apps on Windows 8.x and Windows 10. Partial support for these APIs is available for Win32 desktop applications on Windows 7 Service Pack 1 via KB 2670838.

Windows Store apps can rely on these technologies always being present, while Win32 desktop applications need to provide suitable fallbacks for older versions of Windows.

Direct3D 11.2, DXGI 1.3

These technologies are available for Windows Store apps, universal Windows apps for Windows 10, and Win32 desktop apps for Windows 8.1 and Windows 10.

Windows Store apps for Windows 8.1 can rely on these technologies always being present, while Win32 desktop applications need to provide suitable fallbacks for older versions of Windows.

Note: Windows phone 8.0 and Xbox One XDK do not support Direct3D 11.2 / DXGI 1.3

Diret3D 12, Direct3D 11.3, DXGI 1.4

These technologies are available for universal Windows apps for Windows 10 and Win32 desktop apps for Windows 10.

Universal Windows apps for Windows 10 can rely on these technologies always being present, while Win32 desktop applications need to provide suitable fallbacks for older versions of Windows.

D3DX

All versions of the D3DX utility library (D3DX9, D3DX10, and D3DX11) are deprecated, and are not supported for Windows Store apps, Windows phone 8, Xbox One, or universal Windows apps for Windows 10.

DirectXTK, DirectXTex, and DirectXMesh support Windows Store apps, universal Windows apps for Windows 10, Windows phone 8.x, Xbox One, and Win32 desktop applications on Windows 10, Windows 8.x, Windows 7, and Windows Vista. These provide replacements for much of the functionality in D3DX for Direct3D 11. See "Direct3D 11 Textures and Block Compression" for more information.

The D3DCSX Compute Shader helper utility is available for Win32 desktop applications, but not for Windows Store apps or Windows phone 8.

HLSL Compiler / D3DCompile

The HLSL compiler (FXC.EXE) and the D3DCompile (D3DCompiler_*.DLL) APIs are supported for both Windows Store apps and Win32 desktop apps.

Note that for Windows Store apps on Windows 8.0 and Windows phone 8.0, the HLSL compiler / D3DCompile APIs are only supported for development and not for deployment.

Windows Store apps for Windows 8.1, Windows Phone 8.1, Xbox One, and universal Windows apps for Windows 10 have complete support for D3DCompile APIs. See “HLSL, FXC, and D3DCompile” for more information.

Effects 11 (FX11)

The Effects 11 technology relies on runtime shader reflection via D3DReflect in the D3DCompiler. Due to the limitations above, this makes Effects 11 library unsuited to use in Windows Store apps for Windows 8.0 or Windows phone 8.0.

Note: HLSL Compiler support for the fx_5_0 profile required to use Effects 11 is deprecated.

DirectXMath

The DirectXMath library is supported for Windows Store, universal Windows apps for Windows 10, Windows phone 8.x, Xbox One, and Win32 desktop apps. This library provides SSE/SSE2 optimizations for Windows x86 and x64 native, as well as ARM-NEON optimizations for Windows RT and Windows phone 8.x. See “Introducing DirectXMath” for more information.

Note: DirectXMath on Xbox One also makes use of SSE3, SSSE3, SSE 4.1, AVX, and F16C as described in this blog series.

XAudio2

Windows 8.x and Windows 10 includes XAudio 2.8 which is supported for Windows Store apps, universal Windows apps for Windows 10, Windows phone 8.x, and Xbox One. See “XAudio2 and Windows 8” for more details.

Windows Core Audio (WASAPI) is also available for use by low-level audio libraries.

DirectSound is not supported for Windows Store apps, Windows phone 8.x, Xbox One, or universal Windows apps for Windows 10.

XINPUT

Windows 8.x and Windows 10 includes XInput 1.4 which is supported for Windows store apps and Win32 desktop apps. Windows Vista, Windows 7, Windows 8.x, and Windows 10 also include XInput 9.1.0 which is supported for Win32 desktop applications. See “XInput and Windows 8” for more details.

DirectInput is not supported for Windows Store apps, universal Windows apps for Windows 10, Windows phone 8.x, or Xbox One

Note: XINPUT is not supported by Windows phone 8.x or Xbox One.

Xbox One and universal Windows apps for Windows 10 make use of a WinRT gamepad API which has similar functionality.

Windows Imaging Component (WIC)

This technology is available for Windows Store apps, universal Windows apps for Windows 10, and Win32 desktop apps for Windows 10, Windows 8, Windows 7, and Windows Vista. Be sure to set the _WIN32_WINNT definition properly to ensure use of the correct version of the WIC factory. See "Windows Imaging Component and Windows 8" for more information.

Note: Windows phone 8.0 does not support WIC, but this is supported for Windows phone 8.1. Xbox One XDK does not support the JPEG XR / HD Photo codec and a few other aspects of 'standard' WIC.

Windows Media Foundation (MF)

The Windows Media Foundation is available for Windows Store apps, universal Windows apps for Windows 10, and Win32 desktop applications on Windows 10, Windows 8, Windows 7, and Windows Vista. Be sure to read this post for some additional guidance.

DirectShow is not supported for Windows Store apps, Windows phone 8.x, Xbox One, or universal Windows apps for Windows 10.

Note: Windows phone 8.0 has partial support for the Media Foundation API, specifically IMFMediaEngine. Xbox One XDK also has partial support for the Media Foundation API.

 

(continued in part 3)

Dual-use Coding Techniques for Games, part 3

$
0
0

Writing shared code for Windows Store and Win32 desktop apps

(continued from part 1 and part 2)

Windows Runtime (WinRT) APIs

There are a number of areas of the system where you must use WinRT APIs to access the required functionality for Windows Store apps, and there is no Win32 equivalent included in the Windows Store apps API family. This code is not a good candidate for dual-use scenarios, but there are times when it makes sense to house both the WinRT and Win32 implementation in the same module. Generally you should prefer to have the client application handle this platform-specific functionality and provide the information needed to your dual-use shared code as parameters, but this is not always convenient or practical.

This scenario is one where you have to make use of the WINAPI_FAMILY macro to determine if you are building for Windows Store apps or Win32 desktop apps. There are a number of ways to do this, and most of them are subtly incorrect. The system headers make extensive use of the WINAPI_FAMILY_PARTITION macro available in <winapifamily.h>, however, as the exact make-up of partitions is subject to change with the introduction of new families over time, the recommendation is to only take dependencies on the FAMILY macros.

 #if !defined(WINAPI_FAMILY) || (WINAPI_FAMILY == WINAPI_FAMILY_DESKTOP_APP)
// This code is for Win32 desktop apps
#else
// This code is for Windows Store or Windows phone apps
#endif

In some cases when writing code for Windows phone apps, you may need to handle a difference from Windows Store apps. In this case, you can use this guard.

 #if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP)
// This code is for Windows phone apps only
#endif

Alternatively, you may want to support contexts without the Windows 8.0 SDK such as using the Windows 7.1 SDK for Windows XP support. In this case requiring an explicit build configuration (such as /DBUILDING_FOR_DESKTOP in the project settings for Win32 desktop usage) is the easiest and cleanest solution.

 #ifdef BUILDING_FOR_DESKTOP
// This code is for Win32 desktop apps
#else
// This code is for Windows Store apps
#endif

Note that for Xbox One, you should make use of the _XBOX_ONE and _TITLE defines (both are defined the Xbox One XDK, just _XBOX_ONE is defined for the Xbox One ADK).

The __cplusplus_winrt control define can be a useful way to isolate C++/CX language extensions as well, and this define is active whenever building with /ZW (the default for Windows Store app projects). It is, however, possible to be building for a Windows Store app without the /ZW switch (such as in a static library), so the #ifndef __cplusplus_winrt case can still be for a Windows Store app. Thus it is not a substitute for the logic above with the WINAPI_FAMILY control define for determining when building for the Windows Store vs. Win32 desktop.

 #if !defined(WINAPI_FAMILY) || (WINAPI_FAMILY == WINAPI_FAMILY_DESKTOP_APP)
// This code is for Win32 desktop apps
#elif !defined (__cplusplus_winrt)
#error This module requires WinRT C++/CX language support (/ZW)
// This code is for WinRT Windows Store apps
#endif

For example, here is some utility code for getting access to the proper path for a temporary file folder. This code builds for Windows Store apps using /ZW and for Win32 desktop apps.

 void GetTemporaryDirectory( wchar_t* dir, size_t maxsize )
{
if ( !maxsize ) return;
*dir = 0;
#if !defined(WINAPI_FAMILY) || (WINAPI_FAMILY == WINAPI_FAMILY_DESKTOP_APP)
DWORD nChars = GetTempPath( maxsize, dir );
if ( nChars > 0 )
dir[nChars-1] = '\0'; // Trim trialing '\'
else
*dir = 0;
#else // Windows Store WinRT app
auto folder = Windows::Storage::ApplicationData::Current
->TemporaryFolder;
wcscpy_s( dir, maxsize, folder->Path->Data() );
#endif // WINAPI_FAMILY_PARTITION
}

Here is a similar function that gets the application local data folder for the Windows Store app using /ZW or for Win32 desktop apps using the Windows Vista IKnownFolder API.

 void GetApplicationDataDirectory( wchar_t* dir, size_t maxsize )
{
if ( !maxsize ) return;
*dir = 0;
#if !defined(WINAPI_FAMILY) || (WINAPI_FAMILY == WINAPI_FAMILY_DESKTOP_APP)
Microsoft::WRL::ComPtr<IKnownFolderManager> mgr;
HRESULT hr = CoCreateInstance( CLSID_KnownFolderManager,
nullptr, CLSCTX_INPROC_SERVER, IID_IKnownFolderManager, (LPVOID*)&mgr );
if (SUCCEEDED(hr))
{
Microsoft::WRL::ComPtr<IKnownFolder> folder;
hr = mgr->GetFolder( FOLDERID_LocalAppData, &folder );
if (SUCCEEDED(hr))
{
LPWSTR szPath = 0;
hr = folder->GetPath( 0, &szPath );
if (SUCCEEDED(hr) )
{
wcscpy_s( dir, maxsize, szPath );
wcscat_s( dir, maxsize, L”\\MyUniqueApplicationName”);
CreateDirectory( dir, nullptr );
CoTaskMemFree( szPath );
}
}
}
#else // Windows Store WinRT app
auto folder = Windows::Storage::ApplicationData::Current
->LocalFolder;
wcscpy_s( dir, maxsize, folder->Path->Data() );
#endif
}

Note: This code assumes that CoInitialize(Ex) was already called by the client application.

Remember that Windows Store apps have a very restricted set of security privileges and access to the hard disk is tightly controlled. You should assume you only have read access to the files included in the AppX package for the Windows Store or the install location in “Program Files” for Win32 desktop apps. You should assume you only have read/write access to a temporary folder, the application local data folder, the application roaming data folder, and only other folders in special permissions scenarios (which may be read-only instead of read-write).

Windows::Storage:: ApplicationData propertyIKnownFolder equivalentSHGetFolderPath equivalent
LocalFolderFOLDERID_LocalAppData
+ unique folder name
CSIDL_LOCAL_APPDATA
+ unique folder name
RoamingFolderFOLDERID_RoamingAppData
+ unique folder name
CSIDL_APPDATA
+ unique folder name

Note: There’s no direct equivalent to LocalSettings or RoamingSettings for Win32 desktop apps.

See File access and permissions in Windows Runtime apps

Resources

Scott Meyers. More Effective C++. Addison-Wesley, 1996. Print.

C++: New Standard Concurrency Features in Visual C++ 11, MSDN Magazine (March 2012)

X64 Primer: Everything You Need To Know To Start Programming 64-Bit Windows Systems, MSDN Magazine (May 2006)

BUILD 2012 Conference

$
0
0

Windows Imaging Component and Windows 8

$
0
0

There are a number of new features and some bugs fixed in the Windows Imaging Component for Windows 8. With the installation of KB 2670838 this new version of WIC is also available on Windows 7 Service Pack 1.

The Windows 8.0 SDK contains the latest version of the headers needed to build with the new version of WIC. The behavior of wincodec.h changes depending your build-settings. If you build with _WIN32_WINNT set to 0x602 or later, then WINCODEC_SDK_VERSION, CLSID_WICImagingFactory, and CLSID_WICPngDecoder are set to use "WIC2" by default. Otherwise, it uses the old "WIC1" version. This means Windows Store apps and Win32 desktop applications built for Windows 8 only are already using the new version of WIC. No muss. No fuss. Win32 desktop applications built for older versions of Windows continue to use "WIC1" and the old behaviors are maintained.

If, however, you want to use "WIC2" when it is available but successfully fall back to "WIC1" on Windows Vista or Windows 7 without the KB 2670838 update, then things get a little tricky. The _WIN7_PLATFORM_UPDATE define 'opts-in' to the Windows 8 header behavior without requiring you set your _WIN32_WINNT define in a way that doesn't support older versions of Windows. You will want to avoid using WINCODEC_SDK_VERSION, CLSID_WICImagingFactory, and CLSID_WICPngDecoder and instead use the explicit 'version' ones. You also need to be careful when using the four new WIC pixel format GUIDs (GUID_WICPixelFormat32bppRGB, GUID_WICPixelFormat64bppRGB, GUID_WICPixelFormat96bppRGBFloat, and GUID_WICPixelFormat64bppPRGBAHalf) as they are not valid for use with "WIC1" APIs.

For example, here is how you should be creating the WIC factory for Win32 desktop applications that support older versions of Windows:

 #define _WIN7_PLATFORM_UPDATE
#include <wincodec.h>

// CoInitializeEx needs called at some point before this

IWICImagingFactory* wicFactory = nullptr;
HRESULT hr = CoCreateInstance(CLSID_WICImagingFactory2, nullptr, CLSCTX_INPROC_SERVER, __uuidof(IWICImagingFactory2), reinterpret_cast<LPVOID*>( &wicFactory ) );
if ( SUCCEEDED(hr) )
{
// WIC2 is available on Windows 8 and Windows 7 SP1 with KB 2670838 installed
// Note you only need to QI IWICImagingFactory2 if you need to call CreateImageEncoder
}
else
{
hr = CoCreateInstance(CLSID_WICImagingFactory1, nullptr, CLSCTX_INPROC_SERVER, __uuidof(IWICImagingFactory), reinterpret_cast<LPVOID*>( &wicFactory ) );
}

This results in the application using the new "WIC2" behaviors when available, but falls back to the older versions of WIC when it's not available.

DirectXTK and DirectXTex were both recently updated to support "WIC2" when it is available. This includes use of new WIC pixel formats ( GUID_WICPixelFormat96bppRGBFloat is the most useful since it matches DXGI_FORMAT_R32G32B32_FLOAT ), opts into the new Windows BMP BITMAPV5HEADER support (which encodes 32-bit with alpha channels for GUID_WICPixelFormat32bppBGRA and reads such BMP files as well), and can make use of the fix to the TIFF decoder for 96bpp floating-point images (which load as GUID_WICPixelFormat96bppRGBFloat).

Windows phone: Note that the Windows phone 8.0 platform does not support the WIC API, but Windows phone 8.1 does include it.

Xbox One: The Xbox One platform includes "WIC2". The HD Photo / JPEG XR codec is not currently supported for Xbox One XDK development.

VS 2012 Update 1: When building with the "v110_xp" Platform Toolset, the WIC2 header content is not available so avoid the use of _WIN7_PLATFORM_UPDATE for these configurations.

Windows 8.1: There are a few additional changes to WIC with Windows 8.1 including support for a limited DDS codec. See MSDN.

Direct3D SDK Debug Layer Tricks

$
0
0

When programming graphics applications, one of the more frustrating aspects of development is that you can end up writing thousands of lines of code and when you run it, all you get is a blank screen. Or maybe a blue screen. Or a crash. But often, not actually a useful image. Errors in state setting, transformation math, and other coding problems can mean your application is completely valid just not useful. Other kinds of coding problems are due to misuse or abuse of the Direct3D API itself. In those cases, enabling the 'debug' device can quickly help identify the problems.

With Direct3D 9 and older versions of the API, there was a "Developer Runtime" installed by the (now legacy) DirectX SDK and the DirectX Control Panel was used to switch the debug support on an off. This worked reasonably well in a world where only the running application was using Direct3D, but starting with Windows Vista this 'global' option was no longer feasible since the OS itself was using Direct3D. Even on the older systems, people would install the DirectX SDK, enable the debugging, and then forget about and find all their games would go really slowly.

Staring with Direct3D 10.0, a new mechanism was created for the "Developer Runtime" via a API layering mechanism and is implemented in the D3D10SDKLAYERS.DLL. Developers could opt in their specific application to the debug validation either by creating the device with D3Dxx_CREATE_DEVICE_DEBUG, or by adding the executable to a list in the DirectX Control Panel. This layering mechanism is also used as a way to improve performance, with the non-debug version of the API doing fairly minimal parameter validation leaving the really detailed diagnostics and validation to the debug layer and only doing it when a developer was wanting the additional debug checking done.

This same system is still in place for Direct3D 11.0 (D3D11SDKLAYERS.DLL) and 11.1 (D3D11_1SDKLAYERS.DLL). It is highly recommended that developers make use of the debug layer to validate their Direct3D 11.x-based applications, paying particular attention to CORRUPTION and ERROR level messages. These are often indicators of severe problems lurking in your code, and could help avoid support issues once your application is deployed. The WARNING and INFO level messages can also be very useful. That said, sometimes there are warnings that are not as useful. Just like with compiler warnings, learning to ignore them as 'noise' can result in missing more actionable messages. Therefore, you should consider having your application suppress 'known' messages and the like whenever the debug device is active.

A common error comes from making use of the Object Naming feature to improve the debugging of you resources with the debug device, VS 2012 graphics debugging, and the legacy PIX for Windows tool.

 D3D11 WARNING: ID3D11Texture2D::SetPrivateData: Existing private data of same name with different size found!
[ STATE_SETTING WARNING #55: SETPRIVATEDATA_CHANGINGPARAMS]

This could be an important message in some cases, but likely not for cases where you are using WKPDID_D3DDebugObjectName. There may be other warnings your code generates which are also harmless. This can be solved with some code just after you create your device. This code should probably be excluded from your 'production' build for final release, but for testing you may want it in Release builds in cases where the tester turns on debugging manually (such as via the DirectX Control Panel) which is why I'm not showing it in an #ifdef _DEBUG block. Also, for debug builds it is useful for the application to trigger a break-point for the severe cases of CORRUPTION and ERRORs, which is the code I'm showing as #ifdef _DEBUG here. Finally, remember that on 'end-user' systems and standard OS installs, the debug layer creation fails without the appropriate SDK Layers DLL.

For Win32 desktop applications, this code looks like:

 ...
#ifdef _DEBUG
deviceCreationFlags |= D3D11_CREATE_DEVICE_DEBUG;
#endif
...
...deviceCreationFlags is passed to D3D11CreateDevice as 'Flags' which is the fourth parameter
...
ID3D11Debug *d3dDebug = nullptr;
if( SUCCEEDED( d3dDevice->QueryInterface( __uuidof(ID3D11Debug), (void**)&d3dDebug ) ) )
{
ID3D11InfoQueue *d3dInfoQueue = nullptr;
if( SUCCEEDED( d3dDebug->QueryInterface( __uuidof(ID3D11InfoQueue), (void**)&d3dInfoQueue ) ) )
{
#ifdef _DEBUG
d3dInfoQueue->SetBreakOnSeverity( D3D11_MESSAGE_SEVERITY_CORRUPTION, true );
d3dInfoQueue->SetBreakOnSeverity( D3D11_MESSAGE_SEVERITY_ERROR, true );
#endif

D3D11_MESSAGE_ID hide [] =
{
D3D11_MESSAGE_ID_SETPRIVATEDATA_CHANGINGPARAMS,
// Add more message IDs here as needed
};

D3D11_INFO_QUEUE_FILTER filter;
memset( &filter, 0, sizeof(filter) );
filter.DenyList.NumIDs = _countof(hide);
filter.DenyList.pIDList = hide;
d3dInfoQueue->AddStorageFilterEntries( &filter );
d3dInfoQueue->Release();
}
d3dDebug->Release();
}

For Windows Store and Windows phone 8 applications, this code looks like: 

 ...
#ifdef _DEBUG
deviceCreationFlags |= D3D11_CREATE_DEVICE_DEBUG;
#endif
...
...deviceCreationFlags is passed to D3D11CreateDevice as 'Flags' which is the fourth parameter
...

ComPtr<ID3D11Debug> d3dDebug;
if ( SUCCEEDED( d3dDevice.As(&d3dDebug) ) )
{
ComPtr<ID3D11InfoQueue> d3dInfoQueue;
if ( SUCCEEDED( d3dDebug.As(&d3dInfoQueue) ) )
{
#ifdef _DEBUG
d3dInfoQueue->SetBreakOnSeverity( D3D11_MESSAGE_SEVERITY_CORRUPTION, true );
d3dInfoQueue->SetBreakOnSeverity( D3D11_MESSAGE_SEVERITY_ERROR, true );
#endif
D3D11_MESSAGE_ID hide[] =
{
D3D11_MESSAGE_ID_SETPRIVATEDATA_CHANGINGPARAMS,
// Add more message IDs here as needed
};
D3D11_INFO_QUEUE_FILTER filter;
memset( &filter, 0, sizeof(filter) );
filter.DenyList.NumIDs = _countof(hide);
filter.DenyList.pIDList = hide;
d3dInfoQueue->AddStorageFilterEntries( &filter );
}
}

In these cases I throw away the reference to the debug objects ID3D11Debug and ID3D11InfoQueue, but there are some nifty features you might consider using so it can be useful to hold on them instead. For example, calling this just after releasing all your Direct3D objects just before releasing the ID3D11Device should report that all objects reference counts are 0--although the 'internal' reference counts might still be > 0 since a few objects are alive as long as the device is alive for internal defaults. It can also help to call ClearState and then Flush on the immediate context just before doing the report to ensure nothing is being kept alive by being bound to the render pipeline or because of lazy destruction. This information is output to the Debug Window in VS (or something like DebugView)

d3dDebug->ReportLiveDeviceObjects( D3D11_RLDO_SUMMARY | D3D11_RLDO_DETAIL );

DirectX 11.1: DirectX 11.1 adds a DXGI debug interface as well.

Windows phone: You cannot enable Direct3D debugging with hybrid Silverlight / Direct3D apps.

Update: This of course assumes you want to turn off these particular messages 'globally' for your application. You can also suppress them around only a specific part of your code via PushStorageFilter / PopStorageFilter

Developer Runtime: For details on obtaining the proper "Developer Runtime" for your OS, see DirectX 11.1 and Windows 7, Visual Studio 2012 and Windows 8.0 SDK, Visual Studio 2013 and Windows 8.1 SDK, Where is the DirectX SDK?, and Where is the DirectX SDK (2013 Edition)?. Remember that this includes installing the "reference" device as well as Direct2D debugging facilities.

Operating SystemDeveloper Runtime
Windows Vista
Windows 7 RTM

VS 2012 Remote Debugging Tools
legacy DirectX SDK for Direct3D

Direct2D debugging for these version of the OS can also be done with manual installation.

Windows 7 SP1
Windows 8

VS 2012
VS 2012 Remote Debugging Tools
Windows 8 SDK

Windows 7 SP1
Windows 8
Windows 8.1

VS 2013
VS 2013 Remote Debugging Tools
Windows 8.1 SDK

Windows 10

Enable the Windows optional feature "Graphics Tools". Read this post for details.

Windows RT: Windows RT Store app Debugging

Related: Anatomy of Direct3D 11 Create Device

Manifest Madness

$
0
0

This blog post discusses Application Manifest elements for use in Win32 desktop applications. This is not about the App package manifest (aka AppX) used for Windows Store apps for Windows 8.x.

User Account Control

Back when Windows Vista launched and the User Account Control feature was first introduced, there was one key recommendation for game developer writing PC games: your game should not require administrator rights to run, and you should add the proper embedded manifest to the game EXE so Windows Vista could tell the game was updated for the new OS. With Visual Studio 2005, this was done by turning on some settings for the Linker (Generate Manifest File: Yes) and Manifest Tool (Embed Manifest: Yes) and then setting the “Additional Manifest Files” field to point to a text file that contained:

<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<ms_asmv2:trustInfo xmlns:ms_asmv2="urn:schemas-microsoft-com:asm.v2">
<ms_asmv2:security>
<ms_asmv2:requestedPrivileges>
<ms_asmv2:requestedExecutionLevel level="asInvoker" uiAccess="false" />
</ms_asmv2:requestedPrivileges>
</ms_asmv2:security>
</ms_asmv2:trustInfo>
</assembly>

With Visual Studio 2008 and later, the project settings dialog offered direct support for this under Linker \ Manifest File – “Enable User Account Control (UAC)” and “UAC Execution Level”. This guidance still fully applies to Windows 7, Windows 8 and Windows 8.1. See User Account Control for Game Developers for more details on UAC and related implications. 

High-DPI

Windows Vista also introduced another feature, “High-DPI” which scaled the UI by a factor of 125% or 150% but was off by default. With Windows 7 this was enabled by default depending on the EDID native DPI information so the recommendation is for all Direct3D full-screen applications to declare themselves “High-DPI Aware”. Again, this is done via another manifest element. With Visual Studio 2005 and VS 2008, you add an “Additional Manifest Files” file reference to a text file containing:

<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3" >
<asmv3:application>
<asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
<dpiAware>true</dpiAware>
</asmv3:windowsSettings>
</asmv3:application>
</assembly>

With Visual Studio 2010 and 2012, the project settings dialog offers the choice of “Enable DPI Awareness” set to “No” or “Yes”. See Writing High-DPI Win32 applications for more information.

Note the value in the <dpiAware> element is not case-sensitive, so you'll see it as both “true” and “True” in articles and samples.

Program Compatibility Assistant (PCA)

With Windows Vista, just having the UAC elements was enough to know that the application had been updated for Windows Vista. If no UAC manifest element was found, Windows Vista enabled the Program Compatibility Assistant (PCA) which could check for common failures and resolve them.

Windows 7 needed a new way to detect if the EXE really understood Windows 7 to avoid any use of the PCA, and UAC manifest elements alone wasn't sufficient. The solution was... (drum roll, please): more manifest elements! You again add an “Additional Manifest Files” file reference to a text file containing:

<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
<application>
<!-- Windows Vista -->
<supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/>
<!-- Windows 7 -->
<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
</application>
</compatibility>
</assembly>

Windows 8 also used the same mechanism with a new GUID to indicate Windows 8 support.

<!-- Windows 8 -->
<supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>

For most programs, the PCA behavior impact wasn't really noticeable, so the <compatibility> section was mostly ignored by developers. This, by the way, is what determines the column “Operating System Context” in the Windows 7 or Windows 8 Resource Monitor (resmon) which defaults to “Windows Vista” if there's no <compatibility> manifest elements. On Windows 8.x, you can also see “Operating System Context” as a column in the Task Manager (taskmgr).

Ideally every Windows application would declare a <compatibility> section in their manifest to make it easier for future appcompat solutions to kick in automatically. This is a lot more robust than case-by-case debugging or having to manually apply shims.

Windows 8.1

Windows 8.1 has two important changes to this guidance. First, without the Windows 8.1 GUID in the <compatibility> section, GetVersion(Ex) APIs will always return “6.2” and not “6.3”. The default behavior improves appcompat for the vast majority of applications, but it could cause problems for custom OS-version telemetry, support tools, and potentially 3rd party DRM solutions. Adding the latest GUID to the manifest causes the process to get “6.3” when running on Windows 8.1:

<!-- Windows 8.1 -->
<supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>

See Windows 8.1 Preview and Windows Server 2012 R2 Preview AppCompat Cookbook for more details, as well as Certification requirements for Windows desktop apps. As I've recommended in the past, you really shouldn't be using GetVersion(Ex) APIs at all except perhaps in very specialized cases, and there are better ways to handle 'minimum supported OS' checks (See What's in a version number?)--the Windows 8.1 SDK also offers a set of helpers in VersionHelpers.h that are useful for such checks.

Windows 8.1 also includes enhancements to High-DPI support including per-monitor scaling, 200% scaling, and improved UI behavior. This has necessitated two additional settings for the <dpiaware> manifest value: “Per Monitor” means the application is Per-Monitor DPI-Aware on Windows 8.1. There is also a “True/PM” setting which is both “Per Monitor DPI-Aware” on Windows 8.1, and “System DPI-Aware” on Windows Vista / Windows 7 / Windows 8-- Per Monitor” by itself is interpreted the same as setting “false” down-level. The recommended High-DPI manifest elements for Direct3D full-screen applications is now:

<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3" >
<asmv3:application>
<asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
<dpiAware>True/PM</dpiAware>
</asmv3:windowsSettings>
</asmv3:application>
</assembly>

Visual Studio 2010 and 2012 do not offer the new “Per Monitor” or “True/PM” settings, so you will need to go back to using “Additional Manifest Files” and set the “Enable DPI Awareness” project setting to “No”.

See Writing DPI-Aware Desktop Applications in Windows 8.1 Preview.

Some examples of what can go wrong for a game that fails to use the proper High-DPI manifest setting are covered by KB 2908279 and KB 2907016.

Windows 10

Note that the latest version of Windows includes the default version lie shim that was present in Windows 8.1. If you have the 8.1 GUID present in the <compatibility> section of the manifest, Windows 10 will report version 6.3 if your application uses the legacy GetVersion(Ex) APIs. Without it or with only older GUIDs, it will report 6.2. To get the version number reported as 10.0 (note this was 6.4 with the original Windows 10 Technical Preview build 9841), you must add another GUID to your manifest:

<!-- Windows 10 -->
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/>

Update: With Windows 10 VerifyVersionInfo is now subject to the same manifest-based behavior as GetVersion(Ex): by default IsWindows8OrGreater and earlier will return 'true' as expected on Windows 10, but both IsWindows8Point1OrGreater and IsWindows10OrGreater will return 'false' without the appropriate GUIDs present in the <compatibility> section.

Windows 10 & High DPI: The Windows 10 High DPI settings can be 100%, 125%, 150%, 175%, 200%, 225%, 250%, 300%, 350%, 400%, or 450%. See this post for details.

Related: Desktop Games on Windows 8.x

Certification requirements for Windows desktop apps: The WACK 3.0 test will generate warnings if your application is missing any of these manifest elements.

Manifest Tool Note: Older versions of MT.EXE (including the one that comes with VS 2010 and the Windows 7.0 SDK) will generate a harmless warning for the <compatibility> section. This can be resolved by updating to a newer version of the Manifest Tool by copying MT.EXE out of the Windows 7.1 SDK, Windows 8.0 SDK, or Windows 8.1 SDK into a directory on your project's $(ExecutablePath). This issue does not affect VS 2012 or VS 2013.

Dynamic Link Library (DLL): Embedded manifests can be applied to DLLs for specific elements, but none of the elements listed in this article apply. They only work if provided in the original launching EXE.

Visual Studio 2013 and Windows 8.1 SDK RTM are now available

$
0
0

Visual Studio 2013 RTM is now available. The VS 2013 RTM Redistribution packages are also available (x86, x64, ARM), as well as the Remote Debugging Tools (x86, x64, ARM). For more information, see the Visual C++ team blog, Somasegar’s blog, and the Visual Studio team blog.

VS 2013 RTM includes the Windows Software Development Kit (SDK) for Windows 8.1 (October 2013), which is also available standalone. This includes DirectXMath 3.06, Direct3D 11.2/DXGI 1.3/Direct2D 1.2/DirectWrite 1.2 headers for Windows 8.1, D3DCompiler #47, and the Direct3D Debug Runtime for Windows 8.1. This includes an update of GDFMaker with some minor bugs fixes, and a few more caps detection features in DxCapsViewer as well.

Today is also Windows 8.1 and Windows Server 2012 R2 GA (build 9600). Might be a good time to review and Manifest Madness, Desktop Games on Windows 8.x, and the latest AppCompat Cookbook.

Related:Where is the DirectX SDK (2013 Edition)?, Visual Studio 2013 RC, VS 2012 and Windows 8.0 SDK RTM

Windows XP developers: as with VS 2012, the "v120_xp" platform toolset in VS 2013 uses a version of the Windows 7.1 SDK, not Windows 8.x SDK. See Visual Studio 2012 Update 1.

Windows 7 users: VS 2013 originally required IE10 be installed which requires KB 2670838 (DirectX 11.1 and Windows 7 Update and DirectX 11.1 and Windows 7). The VS 2013 setup has been refreshed and no longer requires IE10 be installed. KB 2670838 and IE10 are still recommended as there are a number of known issues on Windows 7 if they are not present (see KB 2906882) some of which are addressed with VS 2013 Update 1.

Windows 8 users: If you upgrade to Windows 8.1, remember that all attempts to use D3Dxx_CREATE_DEVICE_DEBUG will fail until you upgrade the Developer Runtime. You can do this by installing VS 2013, the standalone Windows 8.1 SDK, or by installing the VS 2013 Remote Debugging Tools. If you are missing the updated SDK Debug Layers, you should see the following message in your debug output:

D3D11CreateDevice: Flags (0x2) were specified which require the D3D11 SDK Layers for Windows 8.1, but they are not present on the system.
These flags must be removed, or the Windows 8.1 SDK must be installed.

DirectX SDK users: Using the legacy DirectX SDK (June 2010) with VS 2013 is the same as it was using it with VS 2012. See MSDN.

Express users: VS 2013 Express for Windows edition include Graphics Diagnostics (aka VS PIX) and the Visual Studio content tools. These are not included with the VS 2013 Express for Windows Desktop edition.

VS 2010/2012 users: You can use the property sheet technique for the Windows 8.1 SDK that was described in this Visual C++ Team blog post originally for VS 2010+Windows 8.0 SDK. For VS 2010, just change the part of the paths with "8.0"/"win8" to "8.1"/"winv6.3" but otherwise use all those instructions. For VS 2012, you can simplify all the paths to just add the 8.1 paths before the existing value for each variable. The updated .props are attached to this blog post. This should only be used for Win32 desktop application development. Windows Store apps should use VS 2013 with the Windows 8.1 SDK. Note you cannot target Windows XP with the Windows 8.1 SDK.

The VS team's instructions omit including the "include\winrt" directory under the assumption that those are for Windows Store apps only, but that's not strictly true. At a minimum, having access to #include <wrl/client.h> provides you the extremely useful Microsoft::WRL::ComPtr smart-pointer that works perfectly fine in Win32 desktop apps and down-level systems.

Windows Store app developers: Remember if writing Windows Store apps for Windows 8.1, you must use the VS 2013 toolset, the Windows 8.1 SDK, and the Windows 8.1 OS. You can optionally install the VS 2012 toolset and Windows 8.0 SDK as part of your VS 2013 setup (called "Tools for Maintaining Store apps for Windows 8" in the optional features list) to maintain Windows Store apps for Windows 8.0. You cannot install VS 2013 on the Windows 8.0 OS to build Windows Store apps for Windows 8.1. None of these restrictions apply to Win32 desktop development.

Update: Refreshed the attached .props with some fixes on October 21, 2013. There are new releases of DirectXTex, DirectXTKEffects 11, and DXUT for Direct3D 11 with support for VS 2013 / Windows 8.1 SDK available as well.

Related:Visual Studio 2013 Update 1, VS 2013 Update 2, VS 2013 Update 3, VS 2013 Update 4, VS 2013 Update 5, Direct3D Game Visual Studio templates (Redux)


Windows 8.1 Update

$
0
0

Windows 8.1 Update is now available via Windows Update, although it may take a while before it rolls out to your systems. See what's new and this blog post with more information. There is also a nice best of BUILD post you may find useful as well.

See KB 2919355

Note that this update is mandatory. All future servicing for Windows 8.1, Windows RT 8.1, and Windows Server 2012 R2 will be based on having this update installed. Windows 8.1 Update includes a roll-up of servicing changes to date. Windows 8.0 users also need to upgrade to Windows 8.1 Update to continue getting support as of January 16, 2016.

MSDN/TechNet Subscribers: This is available as both a standalone update and as a full Windows 8.1 ISO with the update included.

IT Pros: Here are some deployment details on the update, as well as some information on the Windows Server 2012 R2 Update.

Windows XP: In other news, as of today Windows XP is now end-of-life. See this blog post for my homage to this venerable OS...

WSUS Users: There are some issues with the Windows 8.1 Update deployment via WSUS. See this blog post and KB 2959977.

Windows 8.1 SDK: The existing Windows 8.1 SDK was refreshed for this update (April 2014). This refresh is also included in VS 2013 Update 3 or later. See MSDN for notes on the API changes.

Update: This blog post has some tips & tricks as well.

Visual Studio 2013 Update 3

$
0
0

An update to Visual Studio 2013 is now available for download.

For more details see Visual Studio Team Blog, Brian Harry’s blog, and Somasegar’s blog.

Official KB article 2933779. There's also a list of bugs fixed for this release.

Compiler and CRT

VS 2013 Update 3 includes a new version of the C++ compiler (18.00.30723.0). There's no new C/C++ Runtime--it still uses CRT version 12.0.21005.1 from VS 2013 RTM), but there are updated remote debugging tools packages.

Windows SDK: VS 2013 Update 3 includes the April 2014 refresh of the Windows 8.1 SDK for the Windows 8.1 Update.

Windows phone: The Windows Phone 8.1 Update emulators are now also available for download.

VS Graphics Diagnostics: See this article for details. See also KB 2955817.

Improved optimized debugging: The /Zo switch is now officially supported. See Bruce Dawson's blog for the gory details.

Related:Visual Studio 2013 RTM, VS 2013 Update 1, VS 2013 Update 2, VS 2013 Update 4, VS 2013 Update 5

DXGI Debug Device

$
0
0

In my original post on using the debug layer, I mentioned several tricks for getting helpful behavior out of the Direct3D SDK debug layer for your applications. This best practice is demonstrated in my Visual C++ Game templates as follows:

 #ifndef NDEBUG
Microsoft::ComPtr<ID3D11Debug> d3dDebug;
hr = m_d3dDevice.As(&d3dDebug);
if (SUCCEEDED(hr))
{
       ComPtr<ID3D11InfoQueue> d3dInfoQueue;
       hr = d3dDebug.As(&d3dInfoQueue);
       if (SUCCEEDED(hr))
       {
#ifdef _DEBUG
              d3dInfoQueue->SetBreakOnSeverity(D3D11_MESSAGE_SEVERITY_CORRUPTION, true);
              d3dInfoQueue->SetBreakOnSeverity(D3D11_MESSAGE_SEVERITY_ERROR, true);
#endif
              D3D11_MESSAGE_ID hide [] =
              {
                     D3D11_MESSAGE_ID_SETPRIVATEDATA_CHANGINGPARAMS,
              // TODO: Add more message IDs here as needed
              };
              D3D11_INFO_QUEUE_FILTER filter;
              memset(&filter, 0, sizeof(filter));
              filter.DenyList.NumIDs = _countof(hide);
              filter.DenyList.pIDList = hide;
              d3dInfoQueue->AddStorageFilterEntries(&filter);
       }
}
#endif

This snippet ensures that a common but harmless warning message is suppressed in non-Production builds, and enables 'break on' functionality in Debug builds if there are any serious corruption or error messages.

With the Direct3D 11.1 Runtime or later, you can also use a DXGI debug interface to track down additional leaks that are not known to your Direct3D 11 device. How this new interface is exposed, however, is a bit confusing.

For traditional Windows desktop apps, you are expected to use explicit linking. Since the DXGI debug layer is not present on end-user machines, this pattern encourages being able to handle the case of it not being present on the system. The confusing part is that the function you need, DXGIGetDebugInterface is not defined in any header and is not present in any import library.

#include <dxgidebug.h>
#if defined(_DEBUG)
    Microsoft::WRL::ComPtr<IDXGIInfoQueue> dxgiInfoQueue;
 
    typedef HRESULT (WINAPI * LPDXGIGETDEBUGINTERFACE)(REFIID, void ** );
 
    HMODULE dxgidebug = LoadLibraryEx( L"dxgidebug.dll", nullptr, LOAD_LIBRARY_SEARCH_SYSTEM32 );
    if ( dxgidebug )
    {
        auto dxgiGetDebugInterface = reinterpret_cast<LPDXGIGETDEBUGINTERFACE>(
            reinterpret_cast<void*>( GetProcAddress( dxgidebug, "DXGIGetDebugInterface" ) ) );
 
        if ( SUCCEEDED( dxgiGetDebugInterface( IID_PPV_ARGS( dxgiInfoQueue.GetAddressOf() ) ) ) )
        {
            dxgiInfoQueue->SetBreakOnSeverity( DXGI_DEBUG_ALL, DXGI_INFO_QUEUE_MESSAGE_SEVERITY_ERROR, true );
            dxgiInfoQueue->SetBreakOnSeverity( DXGI_DEBUG_ALL, DXGI_INFO_QUEUE_MESSAGE_SEVERITY_CORRUPTION, true );
        }
    }
#endif
 

One issue with this pattern is that you can't use it for Windows Store or universal Windows apps since LoadPackagedLibrary cannot load a system DLL as a security measure. In the DirectX 11.2 Runtime (Windows 8.1 and Windows 10), there is now a DXGIGetDebugInterface1 defined in the dxgi1_3.h header and in the dxgi.lib import library. This implicit linking works fine for Windows Store apps and UWP, but for desktop apps you should stick with the explicit method particularly if you need Windows 7 support as this function is not present in the 11.1 or 11.0 runtime.

#if defined(_DEBUG)
Microsoft::WRL::ComPtr<IDXGIInfoQueue> dxgiInfoQueue;
if ( SUCCEEDED( DXGIGetDebugInterface1( 0, IID_PPV_ARGS( dxgiInfoQueue.GetAddressOf() ) ) ) )
{
       dxgiInfoQueue->SetBreakOnSeverity( DXGI_DEBUG_ALL, DXGI_INFO_QUEUE_MESSAGE_SEVERITY_ERROR, true );
       dxgiInfoQueue->SetBreakOnSeverity( DXGI_DEBUG_ALL, DXGI_INFO_QUEUE_MESSAGE_SEVERITY_CORRUPTION, true );
}
#endif

As with the Direct3D debug layer, there is a method for reporting live DXGI objects as well for tracking down resource leaks. You obtain a IDXGIDevice instance the same was as you do a IDXGIInfoQueue interface above, and then call ReportLiveObjects.

DXGUID: One other issue of note is that the various DXGI debug control GUIDs (i.e. DXGI_DEBUG_ALL) are missing from DXGUID.LIB. You have to define it yourself using INITGUID. This is fixed for the Windows 10 SDK.

Related: Direct3D SDK Debug Layer Tricks, DirectX 11.1 and Windows 7 Update

DirectX Tool Kit: Keyboard and Mouse support

$
0
0

The GamePad abstraction in DirectX Tool Kit was designed to simplify implementing game controller input across the spectrum of platforms supported by DirectX Tool Kit: Windows desktop, Xbox One, Windows 8 Store, and now universal Windows Apps for Windows 10. In a similar vein, the July 2015 release of DirectX Tool Kit includes two new classes for handling keyboard and mouse input across Windows desktop, Windows 8 Store, and universal Windows apps for Windows 10.

Keyboard

The Keyboard class is as usual based on the XNA Game Studio design, with the primary difference being that I needed to use a singleton rather than a static class. As with the XNA Game Studio class, this is intended for using the keyboard as a 'game controller' mapping keys to game input events. To support full text input for chat or text editing, you should make use of the underlying platform's keyboard support to fully handle international input. Integration of the Keyboard class is slightly more complicated than GamePad in that after creating the class instance, you need to make the appropriate calls from either your Win32 message pump for keyboard messages in Windows desktop apps, or you need to provide your application's CoreWindow so that Keyboard can register for the needed callbacks.

For Windows desktop applications, Keyboard takes input from WM_KEYUP, WM_KEYDOWN, WM_SYSKEYUP, and WM_SYSKEYDOWN Win32 messages. For Windows 8 Store and universal Windows apps, it makes use of CoreDispatcher::AcceleratorKeyActivated. As with XNA Game Studio, the Keyboard::State object encodes the virtual keys (rather than scan codes). This works well for most key combinations, but this is a bit quirky when handling Left vs. Right Shift keys (details in the class documentation).

The abstraction makes writing keyboard-based controls quite simple and portable across the supported platforms:

void Game::Update(DX::StepTimer const& timer)
{

auto kb = m_keyboard->GetState();

if (kb.Up || kb.W)
move.y += 1.f;

if (kb.Down || kb.S)
move.y -= 1.f;

if (kb.Left || kb.A)
move.x += 1.f;

if (kb.Right || kb.D)
move.x -= 1.f;
}

See the documentation wiki page on the new class for details, and the related tutorial.

Mouse

The basics of the Mouse class are borrowed from XNA Game Studio, but is also singleton rather than a static class as well as having explicit support for a 'relative' or 'mouse-look' input mode. Integration of the Mouse class is slightly more complicated than GamePad in that you need to make the appropriate calls from either your Win32 message pump for mouse messages in Windows desktop apps, or you need to provide your application's CoreWindow so that Mouse can register for the needed callbacks.

For Windows desktop applications, Mouse uses WM_MOUSEMOVE, WM_LBUTTONDOWN, WM_MOUSEWHEEL, etc. events for handling the default 'absolute' mouse position mode. When in the 'relative' mode, it uses WM_INPUT per the Taking Advantage of High-Definition Mouse Movement article.

For Windows 8 Store and universal Windows apps, Mouse makes use of the standard CoreWindow::PointerMoved, CoreWindow::PointerPressed, etc. events for handling the default 'absolutely' mouse position mode per Responding to touch input (DirectX and C++). For these platforms, the Mouse class also handles the conversion of DIPs to pixels, so be sure to call SetDPI appropriately. When in 'relative' mode, it uses CoreWindow::MouseMoved per Developing mouse controls (DirectX and C++).

The abstraction makes implementing mouse controls simple and reasonably portable between the supported platforms:

void Game::Update(DX::StepTimer const& timer)
{
auto state = g_mouse->GetState();
if (state.positionMode == Mouse::MODE_RELATIVE)
{
// state.x and state.y are relative values; system cursor is not visible
}
else
{
// state.x and state.y are absolute pixel values; system cursor is visible
}

tracker.Update(state);

if (tracker.leftButton == Mouse::ButtonStateTracker::ButtonState::PRESSED)
{
mouse->SetMode(Mouse::MODE_RELATIVE);
}
else if (tracker.leftButton == Mouse::ButtonStateTracker::ButtonState::RELEASED)
{
mouse->SetMode(Mouse::MODE_ABSOLUTE);
}

}

See the documentation wiki page on the new class for details, and the related tutorial.

DirectInput: Developers are strongly discouraged from using legacy DirectInput for handling keyboard and mouse processing as far back as Windows XP. DirectInput should really only be used for supporting legacy HID game controllers and joysticks.

Visual Studio 2015 RTM

$
0
0

Visual Studio 2015 RTM is now available for download, including the updated Community edition. The VS 2015 RTM Redistribution packages are also available (x86, x64), as well as the Remote Debugging Tools (x86, x64, ARM). For more information, see the Visual C++ Team blogBrian Harry’s blog, Somasegar’s blog, and the Visual Studio Team blog.

The C++11 language and standard library tables in the Dual-use Coding Techniques for Games article has been updated for VS 2015 RTM, and you can find much more information about these changes for VS 2015 on the Visual C++ Team blog. Be sure to read the MSDN page Breaking Changes in Visual C++ as well. There are also a number of new warnings in place including format specifier checking that previously required the use of /analyze.

REDIST: VS 2015 can target Windows 10, Windows 8.1, Windows 8.0, Windows 7 Service Pack 1, Windows Vista Service Pack 2, and optionally Windows XP Service Pack 3. Note that the Visual C++ 2015 REDIST does not support Windows 7 RTM, Windows Vista RTM, Windows Vista Service Pack 1, Windows XP RTM, Windows XP Service Pack 1, or Windows XP Service Pack 2 as these platforms are all outside their support lifecycle. See KB2661358.

Visual C++: Note that with VS 2015 RTM, the C++ toolset is not included in the Typical installation. You must select it through the Custom selection. See the Visual C++ Team blog.

Windows 10 DirectX Development: Be sure to read this post on how to enable the DirectX debug device for Windows 10. Installing VS 2015 RTM (or VS 2013 Update 5) on Windows 10 will automatically enable the Graphics Tools Windows optional feature.

Windows XP: When building using the “v140_xp” Platform Toolset for Windows XP Service Pack 3 target support, remember this uses the Windows 7.1A SDK. The older SDK will generate some warnings in system headers with the new toolset that have to be externally suppressed. See VS 2012 Update 1 for some additional implications for DirectX development.

DirectX SDK: If you need to continue to make use of legacy DirectX SDK components such as D3DX9, D3DX10, D3DX11, or XAudio 2.7 with Visual Studio 2015, see MSDN for details on mixing the paths correctly. See also DirectX SDKs of a certain age, The Zombie DirectX SDK, Living without D3DX, DirectX SDK Tools Catalog, and DirectX SDK Samples Catalog

Windows 8.1 SDK: VS 2015 RTM includes the Windows 8.1 SDK Spring Update 2015 with DirectXMath 3.07. You can also download the standalone Windows 8.1 SDK Spring 2015 update.

Windows 10 SDK: Universal Windows apps (UWA) developers should stick with using VS 2015 RC until the final Visual Studio Tools and Windows 10 SDK packages are released next week. See this blog post about adding the Windows 10 SDK 10240 tools to VS 2015 RTM.

VS Content Pipeline: The built-in mesh content exporter in VS 2015 makes use of Autodesk FBX 2015.1–VS 2012 and 2013 used 2013.1.

Related: VS 2015 Update 1

Viewing all 60 articles
Browse latest View live


<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>