Orientation and rotation on Windows Phone

Orientation and rotation on Windows Phone

  • Comments 7

The Windows Phone version of the XNA Framework includes an automatic rotation feature. This allows XNA games to choose whether they want to run in landscape or portrait mode, without having to roll their own rotation solution like we used to on Zune.

Note: rotation was not implemented in the CTP release of the Windows Phone Emulator, but is fully supported in our recent beta version.

 

Things you should know about rotation

  • Rotation is implemented by special driver magic, so costs literally nothing
  • In contrast, rolling your own rotation via a rendertarget costs lots of GPU time and battery
  • So use the built in rotation, don't roll your own!
  • Touch input is automatically rotated to match your chosen orientation
  • If you use other sensor inputs such as accelerometer, you must rotate them yourself

 

Landscape games

Making a landscape game is easy: just don't do anything at all. The Game class defaults to 800x480 landscape resolution.

If you turn the phone the other way up, landscape XNA games automatically flip between LandscapeLeft and LandscapeRight orientation. You don't need to do anything special to enable this. Graphics rendering and touch input are automatically rotated so everything 'just works' ™.

 

Portrait games

To make a portrait game, add this to your Game constructor:

    graphics.PreferredBackBufferWidth = 480;
    graphics.PreferredBackBufferHeight = 800;

Now you have a portrait mode game, which will not rotate as you turn the phone.

Thanks to the scaler feature, the width and height do not have to be exactly 800x480 or 480x800. If width is greater than height, XNA will choose landscape orientation, otherwise it will choose portrait.

 

Custom rotations

If you want to lock your game to just one landscape orientation, so it will not automatically flip between LandscapeLeft and LandscapeRight, add this to your Game constructor:

    graphics.SupportedOrientations = DisplayOrientation.LandscapeLeft;

If you want to change orientation sometime after the game has been initialized:

    graphics.SupportedOrientations = DisplayOrientation.LandscapeRight;
    graphics.ApplyChanges();

If you want to automatically switch between both landscape and portrait orientations as the phone is rotated:

    graphics.SupportedOrientations = DisplayOrientation.Portrait | 
                                     DisplayOrientation.LandscapeLeft | 
                                     DisplayOrientation.LandscapeRight;

Switching between LandscapeLeft and LandscapeRight can be handled automatically with no special help from the game, and is therefore enabled by default. But switching between landscape and portrait alters the backbuffer dimensions (short-and-wide vs. tall-and-thin), which will most likely require you to adjust your screen layout. Not all games will be able to handle this (and some designs only make sense one way up), so dynamic switching between landscape and portrait is only enabled for games that explicitly opt-in by setting SupportedOrientations.

 

Rotation events

When you turn the phone from one orientation to another, two things happen:

  • The GameWindow.OrientationChanged event is raised
  • If the new orientation is included in your SupportedOrientations settings, the graphics device is reset accordingly, which raises the various device reset events

To check the current orientation:

  • GameWindow.CurrentOrientation tells you which way up the phone is currently being held
  • GraphicsDevice.PresentationParameters.DisplayOrientation tells you which way up your game is currently displayed

If the current phone orientation is not one of your SupportedOrientations, these two values may not be the same.

Similarly, if your game is using the scaler, the current backbuffer resolution (which is scaled, and can be queried using GraphicsDevice.PresentationParameters.BackBufferWidth and BackBufferHeight) will not be the same as the screen resolution (which is not scaled, and can be queried using DisplayMode or GameWindow.ClientBounds).

  • Shawn,

    If I understand this correctly, physically rotating the phone will automatically cause the orientation to change, which can be handled using some build-in event.

    If I later want to allow the user to "lock" the orientation, I can change the "SupportedOrientations" and apply my changes? I wish I had a test device...

    Your blog has been epically informative!

  • > If I understand this correctly, physically rotating the phone will automatically cause the orientation to change

    Exactly, but only from within the options that you specify as SupportedOrientations. If you do not set SupportedOrientations, this defaults to either left+right (for landscape games) or just portrait (for portrait games) but will not automatically switch between landscape and portrait.

    > If I later want to allow the user to "lock" the orientation, I can change the "SupportedOrientations" and apply my changes?

    Correct.

    > Your blog has been epically informative!

    Why thank you sir! That's good to hear.

  • Shawn,

    You were the first one who pointed out that rotating of the device from one landscape-mode to the other happens automatically and nothing has to be done manually.

    As for me I have no test-device, it took me very long to find this information.

    Thanks for this post!

  • > As for me I have no test-device, it took me very long to find this information.

    You can also experiment with rotation in the emulator (it has buttons to change which way up you are "holding" it) - no need for an actual hardware device to try this!

  • Shawn,

    My previous comment was eaten! Long story short:

    If I specify the SupportedOrientations, the TouchPanel.DisplayOrientation property will always initially return "Portrait", regardless of the actual orientation of the emulator. Once the emulator is rotated, that property will return the correct value until my game is closed. I am setting the SupportedOrientations in the Game class's constructor with the following line:

    _graphics.SupportedOrientations = (DisplayOrientation.LandscapeLeft | DisplayOrientation.LandscapeRight | DisplayOrientation.Portrait);

    Commenting-out this line resolves the issue (i.e. TouchPanel.DisplayOrientation will return the correct value from the beginning). Is this an issue with the emulator, or (more likely) is there something obvious I'm missing?

  • Is there a way to tell if it's in portrait but upside down?  It's a feature I need for a game I'm working on.

  • Windows Phone does not support upside down portrait mode.

Page 1 of 1 (7 items)
Leave a Comment
  • Please add 6 and 8 and type the answer here:
  • Post