Monday, October 8, 2007

Forcing a window to maintain a particular aspect ratio

This is a piece of code I removed from my framework recently. I first wrote something like this many years ago, back when computer monitors were virtually all 4:3 aspect ratio.

Games typically run full-screen, but during development it's much more convenient to have them run in a window. For 3D games it's easy to resize the window. The problem is what to do when the window's client area doesn't match the aspect ratio of the full-screen monitor. You can letterbox the image, putting black borders on the sides, or you can crop, trimming part of the image off.

I opted to make the program restrict window resizing so that the window's aspect ratio would always match the target monitor's aspect ratio. This turns out not to be too hard to do in Windows.

First, you need to catch the WM_SIZING message in your message handler:

window_ratio_x and window_ratio_y are integer constants that define the desired aspect ratio.

We want to enforce a specific aspect ratio for the client area, but the resize code is dealing with the dimensions of the overall window. To handle this, at startup I use AdjustWindowRect to find out how much padding there is in each dimension, and store it off in g_window_adjust_x and g_window_adjust_y:

I ended up removing this code this week because monitors have gotten much less homogeneous in their aspect ratios. My notebook computer, for instance, is 1440 by 900, which is an 8:5 ratio. HDTV aspect ratios are 16:9. A 1280x1024 notebook (with square pixels) has a 5:4 aspect ratio. I decided that it was better to just have my games adapt their UI and viewport to whatever resolution they're given.