Sign in to follow this  
dudedbz1

SDL_FULLSCREEN - Has unexpected problem

Recommended Posts

Hey all! I made this pong clone. It runs well in windowed mode, but has an "Unexpected error!" on the end when in fullscreen. I ran it in the debugger and heres what it said:
Program received signal (SIGSEGV)
Segmentation fault
Heres my Main.cpp code(I have others, but they are just classes):
/***************************
*    I will quit mostly    *
*    any funtion with      *
*    1 on fail, including  *
*    main(...)!            *
*                          *
*    I will return 0       *
*    upon success.         *
***************************/

#include <windows.h>

#include "SDL.h"
#include "SDL_Image.h"
#include "Errors.h"
#include "Image.h"

SDL_Surface *Screen;

bool BallLeft = false;
bool BallRight = true;
bool BallUp = false;
bool BallDown = true;

int Init();
int InitResources(Image&, Image&, Image&, Image&);

void CleanUp();

bool UpdateGame(Image&, Image&, Image&, Image&);
void DrawGame(Image&, Image&, Image&, Image&);

void Draw(Image&);

int main(int, char**)
{
	if (Init() != 0)
        return 1;
        
    Image P1_Paddle;
    Image P2_Paddle;
    
    Image Ball;
    
    Image BG;
    
    if (InitResources(P1_Paddle, P2_Paddle, Ball, BG) != 0)
        return 1;
        
    while (UpdateGame(P1_Paddle, P2_Paddle, Ball, BG))
        DrawGame(P1_Paddle, P2_Paddle, Ball, BG);
    
    CleanUp();
    
    return 0;
}

int Init()
{
	if (SDL_Init(SDL_INIT_VIDEO) == -1)
    {
    	Fail(INITFAIL);
    	
    	return 1;
    }
	
    Screen = SDL_SetVideoMode(600, 500, 0, SDL_HWSURFACE | SDL_DOUBLEBUF/* | SDL_FULLSCREEN*/);
	
	if (Screen == NULL)
    {
    	Fail(INITFAIL);
    	
    	return 1;
    }
    
    SDL_WM_SetCaption("Pong", NULL);
	
	return 0;
}

int InitResources(Image &P1_Paddle, Image &P2_Paddle, Image &Ball, Image &BG)
{
	P1_Paddle.SetChar(IMG_Load("Images/Paddle.bmp"));
	P2_Paddle.SetChar(IMG_Load("Images/Paddle.bmp"));
	
	Ball.SetChar(IMG_Load("Images/Ball.bmp"));
	
	BG.SetChar(IMG_Load("Images/BG.bmp"));
	
	if (P1_Paddle.CharReady() == false || 
	    P2_Paddle.CharReady() == false ||
        Ball.CharReady() == false ||
        BG.CharReady() == false)
	{
		Fail(LOADFAIL);
		
		return 1;
	}
	
	P1_Paddle.SetColorKey();
	P2_Paddle.SetColorKey();
	
	Ball.SetColorKey();
	
	P1_Paddle.Setx(225);
	P1_Paddle.Sety(480);
	
	P2_Paddle.Setx(225);
	
	Ball.Sety(300);
	Ball.Setx(250);
	    
    return 0;
}

void CleanUp()
{
	SDL_Quit();
}

bool UpdateGame(Image &P1_Paddle, Image &P2_Paddle, Image &Ball, Image &BG)
{
	Uint8 *Keys = SDL_GetKeyState(NULL);
		
    SDL_Event Event;
	
	if (SDL_PollEvent(&Event))
	{
        if (Event.type == SDL_QUIT)
            return false;
	}
	
	if ((Keys[SDLK_LALT] && Keys[SDLK_F4]) || (Keys[SDLK_RALT] && Keys[SDLK_F4]) || Keys[SDLK_ESCAPE])
	    return false;
	    
    if (Ball.Getx() < (P2_Paddle.Getx() + (P2_Paddle.GetChar()->w / 2) - (Ball.GetChar()->w / 2)))
        P2_Paddle.Setx(P2_Paddle.Getx() - 2);
    if (Ball.Getx() > (P2_Paddle.Getx() + (P2_Paddle.GetChar()->w / 2) - (Ball.GetChar()->w / 2)))
        P2_Paddle.Setx(P2_Paddle.Getx() + 2);
    
    if (P2_Paddle.Getx() < BG.Getx())
        P2_Paddle.Setx(BG.Getx());
        
    if ((P2_Paddle.Getx() + P2_Paddle.GetChar()->w) > (BG.Getx() + BG.GetChar()->w))
        P2_Paddle.Setx((BG.Getx() + BG.GetChar()->w) - P2_Paddle.GetChar()->w);
	    
    if (Ball.Getx() < BG.Getx())
    {
        BallLeft = false;
        BallRight = true;
    }
        
    if ((Ball.Getx() + Ball.GetChar()->w) > (BG.Getx() + BG.GetChar()->w))
    {
        BallRight = false;
        BallLeft = true;
    }
    
    if (Ball.CollideOnTop(P2_Paddle))
    {
    	BallUp = false;
    	BallDown = true;
    }
    
    if (Ball.CollideOnBottom(P1_Paddle))
    {
    	BallDown = false;
    	BallUp = true;
    }
    
    if (BallLeft)
        Ball.Setx(Ball.Getx() - 2);
        
    if (BallRight)
        Ball.Setx(Ball.Getx() + 2);
        
    if (BallUp)
        Ball.Sety(Ball.Gety() - 2);
        
    if (BallDown)
        Ball.Sety(Ball.Gety() + 2);
	    
    if (Keys[SDLK_LEFT] && P1_Paddle.Getx() > BG.Getx())
        P1_Paddle.Setx(P1_Paddle.Getx() - 2);
        
    if (Keys[SDLK_RIGHT] && (P1_Paddle.Getx() + P1_Paddle.GetChar()->w) < (BG.Getx() + BG.GetChar()->w))
        P1_Paddle.Setx(P1_Paddle.Getx() + 2);
        
    if ((Ball.Gety() + Ball.GetChar()->h) > (BG.Gety() + BG.GetChar()->h))
    {
    	Ball.Sety(300);
        Ball.Setx(250);
    }
	    
    return true;
}

