Marble Mazes for the 8's
Today's going to be a Marble Maze Monday kind of day... How about one project, a Marble Maze game written with C++, XAML, DirectX written for Windows 8 MDL (Microsoft Design Language, aka a Windows 8 Store App, etc) that was then ported to run on Windows Phone 8? Where of course you get the source for both too!
This sample demonstrates how to build a basic 3D game using DirectX. This game is a simple labyrinth game where the player is challenged to roll a marble through a maze of pitfalls using tilt controls.
Areas covered include:
- Incorporating the Windows Runtime into your DirectX game for full Windows Developer Preview support
- Using DirectX to render 3D graphics for display in a game
- Implementing simple vertex and pixel shaders with HLSL
- Developing simple physics and collision behaviors in a DirectX game
- Handling input from accelerometer, touch, and mouse, and game controller with the Windows Runtime and XInput
- Playing and mixing sound effects and background music with XAudio2
This sample is written in C++ and requires some experience with graphics programming and DirectX. Complete content that examines this code can be found at Developing Marble Maze, a gama in C++ and DirectX.
For more info about the concepts and APIs demonstrated in this sample, see these topics:
- Create an app using DirectX
- Understanding DirectX game development
- Direct3D 11 graphics
- Direct2D graphics
- DirectX HLSL
- Developing games
This sample app is a port of the Marble Maze sample game targeted to Windows Phone 8. This is a fully featured game that demonstrates the use of Direct3D and Microsoft Media Foundation APIs.
This sample app is a port of the Marble Maze Windows Store app. Complete implementation details of the original Marble Maze game can be found in the topic Developing Marble Maze. Windows Phone 8 supports a subset of the features that are available for Windows Store apps. Because of this, several key changes were made to the app as it was ported. Details about these changes are provided later in this document. For more info about creating games for the phone, see Games for Windows Phone.
Build the sample
Start Visual Studio Express 2012 for Windows Phone and select File > Open > Project/Solution.
Go to the directory in which you unzipped the sample. Double-click the Visual Studio Express 2012 for Windows Phone solution (.sln) file.
Use Build > Rebuild Solution to build the sample.
Run the sample
To debug the app and then run it, press F5 or use Debug >Start Debugging. To run the app without debugging, press Ctrl+F5 or use Debug > Start Without Debugging.
When running the sample in the debugger, the first time you launch the sample a first-chance exception will be thrown. This is because of the way that Windows Phone Runtime APIs handle the fact that the save game file does not exist yet. It is possible to suppress this error, but that could potentially hide other exceptions that may be introduced as you modify the code, so the error is not suppressed in the sample. Click Continue in the error dialog to ignore the exception and allow the app to run normally.
Changes made to the Marble Maze sample to run on Windows Phone
The following list describes the changes that were made to the Marble Maze app when it was ported from a Windows Store app to Windows Phone. Where possible, the source files in the sample solution where the relevant changes were made are listed. For more info about what’s different when developing a game for the phone, see Differences in game development between the phone and the desktop.
Drawing 2D graphics - Direct2D is not available on Windows Phone. The Windows Store version of the game uses Direct2D to draw 2-D graphics such as GUI elements. The phone version uses helper classes provided by the DirectX Tool Kit (DirectXTK) to reimplement the game’s UI. Source files: UserInterface.cpp, LoadScreen.cpp
DirectXTK’s SpriteFont was used in place of Direct2D fonts. Bitmap fonts were precomputed ahead of time. Source files: MarbleMaze.cpp, UserInterface.cpp
Loading textures - The Windows Imaging Component (WIC) APIs are not available on Windows Phone. These APIs allow you to load textures in multiple file formats. The phone version of the game uses DDS textures for the load screen instead of PNG images. Source files: LoadScreen.cpp
Texture images were downscaled from the versions used on the desktop. This is not for performance reasons but instead to reduce the size of the app. The larger textures greatly increased the app size, but did not provide greater visual fidelity due to the phone’s smaller screen. Source files: bridge.dds, bridge_bump.dds, floor_section1.dds, floor_section2.dds, walllevel1.dds
Direct3D APIs - Of the Direct3D APIs that are supported on the phone, most function exactly like their desktop counterparts for the supported feature level (feature level 9_3). One of the exceptions is the creation of a swap chain. There are a few initialization parameters that have special requirements on the phone. These include:swapChainDesc.BufferCount = 1;swapChainDesc.Scaling = DXGI_SCALING_STRETCH;swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
This code can be found in DirectXBase.cpp at lines 152-154.
Other changes to Direct3D code include:
Removed IDXGISwapChain1::ResizeBuffers call (DirectXBase.cpp)
Using IDXGISwapChain1::Present1 instead of Present (DirectXBase.cpp)
Removed unnecessary window size and DPI change handling code. These events do not occur on the phone (DirectXBase.cpp, DirectXApp.cpp)
File I/O – On Windows Phone, the LocalSettings folder is not supported. The PersistentState class from the desktop version was reimplemented in a custom SaveState method. Source files: MarbleMaze.cpp
FileIO is not available on the phone. The implementation was changed slightly in BasicReaderWriter::ReadDataAsync and BasicReaderWriter::WriteDataAsync. Source files: BasicReaderWriter.cpp
Input - To support the phone’s back button, BackPressed key handling was added to the game and keyboard events were removed due to the phone’s lack of keyboard support. Source files: DirectXApp.cpp, MarbleMaze.cpp
Audio - Due to limited support for Microsoft Media Foundation APIs, a custom WAV loading implementation was created. Source files: MediaStreamer.cpp
Code for background music playback was modified to use IMFMediaEngine. Source files: Audio.cpp
Note: When playing with this app in the Windows Phone Emulator and using a mouse, switch the Orientation to Portrait Flat. This will make it work with the mouse as you would expect it too. (Since the game is meant to be used with the Phone flat and not standing...and all that)
Since I was able to make //build/ this year, I got a new Surface RT and Nokia Lumia 920. So the Greg Coding4Fun workshop now consists of a x86 notebook (my Alienware M11xr3, running Windows 8 x64) the Surface RT (ARM) and the a Windows Phone 8 (ARM again).
So do these two app's deploy onto those two devices? You bet!
Here's two snaps of the above app's deployed and running on the given devices.
Was it easy getting the app's deployed to the devices? Yes and mostly yes. And the mostly yes reflects one time pain. I won't go into depth on how to deploy and remote debug app's on the given devices, but will give you a high level glimpse.
While on the Surface in the Desktop IE, go to https://www.microsoft.com/visualstudio/eng/downloads scroll down to the "Additional software" section and in the "Remote Tools for Visual Studio 2012" panel download "Remote Tools for Visual Studio 2012 (ARM)"
Once downloaded, install it.
When done you'd have a new tile called "Remote Debugger".
Start that and an app will launch on the desktop.
Now back on the x86/x64 machine running VS2012, change the target to Remote Machine
Since this is a C++ project there's two more steps you have to do.
In the Project Properties set the Machine Name for your Surface RT device. This will NOT happen automagically when you press F5. The Remote Debugger Connections will NOT start when you hit F5 like it will with other project types. So you have to set the remote machine name here, this is where the Remote Debugger Connections comes into play.
If you don't set the Machine Name prior to hitting F5, you'll get an error like this,
1>------ Deploy started: Project: MarbleMaze, Configuration: Release ARM ------
1>Error: Microsoft Visual Studio Remote Debugging Monitor cannot start without a Machine Name. Open project properties and specify a Machine Name under 'Configuration Properties -> Debugging'.
So select Machine Name, edit and select your Surface RT device.
Finally, change the Platform from x86 to ARM
Hit F5, the app should promote you to recompile (that it's out of date), it will deploy and launch on the Surface device. You may also get a dialog on the Surface asking you to get a Developers License... Log in with your Microsoft account and you'll get your 3 month license. These are free...
This is your one time pain. The next time you do this, you won't have to install the Remote Debugger and you'll know about the Machine Name/Platform change and you'll already have the Dev license installed on the Surface.
Windows Phone 8
Windows Phone 8 deployment was much easier. Plug in the phone via USB, select "Device" as your target
Make sure the Phone is unlocked (as in the Lock Screen is not up) and hit F5.
If I remember correctly, I was also promoted for a Dev license during this process too, but this time, it was on my Notebook and not on the device.
Anyway, that's it. The Windows Phone SDK is smart enough to automagically switches the platform to ARM (which makes sense since every Windows Phone 8 Device is ARM whereas Surface's can be ARM or Intel).
Now you have these two projects, the source for them both, guidance on how the Windows 8 Store App was modified to work on Windows Phone 8 and finally how to get both app's onto their respective devices... That should be enough to keep you busy for the next couple days?