Understanding Windows Phone Orientation in XNA

Panic Orientation

The many orientations of Panic.

Above you can see  my Windows Phone 7 Panic Button application. This gives you a panic button to press at any point in your panic inducing life. To make it work in any orientation I had to do a couple of things.

I had to tell the Windows Phone system the orientations my XNA game can support. I did this in the constructor for the game:

public PanicButtonGame()
    graphics = new GraphicsDeviceManager(this);
    Content.RootDirectory = "Content";

    graphics.SupportedOrientations =
        DisplayOrientation.Default |
        DisplayOrientation.LandscapeLeft |
        DisplayOrientation.LandscapeRight |
    // rest of constructor here

This effectively tells XNA that the graphics device for my game can support any way the player might want to hold the phone. The next thing I had to do was get an event fired when the orientation changed so that I could re-position that all important button:

public PanicButtonGame()
     // start of constructor here

    Window.OrientationChanged +=
          new EventHandler<EventArgs>

    // Frame rate is 30 fps by default for Windows Phone.
    TargetElapsedTime = TimeSpan.FromTicks(333333);

void Window_OrientationChanged(object sender, EventArgs e)
    // called when the orientation changes

When the game is running and the player changes the orientation of the phone my method bound to the Window_OrientationChanged event will fire and re-position the button on the screen.

If you game can only support particular orientations then just leave out the ones that you don’t want to make available. 

Things get interesting if you do something stupid with preferred resolutions and orientation:

graphics.SupportedOrientations = DisplayOrientation.Portrait;
graphics.PreferredBackBufferWidth = 400;
graphics.PreferredBackBufferHeight = 240;

I’ve asked to work in Portrait orientation. However, I’ve also asked for a screen which is 400 wide and 240 high (i.e. a landscape one) which is a bit daft. What happens here is that my program will think it has a “screen”  400 wide by 240 high, but this will then be scaled by the hardware to fit in a display working  in portrait mode, which means that I’ll get my screen scrunched into the middle of the screen, with black bands above and below:


I’ve added a blue background here so you can see what happens.

If you want to select particular screen orientations and also use the hardware scaler you have to make sure that your selections agree or this will happen to you.