void DrawGame(Image &P1_Paddle, Image &P2_Paddle, Image &Ball, Image &BG)
{
	SDL_FillRect(Screen, NULL, SDL_MapRGB(Screen->format, 0, 0, 0));
	
	Draw(BG);
		
    Draw(P1_Paddle);
	Draw(P2_Paddle);
	
    Draw(Ball);
    
    SDL_Flip(Screen);
}

void Draw(Image &Sprite)
{
    SDL_Rect Source;
    SDL_Rect Dest;

    Source.x = 0;
    Source.y = 0;
    Source.w = Sprite.GetChar()->w;
    Source.h = Sprite.GetChar()->h;

    Dest.x = Sprite.Getx();
    Dest.y = Sprite.Gety();
    Dest.w = Source.w;
    Dest.h = Source.h;

    SDL_BlitSurface(Sprite.GetChar(), &Source, Screen, &Dest);
}

Any suggestions?

Share this post


Link to post
Share on other sites
Hmmm... Doesnt seem to fix it. I changed the resolution, but it still persists. Maybe its in my class?

class Image
{
public:
Image() {m_x = 0;
m_y = 0;}
~Image() {if (m_Char != NULL)
SDL_FreeSurface(m_Char);
else
Fail(UNLOADFAIL);}

int Getx() {return m_x;}
int Gety() {return m_y;}

void Setx(int temp) {m_x = temp;}
void Sety(int temp) {m_y = temp;}

SDL_Surface *GetChar() {return m_Char;}
void SetChar(SDL_Surface *temp) {m_Char = SDL_DisplayFormat(temp);
SDL_FreeSurface(temp);}

bool CharReady() {if (m_Char == NULL) return false;
if (m_Char != NULL) return true;}

bool CollideOnTop(Image&);
bool CollideOnBottom(Image&);

void SetColorKey() {SDL_SetColorKey(m_Char,
SDL_SRCCOLORKEY,
SDL_MapRGB(m_Char->format,
255, 255, 255));}

private:
SDL_Surface *m_Char;

int m_x;
int m_y;
};




P.S. It doesnt return null, screen still draws and this:

if (Screen == NULL)
{
Fail(INITFAIL);

return 1;
}

doesnt fail!

Share this post


Link to post
Share on other sites
Code::Blocks. And yes, I told you what the debugger says in my first post. Do you think it might be the SDL_DisplayFormat(...)? Hmm.. Lets see(in real time)... AHA! It is! But why would that cause the problem?

Share this post


Link to post
Share on other sites
I had the same problem! (See this)

The answer is to pass SDL_SWSURFACE instead of SDL_HWSURFACE (you also can't pass SDL_DOUBLEBUF) I don't know why hardware surfaces introduce these bugs. It's pretty frustrating.

This problem was mentioned in the book Programming Linux Games so I think that it's not just somthing wrong with our code.

Share this post


Link to post
Share on other sites
a debugger might point to the line where it segfaults!

not just that it is segfaulting...

why SDL_DisplayFormat(...)?

because its the only part of your loading code that varys with the SDL_SetVideoMode(...);

the whole SW/HW surface thing shouldn't affect a segfault, maybe it does though.

not doubting that it fixed your(Simian's) problem, but why would it affect it...

its too late for this kind of mental stuff. maybe tomorrow

[Edited by - rip-off on October 7, 2005 6:24:17 AM]

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this