[pygame] Fixed aspect ratio scaling

2007-05-31 Thread John Eriksson
Hi,

Does anyone know about a good solution on the stretching problem when
running in fullscreen mode on a widescreen monitor?

For windows users having an nvidia driver it's possible to set Fixed
aspect ratio scaling as an option for the display causing the
widescreen to have black borders at the sides.

But are there any platform independent solutions to this?

I guess it might be possible to solve this using code, creating a
correct sized display and then blitt the game screen to it's centered.

But this (I guess) can cause some performance loss. And I don't know if
it's even possible to detect the best screen resolution to use.
As far as I know there are no way to determine the current screen
resolution (to calculate the monitors aspect ratio) of the system?

Any inputs?

Thanks
/John





Re: [pygame] Fixed aspect ratio scaling

2007-05-31 Thread Casey Duncan

On May 31, 2007, at 1:03 AM, John Eriksson wrote:


Hi,

Does anyone know about a good solution on the stretching problem when
running in fullscreen mode on a widescreen monitor?

For windows users having an nvidia driver it's possible to set Fixed
aspect ratio scaling as an option for the display causing the
widescreen to have black borders at the sides.

But are there any platform independent solutions to this?

I guess it might be possible to solve this using code, creating a
correct sized display and then blitt the game screen to it's centered.

But this (I guess) can cause some performance loss. And I don't  
know if

it's even possible to detect the best screen resolution to use.
As far as I know there are no way to determine the current screen
resolution (to calculate the monitors aspect ratio) of the system?


Is the problem that your game expects a fixed-resolution and  
therefore a fixed aspect ratio? Regardless if your game demands a  
fixed aspect ratio then on some monitors you must either letter-box  
the screen or stretch everything to fit. You seem to be hinting at  
doing the latter, but that causes undesireable distortion (i.e.,  
circles become ovals, etc).


Here is my suggested solution to this problem:

- Make your game resolution independent. That is, distances in the  
game are independent of pixel size.


- Make either the horizontal or vertical screen distance fixed,  
perhaps matching it to the ideal screen size (e.g., 1280 or 1600)


- At game startup let pygame pick the resolution by default or allow  
it to be overridden by user preference. Figure out the scale by  
dividing the fixed screen distance by the actual screen resolution.  
Then scale all of your graphics accordingly. If you are using sprite  
images, rotozoom works excellent (just zoom everything at load-time)  
and is very fast.


You get several benefits from this:

- You can pretty easily implement a zoom in/out feature by varying  
the fixed screen distance.


- Users can select lower resolutions to trade quality for performance  
or vice versa. Some resolutions may be letterboxed, but the user can  
decide if this is objectionable, many times it isn't.


To get at the screen resolution use the surface object returned from  
pygame.display.set_mode(), call get_rect() on it to figure out the  
screen res.


Here is some code I wrote to select the screen res from four user  
resolution settings: max, high, med and low. It is intended to pick  
sizes that fit the aspect ratio of the screen in fullscreen mode,  
where possible. It also favors portrait orientation (for those of us  
with pivoting monitors).


screen_sizes = {
'max': ((0, 10), (1280, 1024)),
'high': ((650, 800), (1024, 768)),
'med': ((500, 649), (800, 600)),
'low': ((400, 499), (640, 480))
}
(min_height, max_height), window_size = screen_sizes[resolution]
if fullscreen:
modes = pygame.display.list_modes()
# Choose the first mode with a height in the desired range
for mode in modes:
if min_height = mode[1] = max_height and mode[0]  mode[1]:
break
else:
mode = modes[0]
print Could not find ideal display mode, using, mode
screen = pygame.display.set_mode(mode, FULLSCREEN)
else:
screen = pygame.display.set_mode(window_size)
screen_rect = screen.get_rect()

hth,

-Casey




Re: [pygame] Fixed aspect ratio scaling

2007-05-31 Thread Dave LeCompte (really)
John Eriksson [EMAIL PROTECTED] asked:

 Does anyone know about a good solution on the stretching problem when
 running in fullscreen mode on a widescreen monitor?

One thing I would do would be to inspect the available resolutions. On my
widescreen laptop, I get the familiar 800x600 and friends (4:3 aspect
ratio), and some unfamiliar widescreen resolutions (16:9, I think). If all
the resolutions supported by the card are 4:3, you can bail out and stop
doing anything special.

If you have some 16:9 (or crazier) resolutions, I would filter out all the
4:3 options, assuming that they're undesirable relics.

 I guess it might be possible to solve this using code, creating a
 correct sized display and then blitt the game screen to it's centered.

By correct sized display, you mean having an off-screen buffer of a
fixed 4:3 resolution (e.g. 800x600), and then blit that? It could work,
assuming you're OK with the inverse letterbox black bars on the side,
and if you can guarantee that there's going to be a resolution of the
right height on the player's device (1067x600, in this case).

 But this (I guess) can cause some performance loss. And I don't know if
 it's even possible to detect the best screen resolution to use.

Yeah, that ought to be a decision by the player, rather than some guess by
code, I imagine.

One other thing to consider - what if the monitor is in portrait mode?
If you look through the available resolutions and see 3:4 or 9:16 aspect
ratios, it seems like a good solution is even more important - a little
stretching between 4:3 and 16:9 looks bad, but I imagine it'd look
terrible between 4:3 and 3:4.

-Dave LeCompte