Forcing a resolution + center screen (EeePC)

Hi,

The EeePC 70X’s resolution is 800x480.

With SDL, when I select 640x480 fullscreen it “streches” the screen
and lose the aspect ratio. This is due to the graphic card video mode
that is stretched instead of centered.

So I’d rather have SDL select a physical 800x640 resolution, center
the screen in it, and return a 640x480 logical surface - which SDL
would do if the 640x480 stretched mode weren’t available.

For reference this can be done in the code, by forcing 800x640
manually and doing all blits on a secondary surface using the
subsurface technique - but this requires manually messing with each
SDL app code, plus special cares when setting screen palettes (needs
to be done on both the screen surface and the subsurface).

Is there a cleaner way to have an SDL app use a specific physical
resolution?–
Sylvain

Here’s an ugly, evil way of doing it…

screen = SDL_SetVideoMode(800, 480, 0, SDL_HWSURFACE);
screen->width = 640;
screen->pixels += (800-640)/2 * screen->format->BytesPerPixel;

Slightly more ugly and less evil:

#include
#include

SDL_Surface* _screen;
SDL_Surface* screen;

_screen = SDL_SetVideoMode(800, 480, 0, SDL_HWSURFACE);

screen = (SDL_Surface*) malloc(sizeof(SDL_Surface));
memcpy(screen, _screen, sizeof(SDL_Surface));

screen->width = 640;
screen->pixels += (800-640)/2 * screen->format->BytesPerPixel;

free(screen);

2009/6/20 Sylvain Beucler > Hi,

The EeePC 70X’s resolution is 800x480.

With SDL, when I select 640x480 fullscreen it “streches” the screen
and lose the aspect ratio. This is due to the graphic card video mode
that is stretched instead of centered.

So I’d rather have SDL select a physical 800x640 resolution, center
the screen in it, and return a 640x480 logical surface - which SDL
would do if the 640x480 stretched mode weren’t available.

For reference this can be done in the code, by forcing 800x640
manually and doing all blits on a secondary surface using the
subsurface technique - but this requires manually messing with each
SDL app code, plus special cares when setting screen palettes (needs
to be done on both the screen surface and the subsurface).

Is there a cleaner way to have an SDL app use a specific physical
resolution?


Sylvain


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

The first version might cause problems (for example) when freeing the
surface, so use the second one instead.

Of course, you could always make your own surface class to wrap SDL_Surface
and implement subsurfaces there instead, but I get the impression you’re
converting existing code to run on this device, not writing something new.
Otherwise you’d just use the native resolution.

Way back when, I suggested a similar solution to this problem:

http://article.gmane.org/gmane.comp.lib.sdl/41856

Thanks for reminding us about this issue.On Sat, Jun 20, 2009 at 5:36 PM, Sylvain Beucler wrote:

Hi,

The EeePC 70X’s resolution is 800x480.

With SDL, when I select 640x480 fullscreen it “streches” the screen
and lose the aspect ratio. This is due to the graphic card video mode
that is stretched instead of centered.

So I’d rather have SDL select a physical 800x640 resolution, center
the screen in it, and return a 640x480 logical surface - which SDL
would do if the 640x480 stretched mode weren’t available.

For reference this can be done in the code, by forcing 800x640
manually and doing all blits on a secondary surface using the
subsurface technique - but this requires manually messing with each
SDL app code, plus special cares when setting screen palettes (needs
to be done on both the screen surface and the subsurface).

Is there a cleaner way to have an SDL app use a specific physical
resolution?


http://codebad.com/

Thanks, but as I mentioned, I already have the ‘ugly way’ ready, and
I’m looking for a cleaner way, hopefully one that does not involve
messing with the code :)On Sun, Jun 21, 2009 at 06:02:59PM -0400, Kenneth Bull wrote:

The first version might cause problems (for example) when freeing the
surface, so use the second one instead.

Of course, you could always make your own surface class to wrap SDL_Surface
and implement subsurfaces there instead, but I get the impression you’re
converting existing code to run on this device, not writing something new.
Otherwise you’d just use the native resolution.

Yes, that’s the same issue.

