A helper class to show video "safe areas"


In this brave new world of XNA, we need to think about how our programs will look when displayed on televisions, as well as on computer monitors.  One new issue to be aware of is the concept of the safe area.  When your game runs on a console, the user’s television may not show every pixel you render to the viewport — some bits around the edges may get cropped.  The amount that will be visible will vary, based on the model of television.  Both standard-definition and high-definition TVs do this cropping, to about the same extent.  The consensus rule that broadcasters and console programmers tend to follow is:



  • Don’t show any essential “action” outside of the center 90% of the viewport (the “action safe area”)

  • Don’t show any symbolic information such as text outside of the center 80% of the viewport (the “title safe area”)

Note that you should still render your scene to the full viewport — you just need to be aware that some users won’t see those pixels near the edge, so don’t rely on everyone being able to see what’s out there.  As a game programmer, the main takeaway is that you should layout your UI elements to be within the title safe area.


Video editing tools generally have a way to visualize the safe areas.  I wrote up a quick helper class to do this in XNA.  Not rocket science, I know, but you can grab this code and use it to check your game before releasing it to the teeming masses.


Here’s the code:


/// <summary>
/// A helper class to indicate the “safe area” for rendering to a
/// television. The inner 90% of the viewport is the “action safe” area,
/// meaning all important “action” should be shown within this area. The
/// inner 80% of the viewport is the “title safe area”, meaning all text
/// and other key information should be shown within in this area. This
/// class shows the area that is not “title safe” in yellow, and the area
/// that is not “action safe” in red.
/// </summary>
public class SafeArea
{
    GraphicsDevice graphicsDevice;
    SpriteBatch spriteBatch;
    Texture2D tex; // Holds a 1×1 texture containing a single white texel
    int width; // Viewport width
    int height; // Viewport height
    int dx; // 5% of width
    int dy; // 5% of height
    Color notActionSafeColor = new Color(255, 0, 0, 127); // Red, 50% opacity
    Color notTitleSafeColor = new Color(255, 255, 0, 127); // Yellow, 50% opacity

    public void LoadGraphicsContent(GraphicsDevice graphicsDevice)
    {
        this.graphicsDevice = graphicsDevice;
        spriteBatch =
new SpriteBatch(graphicsDevice);
        tex =
new Texture2D(graphicsDevice, 1, 1, 1, ResourceUsage.None, SurfaceFormat.Color);
        Color[] texData = new Color[1];
        texData[0] =
Color.White;
        tex.SetData<
Color>(texData);
        width = graphicsDevice.Viewport.Width;
        height = graphicsDevice.Viewport.Height;
        dx = (
int)(width * 0.05);
        dy = (
int)(height * 0.05);
    }

    public void Draw()
    {
        spriteBatch.Begin(
SpriteBlendMode.AlphaBlend);

        // Tint the non-action-safe area red
        spriteBatch.Draw(tex, new Rectangle(0, 0, width, dy), notActionSafeColor);
        spriteBatch.Draw(tex,
new Rectangle(0, height – dy, width, dy), notActionSafeColor);
        spriteBatch.Draw(tex,
new Rectangle(0, dy, dx, height – 2 * dy), notActionSafeColor);
        spriteBatch.Draw(tex,
new Rectangle(width – dx, dy, dx, height – 2 * dy), notActionSafeColor);

        // Tint the non-title-safe area yellow
        spriteBatch.Draw(tex, new Rectangle(dx, dy, width – 2 * dx, dy), notTitleSafeColor);
        spriteBatch.Draw(tex,
new Rectangle(dx, height – 2 * dy, width – 2 * dx, dy), notTitleSafeColor);
        spriteBatch.Draw(tex,
new Rectangle(dx, 2 * dy, dx, height – 4 * dy), notTitleSafeColor);
        spriteBatch.Draw(tex,
new Rectangle(width – 2 * dx, 2 * dy, dx, height – 4 * dy), notTitleSafeColor);
        spriteBatch.End();
    }
}


Let’s see how it works on Wendybrot


Safe Area Example


Uh oh, call the TV police!  I’m definitely drawing some text and UI elements too close to the edge of the viewport.  If I were to ship this app as a real console title, I’d definitely want to move the text and the progress indicator wheel inward so they’re in neither the red nor yellow zones.


-Mike 


Comments (7)

  1. I&#39;m still enjoying my vacation in Texas. 80F weather the last several days, but dropping to low 40&#39;s

  2. I’m finally done writing an XNA game called "Microbe Patrol" based on the Microbes sample I wrote and

  3. Alex says:

    Hey everyone, I finally got around to uploading a version of WildBoarders that will compile and run on…

  4. I’ve updated my Microbe Patrol XNA project to build for both Windows and the Xbox 360. I didn’t make

  5. Mykres Space says:

    This Safe Area Component is based off a helper class that was written by Manders from &quot; Manders

  6. This Safe Area Component is based off a helper class that was written by Manders from &quot; Manders vs. Machine &quot; a long while back. This Component will draw a transparent set of rectangles on the Game Application to show the different Safe areas.