SDL: Window FS Window FS HANG (solved)

Started by
5 comments, last by Kwizatz 18 years, 1 month ago
I've begun working on a(nother) SDL-based 2D engine but I've ran into a problem with switching back and forth between windowed and fullscreen modes. Basically, after a couple of switches the SDL window/screen hangs (always when going from fullscreen to windowed). I'd provide a pic, but I have to restart the computer when this happens. Here's the relevant code, and I'm using OS X 10.4.5 if it makes any difference:

void oth::Window::switchBetweenWindowAndFull()
{
	/**
		If SDL is NOT currently in fullscreen mode then switch to fullscreen, otherwise go
		into window mode
	*/
	
	if(inFullScreen == false)
	{
		userSelectedFlags |= SDL_FULLSCREEN;
		screen = SDL_SetVideoMode(userSelectedWidth, userSelectedHeight, userSelectedBPP, userSelectedFlags);		
		inFullScreen = true;
	}
	else
	{
		/**
			There is a chance that the userSelectedFlags variable may be set to SDL_FULLSCREEN (eg, the user requested
			SDL_FULLSCREEN when the window was created). "userSelectedFlags &= ~(userSelectedFlags << SDL_FULLSCREEN)" 
			will turn it off if it's set and leave it off if it isn't set.
		*/
		userSelectedFlags &= ~(userSelectedFlags << SDL_FULLSCREEN);
		screen = SDL_SetVideoMode(userSelectedWidth, userSelectedHeight, userSelectedBPP, userSelectedFlags);
		inFullScreen = false;
	}
}



The code works fine and I can succesfully switch back and forth about two times before the problem (stays in fullscreen mode and is unresponsive to all input, requires restart) occurs. Anyway, thanks for taking the time to look over the code. [Edited by - ontheheap on March 2, 2006 7:13:39 AM]
Advertisement
There is something I don't like about the left shift operation, I think it should just be userSelectedFlags &= ~(SDL_FULLSCREEN) but I am not 100% sure.
I believe using ~(SDL_FULLSCREEN) would provide an incorrect result. Here's a check:

#include <iostream>const int A = 10;const int B = 212;const int C = 300;int main () {		int FLAGS_x = A | B | C;        std::cout << "FLAGS_x = " << FLAGS_x << std::endl;		int FLAGS_y = A | C;	std::cout << "FLAGS_y = " << FLAGS_y << std::endl;		int test_a = FLAGS_x;	test_a &= ~(test_a << B);        // test_a should be the same as FLAGS_y, and it is	std::cout << test_a << std::endl;        int test_b = FLAGS_x;        test_b &= ~(B);        // test_b does not have the same value as FLAGS_y        std::cout << test_a << std::endl;	    return 0;}


The output is:

FLAGS_x = 510FLAGS_y = 302test_a = 510test_b = 298


I've checked the values of userSelectedFlags in my engine code as well and it's ok.
You say:
'test_a should be the same as FLAGS_y, and it is'

But it isn't : test_a is the same as FLAGS_x.

You should turn off a flag with &= ~FLAG_VALUE.
Note that flags should be powers of 2, not any arbitary value like in your example.
Anon is right, when you use flags each bit in the variable represents an on/off flag, so you cannot regard it as a number anymore, SDL_FULLSCREEN equals 0x80000000, by shifting userSelectedFlags an insane amount of bits to the left (the bit is droped if there is no more space), example:

0001 << 0 = 0001
0001 << 1 = 0010
0001 << 2 = 0100
0001 << 3 = 1000
0001 << 4 = 0000

So, you're effectivelly turning the statement inside the parentesis into zero, thus userSelectedFlags & ~(userSelectedFlags << SDL_FULLSCREEN) == userSelectedFlags, so you changed nothing.

lets imagine for a moment that SDL_FULLSCREEN=1 (binary: 0001) and userSelectedFlags=3 (binary: 0011)

you say:

userSelectedFlags &= ~(userSelectedFlags << SDL_FULLSCREEN);
userSelectedFlags &= ~(0011 << 0001);
userSelectedFlags &= ~(0110);
userSelectedFlags &= 1001;
userSelectedFlags = 0011&1001;
userSelectedFlags = 0001;

as you can see, you managed to (accidentally) turn off the other flag, but SDL_FULLSCREEN is still on!

Now I say:
userSelectedFlags &= ~(SDL_FULLSCREEN);
userSelectedFlags &= ~(0001);
userSelectedFlags &= 1110;
userSelectedFlags = 0011&1110;
userSelectedFlags = 0010;

Which is what we wanted, now, notice that if userSelectedFlags already is 0010, it doesn't get modified:

userSelectedFlags &= ~(SDL_FULLSCREEN);
userSelectedFlags &= ~(0001);
userSelectedFlags &= 1110;
userSelectedFlags = 0010&1110;
userSelectedFlags = 0010;

Hope that clears it up [smile].
That's exactly what the problem was and now it's working fine! Thanks, I really appreciate the help.
No problem! [smile]

This topic is closed to new replies.

Advertisement