I did try the “get your operating system to deny these video modes for
that display” but I personaly didn’t found out how, so I guess players
won’t either. Incidentally it’s more and more difficult to do this
kind of configuration under X11 with all the auto-detection stuff it
does nowadays. I’m not really interested in the scaling, just in
centering the logical screen.

It would be nice to get an environment variable, or an API, to force a
given hardware video mode.

Should we file a bug?On Sun, Jun 21, 2009 at 09:17:28PM -0400, Donny Viszneki wrote:

On Sat, Jun 20, 2009 at 5:36 PM, Sylvain Beucler<@Sylvain_Beucler> wrote:

Hi,

The EeePC 70X’s resolution is 800x480.

With SDL, when I select 640x480 fullscreen it “streches” the screen
and lose the aspect ratio. This is due to the graphic card video mode
that is stretched instead of centered.

So I’d rather have SDL select a physical 800x640 resolution, center
the screen in it, and return a 640x480 logical surface - which SDL
would do if the 640x480 stretched mode weren’t available.

For reference this can be done in the code, by forcing 800x640
manually and doing all blits on a secondary surface using the
subsurface technique - but this requires manually messing with each
SDL app code, plus special cares when setting screen palettes (needs
to be done on both the screen surface and the subsurface).

Is there a cleaner way to have an SDL app use a specific physical
resolution?

Way back when, I suggested a similar solution to this problem:

http://article.gmane.org/gmane.comp.lib.sdl/41856

Thanks for reminding us about this issue.


Sylvain

Den Mon, 22 Jun 2009 08:23:33 +0200
skrev Sylvain Beucler :

Should we file a bug?

The conclusion back then seemed to be “if you want it, write it
yourself.” Which I intend to do one of these days unless someone else
beats me to it… (Feel free, I’ve got some other things to do first.)

  • Gerry

“Write it yourself” as in:

  • “we’ll accept a patch in 1.2 and roll out a new release before 2010”
  • “we’ll accept a patch in 1.X and, well, release it someday”
  • “add a layer on top of SDL in all your apps”
    ? :)On Mon, Jun 22, 2009 at 02:20:46PM +0200, Gerry JJ wrote:

Den Mon, 22 Jun 2009 08:23:33 +0200
skrev Sylvain Beucler <@Sylvain_Beucler>:

Should we file a bug?

The conclusion back then seemed to be “if you want it, write it
yourself.” Which I intend to do one of these days unless someone else
beats me to it… (Feel free, I’ve got some other things to do first.)


Sylvain

Den Mon, 22 Jun 2009 15:23:45 +0200
skrev Sylvain Beucler :

“Write it yourself” as in:

  • “we’ll accept a patch in 1.2 and roll out a new release before 2010”

No. As I understand it, SDL 1.2 is complete, and no new API will be
added to it. (Maybe an environment variable hack could be added if
you’re lucky.)

  • “we’ll accept a patch in 1.X and, well, release it someday”

Hopefully this, for 1.3. To be honest, I don’t think anyone actually
said that the patch will be accepted if anyone actually makes it, but
it sure won’t if there’s no patch in the first place. If worse comes
to worst we’ll just have to fork SDL, I guess :wink: (nah, we can probably
work something out …)

  • “add a layer on top of SDL in all your apps”

If all else fails you could always do this, but you’d be restricted to
software rendering.

  • Gerry

I did try the “get your operating system to deny these video modes
for that display” but I personaly didn’t found out how

Hmm, actually there is a way to get the aspect ratio right without
modifying the code:

xrandr --output LVDS --set PANEL_FITTING full_aspect

Admittedly obscure, but there’s one. Maybe it requires a recent distro
though.

Which makes me think it may not be something to fix at the SDL level
eventually.

So I’d rather have SDL select a physical 800x640 resolution, center
the screen in it, and return a 640x480 logical surface - which SDL
would do if the 640x480 stretched mode weren’t available.

[…] but you’d be restricted to software rendering.

Are you sure? What prevents a hardware rendering from filling the
screen with black, and return a subsurface (same pitch, different
’->pixels’ origin) instead of the full surface?

