Welcome to MSDN Blogs Sign in | Join | Help

Zune landscape mode

My Zune Freecell game runs in 320x240 landscape mode, rather than the default 240x320 portrait orientation.

Unfortunately, the XNA Framework does nothing to help you render rotated scenes.

Fortunately, you can do this rather easily by drawing everything to a rendertarget, then rotating that as a postprocess.

But unfortunately, copying the entire scene via a rendertarget didn't meet my power efficiency goals.

The most efficient way to do any task is to find some way to avoid the need to do it at all. If I rotate my textures ahead of time during the Content Pipeline build process, my game code will not need to bother rotating them at runtime on the Zune. So I wrote this custom Content Processor:

    [ContentProcessor]
public class RotatedTextureProcessor : TextureProcessor
{
public override TextureContent Process(TextureContent input, ContentProcessorContext context)
{
if (context.TargetPlatform == TargetPlatform.Zune)
{
input.ConvertBitmapType(typeof(PixelBitmapContent<Color>));

for (int i = 0; i < input.Faces.Count; i++)
{
for (int j = 0; j < input.Faces[i].Count; j++)
{
PixelBitmapContent<Color> source = (PixelBitmapContent<Color>)input.Faces[i][j];
PixelBitmapContent<Color> dest = new PixelBitmapContent<Color>(source.Height, source.Width);

for (int x = 0; x < dest.Width; x++)
{
for (int y = 0; y < dest.Height; y++)
{
dest.SetPixel(x, y, source.GetPixel(y, source.Height - x - 1));
}
}

input.Faces[i][j] = dest;
}
}
}

return base.Process(input, context);
}
}

Of course it is not enough to just rotate the contents of each texture: I also need to change the coordinates where I draw them on the screen. I did this by tweaking my SpriteBatch class:

    class Renderer : SpriteBatch
{
new public void Draw(Texture2D texture, Vector2 position, Color color)
{
#if ZUNE
position = new Vector2(240 - texture.Width - position.Y, position.X);
#endif
base.Draw(texture, position, color);
}
}
Published Tuesday, December 02, 2008 5:28 PM by ShawnHargreaves

Comment Notification

If you would like to receive an email when updates are made to this post, please register here

Subscribe to this post's comments using RSS

Comments

Tuesday, December 02, 2008 9:34 PM by BillReiss

# re: Zune landscape mode

Hi Shawn, why not just do a Transform matrix on the SpriteBatch.Begin which does a rotate and a translate? I've done this before and it works pretty well. Is this technique better for performance reasons?

Thanks,

Bill Reiss

Wednesday, December 03, 2008 12:34 PM by ShawnHargreaves

# re: Zune landscape mode

Great point - I forgot all about the transform matrix approach!

That will be much more efficient than using a rendertarget (because it avoids having to copy the entire scene an extra time) but a little less efficient than precomputing the rotations (because it does still require the runtime drawing code to apply the rotation logic, and even though a 90 degree rotation is algorithmically trivial, this will be much less cache friendly as the source and destination are not layed out the same way in memory).

Wednesday, December 03, 2008 8:36 PM by kewlniss

# re: Zune landscape mode

Also I have seen it to actually stretch / skew the sprite font text when used.

I definitely like the content pipeline approach here.

Thanks Shawn!

Chad

Leave a Comment

(required) 
required 
(required) 

  
Enter Code Here: Required
 
Page view tracker