Marble Maze sample fundamentals
This document describes the fundamental characteristics of the Marble Maze project, for example, how it uses Visual C++ in the Windows Runtime environment, how it is created and structured, and how it is built. The document also describes several of the conventions that are used in the code.
Note The sample code that corresponds to this document is found in the DirectX Marble Maze game sample.
Here are some of the key points that this document discusses for when you plan and develop your Windows Store game.
- Use the Direct3D Application template in a C++ application to create your DirectX Windows Store game. Use Visual Studio to build a Windows Store app project as you would build a standard project.
- The Windows Runtime provides classes and interfaces so that you can develop Windows Store apps in a more modern, object-oriented manner.
- Use object references with the hat (^) symbol to manage the lifetime of Windows Runtime variables, Microsoft::WRL::ComPtr to manage the lifetime of COM objects, and std::shared_ptr or std::unique_ptr to manage the lifetime of all other heap-allocated C++ objects.
- In most cases, use exception handling, instead of result codes, to deal with unexpected errors.
- Use SAL annotations together with code analysis tools to help discover errors in your app.
If you've downloaded and extracted the sample, you can open the MarbleMaze.sln solution file in Visual Studio, and you'll have the code in front of you. You can also view the source on the DirectX Marble Maze game sample MSDN Samples Gallery page by selecting the Browse Code tab.
When we created the Visual Studio project for Marble Maze, we started with an existing project. However, if you do not already have an existing project that provides the basic functionality that your DirectX Windows Store game requires, we recommend that you create a project based on the Visual Studio Direct3D Application template because it provides a basic working 3-D application.
One important project setting in the Direct3D Application template is the /ZW option, which enables the program to use the Windows Runtime language extensions. This option is enabled by default when you use the Visual Studio template.
Caution The /ZW option is not compatible with options such as /clr. In the case of /clr, this means that you cannot target both the .NET Framework and the Windows Runtime from the same Visual C++ project.
Every Windows Store app that you acquire from the Windows Store comes in the form of an app package. An app package contains a package manifest, which contains information about your app. For example, you can specify the capabilities (that is, the required access to protected system resources or user data) of your app. If you determine that your app requires certain capabilities, use the package manifest to declare the required capabilities. The manifest also lets you specify project properties such as supported device rotations, tile images, and the splash screen. For more info about app packages, see App packages and deployment.
Build a Windows Store app project as you would build a standard project. (On the menu bar, choose Build, Build Solution.) The build step compiles the code and also packages it for use as a Windows Store app.
After you build the project, you must deploy it. (On the menu bar, choose Build, Deploy Solution.) Visual Studio also deploys the project when you run the game from the debugger.
After you deploy the project, pick the Marble Maze tile to run the game. Alternatively, from Visual Studio, on the menu bar, choose Debug, Start Debugging.
You can use touch, the accelerometer, the Xbox 360 controller, or the mouse to control Marble Maze.
- Use the directional pad on the controller to change the active menu item.
- Use touch, the A button, the Start button, or the mouse to pick a menu item.
- Use touch, the accelerometer, the left thumbstick, or the mouse to tilt the maze.
- Use touch, the A button, the Start button, or the mouse to close menus such as the high score table.
- Use the Start button or the P key to pause or resume the game.
- Use the Back button on the controller or the Home key on the keyboard to restart the game.
- When the high-score table is visible, use the Back button or Home key to clear all scores.
You only have to use ^ and ref new when you create Windows Runtime objects or create Windows Runtime components. You can use the standard C++ syntax when you write core application code that does not use the Windows Runtime.
Marble Maze uses ^ together with Microsoft::WRL::ComPtr to manage heap-allocated objects and minimize memory leaks. We recommend that you use ^ to manage the lifetime of Windows Runtime variables, ComPtr to manage the lifetime of COM variables (such as when you use DirectX), and std::std::shared_ptr or std::unique_ptr to manage the lifetime of all other heap-allocated C++ objects.
For more info about the language extensions that are available to a C++ Windows Store app, see Visual C++ Language Reference (C++/CX). For more info about the Windows Runtime API, see Windows API reference for Windows Store apps.
Marble Maze uses exception handling as the primary way to deal with unexpected errors. Although game code traditionally uses logging or error codes, such as HRESULT values, to indicate errors, exception handling has two main advantages. First, it can make the code easier to read and maintain. From a code perspective, exception handling is a more efficient way to propagate an error to a routine that can handle that error. The use of error codes typically requires each function to explicitly propagate errors. A second advantage is that you can configure the Visual Studio debugger to break when an exception occurs so that you can stop immediately at the location and context of the error. The Windows Runtime also uses exception handling extensively. Therefore, by using exception handling in your code, you can combine all error handling into one model.
We recommend that you use the following conventions in your error handling model:
- Use exceptions to communicate unexpected errors.
- Do not use exceptions to control the flow of code.
- Catch only the exceptions that you can safely handle and recover from. Otherwise, do not catch the exception and allow the app to terminate.
When you call a DirectX routine that returns HRESULT, use the DX::ThrowIfFailed function. This function is defined in DirectXSample.h. ThrowIfFailed throws an exception if the provided HRESULT is an error code. For example, E_POINTER causes ThrowIfFailed to throw Platform::NullReferenceException.
When you use ThrowIfFailed, put the DirectX call on a separate line to help improve code readability, as shown in the following example.
- Although we recommend that you avoid the use of HRESULT for unexpected errors , it is more important to avoid the use of exception handling to control the flow of code. Therefore, it is preferred to use an HRESULT return value when necessary to control the flow of code.
Use SAL annotations together with code analysis tools to help discover errors in your app.
By using Microsoft source-code annotation language (SAL), you can annotate, or describe, how a function uses its parameters. SAL annotations also describe return values. SAL annotations work with the C/C++ Code Analysis tool to discover possible defects in C and C++ source code. Common coding errors reported by the tool include buffer overruns, uninitialized memory, null pointer dereferences, and memory and resource leaks.
Consider the BasicLoader::LoadMesh method, which is declared in BasicLoader.h. This method uses _In_ to specify that filename is an input parameter (and therefore will only be read from), _Out_ to specify that vertexBuffer and indexBuffer are output parameters (and therefore will only be written to), and _Out_opt_ to specify that vertexCount and indexCount are optional output parameters (and might be written to). Because vertexCount and indexCount are optional output parameters, they are allowed to be nullptr. The C/C++ Code Analysis tool examines calls to this method to ensure that the parameters it passes meet these criteria.
void LoadMesh( _In_ Platform::String^ filename, _Out_ ID3D11Buffer** vertexBuffer, _Out_ ID3D11Buffer** indexBuffer, _Out_opt_ uint32* vertexCount, _Out_opt_ uint32* indexCount );
To perform code analysis on your app, on the menu bar, choose Build, Run Code Analysis on Solution. For more info about code analysis, see Analyzing C/C++ Code Quality by Using Code Analysis.
The complete list of available annotations is defined in sal.h. For more info about SAL Annotations.
Read Marble Maze application structure for information about how the Marble Maze application code is structured and how the structure of a DirectX Windows Store app differs from that of a traditional desktop application.