As I understand it, SDL 1.2 is complete, and no new API will be
added to it.

I don’t think a piece of software can be complete. When SDL 1.2 was
first released, there was essentially no need to deal with 16:10
screens, while they are widespread nowadays. The world evolves,
software must adapt, nothing is static, everything is falling app…
well you got me :)–
Sylvain

Agreed!

-bill!On Mon, Jun 22, 2009 at 08:23:33AM +0200, Sylvain Beucler wrote:

It would be nice to get an environment variable, or an API, to force a
given hardware video mode.

Den Mon, 22 Jun 2009 18:41:25 +0200
skrev Sylvain Beucler :

I did try the “get your operating system to deny these video modes
for that display” but I personaly didn’t found out how

Hmm, actually there is a way to get the aspect ratio right without
modifying the code:

xrandr --output LVDS --set PANEL_FITTING full_aspect

Admittedly obscure, but there’s one. Maybe it requires a recent distro
though.

Which makes me think it may not be something to fix at the SDL level
eventually.

That’s nice, and I’m happy you solved the problem for yourself.
However, this is far from a universal solution. As I’ve explained
before (at length), there’s just so many monitors / graphics cards /
drivers with all kinds of problems that in the end you can’t be sure
that the display will be shown with the correct aspect ratio unless you
do it “manually” (ie by working with both a physical, a logical, and
optionally a scaled resolution.)

Also, fwiw, your xrandr magic doesn’t work here, and I do have a recent
Xorg server and gfx driver (nvidia). I can tell the driver to do
aspect-ratio scaling in the driver settings, but that still screws up
at some resolutions (eg 800x600 actually sets the videomode to around
700x525 and only shows the top left part of the screen for some reason,
with some flickering added at the bottom for good measure). This is
obviously not SDL’s fault, but again, the point is that there’s just so
much broken stuff out there that you can’t count on it working.

So I’d rather have SDL select a physical 800x640 resolution, center
the screen in it, and return a 640x480 logical surface - which SDL
would do if the 640x480 stretched mode weren’t available.

[…] but you’d be restricted to software rendering.

Are you sure? What prevents a hardware rendering from filling the
screen with black, and return a subsurface (same pitch, different
’->pixels’ origin) instead of the full surface?

SDL 1.3 uses textures for hardware rendering, and the screen is, well,
the screen. It’s not a texture or a surface. Textures can’t
(currently) be rendered to other textures. The surfaces that
you’re used to from 1.2 are always software surfaces.

Anyway, that reply was for the case in which SDL stays as it is, and
you implement the black bars in your own code or maybe an add-on
library. There are things you can do to keep hardware acceleration
even then – eg if SDL uses the opengl backend, you could easily use
glViewport to add black bars, but since SDL “owns” the screen it can
(at least in theory, haven’t actually checked this) set its own
viewport at any time, removing the bars again. There’s also all the
other backends to consider, if you want to support more than just
opengl – and if not, you might as well just use opengl directly for
less hassle and more features…

If SDL had render target support (another feature on my personal wish
list), you could render to a texture in stead, and then draw that to
the screen with all the borders and scaling you wanted (if any). But it
doesn’t, at least not yet.

Anyway, even if SDL does get render target support, black bars or even
screen scaling doesn’t necessarily need that. To use opengl as an
example again, rendering to a texture requires an extension, but adding
black borders can be done with a simple glViewport call, which has been
part of opengl since the beginning. Scaling of the screen can be also
be done practically for free simply by changing the values passed to
glOrtho when setting up the projection (though this only actually
scales coordinates, not pixels, but this should be good enough for
most purposes, specially since SDL manage the coordinates used … for
the cases where it’s not good enough, you’ll need render target
support anyway)

As I understand it, SDL 1.2 is complete, and no new API will be
added to it.

I don’t think a piece of software can be complete. When SDL 1.2 was
first released, there was essentially no need to deal with 16:10
screens, while they are widespread nowadays. The world evolves,
software must adapt, nothing is static, everything is falling app…
well you got me :slight_smile:

Yes, I think complete was the wrong word there. Frozen might be a
better one. As in, all new stuff go into 1.3.

  • Gerry