PDA

View Full Version : The Querks of SDL_VideoModeOK()



WILL
22-05-2006, 08:57 PM
I'm having the hardest time trying to figure out the exact functionality of SDL_VideoModeOK().

Now this is a standard command in the sdl.dll(and libsdl.so) so I doubt that there is a bug.


{ Check to see if a particular video mode is supported.
It returns 0 if the requested mode is not supported under any bit depth,
or returns the bits-per-pixel of the closest available mode with the
given width and height. If this bits-per-pixel is different from the
one used when setting the video mode, SDL_SetVideoMode() will succeed,
but will emulate the requested bits-per-pixel with a shadow surface.

The arguments to SDL_VideoModeOK() are the same ones you would pass to
SDL_SetVideoMode() }

This is my own GraphicsUnit.pas function that I use to autodetect the lowest possible res for required width/height and set/return the video mode. If FullScreen is not set then it just creates a window at the exact size needed, no questions asked.

// Video Mode Initialiation
function SetGameVideoMode(MinWidth, MinHeight: Integer; FullScreen: Boolean): PSDL_Surface;
var
i: Integer;
ResWidth, ResHeight: Array[0 .. 13] of Cardinal;
flags: Cardinal;
HasMode: Boolean;
SetWidth, SetHeight: Cardinal;
begin
// Set Software Surface Flag
flags := SDL_SWSURFACE;

// Supported Game Resolutions
// 320x200 (PDA)
ResWidth[0] := 240;
ResHeight[0] := 320;
// 320x200 (Common)
ResWidth[1] := 320;
ResHeight[1] := 200;
// 320x240 (Common)
ResWidth[2] := 320;
ResHeight[2] := 240;
// 400x300 (Uncommon)
ResWidth[3] := 400;
ResHeight[3] := 300;
// 512x384 (Uncommon)
ResWidth[4] := 512;
ResHeight[4] := 384;
// 640x400 (Uncommon)
ResWidth[5] := 640;
ResHeight[5] := 400;
// 640x480 (Common)
ResWidth[6] := 640;
ResHeight[6] := 480;
// 800x600 (Common)
ResWidth[7] := 800;
ResHeight[7] := 600;
// 1024x768 (Common)
ResWidth[8] := 1024;
ResHeight[8] := 768;
// 1280x800 (Widescreen)
ResWidth[9] := 1280;
ResHeight[9] := 800;
// 1280x1024 (Common)
ResWidth[10] := 1280;
ResHeight[10] := 1024;
// 1600x1200 (???)
ResWidth[11] := 1600;
ResHeight[11] := 1200;
// 1920x1440 (???)
ResWidth[12] := 1920;
ResHeight[12] := 1440;
// 2048x1536 (???)
ResWidth[13] := 2048;
ResHeight[13] := 1536;

// Detect Lowest possible suppoerted resolution
HasMode := False;
if (not FullScreen) then
begin
HasMode := True;
SetWidth := MinWidth;
SetHeight := MinHeight;
end
else
begin
for i := 0 to 13 do
if (MinWidth <= ResWidth[i]) and (MinHeight <= ResHeight[i]) then
if (SDL_VideoModeOK(ResWidth[i], ResHeight[i], 32, SDL_SWSURFACE) > 0) then
begin
HasMode := True;
SetWidth := ResWidth[i];
SetHeight := ResHeight[i];
Break;
end;
end;

// Set Fullscreen Flag
if (FullScreen) then
flags := flags + SDL_FULLSCREEN;

if (HasMode) then
Result := SDL_SetVideoMode(SetWidth, SetHeight, 32, flags)
else
Result := nil;
end;

Now here is the 'hick-up'! Once SDL_VideoModeOK() finds the resolution it likes (iow; returns something higher than 0), and SDL_SetVideoMode() tries to set it, SDL_SetVideoMode() fails and I don't get my init. :?


Any ideas, suggestions?

cragwolf
23-05-2006, 01:59 AM
For a particular resolution, SDL_VideoModeOK may return OK, but if you subsequently add SDL_FULLSCREEN to the flags variable, there is no guarantee that SDL_SetVideoMode will work; they're two different video modes. Does SDL_SetVideoMode fail when FullScreen is False?

WILL
23-05-2006, 03:56 AM
Well that makes no sense. When the FULLSCREEN flag in SDL is not set it simply creates a Window and doesn't touch the physical video mode of your system.

But to asnswer your question; No, it just creates a normal window with a video overlay inside it as per normal SDL.

savage
23-05-2006, 08:39 AM
I agree with cragwolf here. SDL_VideoModeOK says that a particular video mode is fine, but does not guarantee that video mode works in fullscreen mode as well. So if you want to know if it works in fullscreen mode you need to pass SDL_VideoModeOK the fullscreen flag. I would re-write your function as follows...

// Video Mode Initialiation
function SetGameVideoMode(MinWidth, MinHeight: Integer; FullScreen: Boolean): PSDL_Surface;
var
i: Integer;
ResWidth, ResHeight: Array[0 .. 13] of Cardinal;
flags: Cardinal;
HasMode: Boolean;
SetWidth, SetHeight: Cardinal;
begin
// Set Software Surface Flag
flags := SDL_SWSURFACE;

// Set Fullscreen Flag
if (FullScreen) then
flags := flags + SDL_FULLSCREEN;

// Supported Game Resolutions
// 320x200 (PDA)
ResWidth[0] := 240;
ResHeight[0] := 320;
// 320x200 (Common)
ResWidth[1] := 320;
ResHeight[1] := 200;
// 320x240 (Common)
ResWidth[2] := 320;
ResHeight[2] := 240;
// 400x300 (Uncommon)
ResWidth[3] := 400;
ResHeight[3] := 300;
// 512x384 (Uncommon)
ResWidth[4] := 512;
ResHeight[4] := 384;
// 640x400 (Uncommon)
ResWidth[5] := 640;
ResHeight[5] := 400;
// 640x480 (Common)
ResWidth[6] := 640;
ResHeight[6] := 480;
// 800x600 (Common)
ResWidth[7] := 800;
ResHeight[7] := 600;
// 1024x768 (Common)
ResWidth[8] := 1024;
ResHeight[8] := 768;
// 1280x800 (Widescreen)
ResWidth[9] := 1280;
ResHeight[9] := 800;
// 1280x1024 (Common)
ResWidth[10] := 1280;
ResHeight[10] := 1024;
// 1600x1200 (???)
ResWidth[11] := 1600;
ResHeight[11] := 1200;
// 1920x1440 (???)
ResWidth[12] := 1920;
ResHeight[12] := 1440;
// 2048x1536 (???)
ResWidth[13] := 2048;
ResHeight[13] := 1536;

// Detect Lowest possible suppoerted resolution
HasMode := False;
if (not FullScreen) then
begin
HasMode := True;
SetWidth := MinWidth;
SetHeight := MinHeight;
end
else
begin
for i := Low(ResWidth) to High(ResWidth) do
if (MinWidth <= ResWidth[i]) and (MinHeight <= ResHeight[i]) then
if (SDL_VideoModeOK(ResWidth[i], ResHeight[i], 32, flags) > 0) then
begin
HasMode := True;
SetWidth := ResWidth[i];
SetHeight := ResHeight[i];
Break;
end;
end;

if (HasMode) then
Result := SDL_SetVideoMode(SetWidth, SetHeight, 32, flags)
else
Result := nil;
end;

WILL
23-05-2006, 01:08 PM
Oh... thats interesting... I'm not passing the flag with the FULLSCREEN flag up at all to SDL_VideoModeOK().

I didn't notice that! :P Thanks Dom! ;)