Sign in to follow this  
dudedbz1

SDL_Flip() crashing

Recommended Posts

Hi all! Here we go!!! SDL_Flip() seems to crash my program. I figured this by commenting out my line:
//app.Flip();
Now, here is that function:
void cApp_Flip() {SDL_Flip(m_Screen);}
m_Screen gets set up with this:
app.cApp_InitWindow(SCREEN_H, SCREEN_W, SDL_HWSURFACE | SDL_DOUBLEBUF)

//which is:
bool ret = (app.cApp_Init(SDL_INIT_VIDEO) &&
                app.cApp_InitWindow(SCREEN_H, SCREEN_W, SDL_HWSURFACE | SDL_DOUBLEBUF) &&
                app.cApp_AddImage("Paddle.bmp") &&
                app.cApp_AddImage("Paddle.bmp") &&
                app.cApp_AddImage("Ball.bmp"));


I AM using SDL_DOUBLEBUF, so that is not the case. So what can be a possible cause for SDL_Flip(..) failing? P.S. It seems that if I comment that line out my program does not draw my pictures, but DOES draw them when I draw the program under the start menu and back up...

Share this post


Link to post
Share on other sites
Chances are your m_Screen is NULL or some random value because you did not properly initilize it. Just to see if I'm right, try:
void cApp_Flip() {SDL_Flip(SDL_GetVideoSurface());}
If it works fine now, you will need to make your code assign m_Screen a proper value: m_Screen = SDL_GetVideoSurface(); after you initialize SDL and create your display window.

If it doesn't work, make sure that function is not being called before you initialize SDL and your display window.

Share this post


Link to post
Share on other sites
Quote:
Original post by Drew_Benton
Chances are your m_Screen is NULL or some random value because you did not properly initilize it. Just to see if I'm right, try:
void cApp_Flip() {SDL_Flip(SDL_GetVideoSurface());}
If it works fine now, you will need to make your code assign m_Screen a proper value: m_Screen = SDL_GetVideoSurface(); after you initialize SDL and create your display window.

If it doesn't work, make sure that function is not being called before you initialize SDL and your display window.


Good idea, but it still doesnt work. It crashes on that line.

I'm pretty sure m_Screen isnt null, or else my above code snippet's "ret" would be false and the program would quit before the flip...

Share this post


Link to post
Share on other sites
Quote:
Original post by dudedbz1
I'm pretty sure m_Screen isnt null, or else my above code snippet's "ret" would be false and the program would quit before the flip...


Oh ok, so in your cApp_InitWindow function, you have something like this:
m_Screen = SDL_SetVideoMode(SCREEN_W, SCREEN_H, bpp, flags)

Also just noting you pass in the heigth then the width 1st in your code, is your function handling that properly. Other than that, only reason I could see it crash is with an invalid surface, what do all your functions look like: cApp_Init, cApp_InitWindow, and cApp_AddImage. Also you might want to try not putting all of those in that one line, break it up to make sure things are getting called in the right order:
int error = 0;
error += app.cApp_Init(SDL_INIT_VIDEO);
error += app.cApp_InitWindow(SCREEN_H, SCREEN_W, SDL_HWSURFACE | SDL_DOUBLEBUF);
error += app.cApp_AddImage("Paddle.bmp");
error += app.cApp_AddImage("Paddle.bmp");
error += app.cApp_AddImage("Ball.bmp");


Now if error > 0, then one of them failed (assuming your return 0 on no error and 1 on error), and you are sure they all got called in the right order.

Share this post


Link to post
Share on other sites
Quote:
Original post by Drew_Benton
Quote:
Original post by dudedbz1
I'm pretty sure m_Screen isnt null, or else my above code snippet's "ret" would be false and the program would quit before the flip...


Oh ok, so in your cApp_InitWindow function, you have something like this:
m_Screen = SDL_SetVideoMode(SCREEN_W, SCREEN_H, bpp, flags)

Also just noting you pass in the heigth then the width 1st in your code, is your function handling that properly. Other than that, only reason I could see it crash is with an invalid surface, what do all your functions look like: cApp_Init, cApp_InitWindow, and cApp_AddImage. Also you might want to try not putting all of those in that one line, break it up to make sure things are getting called in the right order:
int error = 0;
error += app.cApp_Init(SDL_INIT_VIDEO);
error += app.cApp_InitWindow(SCREEN_H, SCREEN_W, SDL_HWSURFACE | SDL_DOUBLEBUF);
error += app.cApp_AddImage("Paddle.bmp");
error += app.cApp_AddImage("Paddle.bmp");
error += app.cApp_AddImage("Ball.bmp");


Now if error > 0, then one of them failed (assuming your return 0 on no error and 1 on error), and you are sure they all got called in the right order.


Hmmm... I changed my Init function so that everything is called in order, but it still doest work, so I changed it back. Its not the problem most likely anyways, since cApp_AddImage(...) doesnt really need SDL, just the drawing does.

The screen width and height is most likely correct, but it doesnt really matter since for now both my height and width are 500 pixels... Here are the functions:

bool cApp::cApp_Init(unsigned int flags, bool text)
{
if (SDL_Init(flags) == -1)
return false;

if (text)
{
if (TTF_Init() == -1)
return false;

_TextOn = true;
}
else
_TextOn = false;

return true;
}

bool cApp::cApp_InitWindow(int h, int w, unsigned int flags)
{
m_Screen = SDL_SetVideoMode(w, h, 0, flags);

if (m_Screen == NULL)
return false;

return true;
}

bool cApp::cApp_AddImage(const char *fileName)
{
Image *imageToAdd = new Image;

imageToAdd->SetSprite(IMG_Load(fileName));

if (imageToAdd->GetSprite() == NULL)
{
delete imageToAdd;

return false;
}

m_Graphics.push_back(imageToAdd);

return true;
}



They all have error checking(true or false), and according to what they return, they are all true. Paddle.bmp and Ball.bmp exist.

The cApp_Draw(...) function does not fail, because if I comment out the flipping it works... I dont know what might be the bug...

P.S. I dont know if it is of any help, but it looks like when I comment out the flipping and when I draw the app below the start bar and up again everything is drawn. It isnt at the beginning.

Share this post


Link to post
Share on other sites
SDL_Flip returns an int.

if its -1 then there was an error.

if theres an error then cout << SDL_GetError() << endl;

also, you might want to try

SDL_UpdateRect( SDL_GetVideoSurface() , 0, 0, 0, 0)

it an alternative to SDL_Flip, but doesnt do double buffering. you could try it out though to see if it still crashes. BTW, there is nothing in sdterr.txt, is there?

do you ever call SDL_LockSurface( m_screen ) ? thats the only reason i could think of it failing...

Share this post


Link to post
Share on other sites
Quote:
Original post by rip-off
SDL_Flip returns an int.

if its -1 then there was an error.

if theres an error then cout << SDL_GetError() << endl;

also, you might want to try

SDL_UpdateRect( SDL_GetVideoSurface() , 0, 0, 0, 0)

it an alternative to SDL_Flip, but doesnt do double buffering. you could try it out though to see if it still crashes. BTW, there is nothing in sdterr.txt, is there?

do you ever call SDL_LockSurface( m_screen ) ? thats the only reason i could think of it failing...


YES YES YES!!! Thanks sooo much.

Anyways, SDL_UpdateRect(...) works... But why? I'm using SDL_DOUBLEBUF, so why would it work and SDL_Flip() fail? The screen is not locked. There is nothing in stderr.txt. Anyone have any ideas why?

Share this post


Link to post
Share on other sites
Quote:
Original post by dudedbz1
Quote:
Original post by rip-off
SDL_Flip returns an int.

if its -1 then there was an error.

if theres an error then cout << SDL_GetError() << endl;

also, you might want to try

SDL_UpdateRect( SDL_GetVideoSurface() , 0, 0, 0, 0)

it an alternative to SDL_Flip, but doesnt do double buffering. you could try it out though to see if it still crashes. BTW, there is nothing in sdterr.txt, is there?

do you ever call SDL_LockSurface( m_screen ) ? thats the only reason i could think of it failing...


YES YES YES!!! Thanks sooo much.

Anyways, SDL_UpdateRect(...) works... But why? I'm using SDL_DOUBLEBUF, so why would it work and SDL_Flip() fail? The screen is not locked. There is nothing in stderr.txt. Anyone have any ideas why?


So, anyone have an idea why UpdateRect might work but SDL_Flip doesnt?

Share this post


Link to post
Share on other sites
Did you actually try Drew's suggestion for using SDL_GetVideoSurface() instead of your m_Screen variable? SDL_Flip calls SDL_UpdateRect internally if SDL_DOUBLEBUF is not available so there really shouldn't be a difference.

What version of SDL do you have installed?

Try walking through the code with a debugger. Put a break point right before that line of code and see what the value of m_Screen is before and durring the SDL_Flip function.

Share this post


Link to post
Share on other sites
Quote:
Original post by dudedbz1
So, anyone have an idea why UpdateRect might work but SDL_Flip doesnt?


Well you got me, no clue why the SDL_Flip isn't working at all. If you could post all your code, that is if you wanted to, I'd not mind taking a look though it and see if it crashes on my computer.

Hey, by any chance, do you have a new NVidia card, either PCI-E or higher model past 6600 either agp? There was a recent thread with a problem with SDL and that type, so if you do have one of those, maybe it's a new problem that has not been acknowledge yet.

Share this post


Link to post
Share on other sites
Quote:
Original post by Drew_Benton
Quote:
Original post by dudedbz1
So, anyone have an idea why UpdateRect might work but SDL_Flip doesnt?


Well you got me, no clue why the SDL_Flip isn't working at all. If you could post all your code, that is if you wanted to, I'd not mind taking a look though it and see if it crashes on my computer.

Hey, by any chance, do you have a new NVidia card, either PCI-E or higher model past 6600 either agp? There was a recent thread with a problem with SDL and that type, so if you do have one of those, maybe it's a new problem that has not been acknowledge yet.


Well, I guess I can do that. It's just that there's a lot of code that I'm not using yet, so I'll see what to post here. It's most likely not my video card, since I have used this same method before... And the interesting part is, that with this:

int main(int, char**)
{
cApp app(1);

app.cApp_Init(SDL_INIT_VIDEO);
app.cApp_InitWindow(500, 500, SDL_HWSURFACE | SDL_DOUBLEBUF);

app.cApp_AddImage("Paddle.bmp");

SDL_Event event;

while (true)
{
app.cApp_RefreshScreen();

if (SDL_PollEvent(&event))
{
if (event.type == SDL_QUIT)
break;
}

app.cApp_Draw(0);
app.cApp_Flip();
}

app.cApp_DeInit();

return 0;
}




It works perfectly... I just dont know...

Well, here is the code:

//main.cpp

#include <SDL.h>

#include "cApp.h"

const int NUM_IMAGES = 3;

cApp app(NUM_IMAGES);

const int SCREEN_H = 500;
const int SCREEN_W = 500;

const int FAIL = 1;
const int SUCCESS = 0;

enum {P1, P2, BALL};

bool Init();
void DeInit();

bool Run();
void Draw();

int MiddleWidth(int width1, int width2)
{
return ((width1 / 2) - (width2 / 2));
}
int MiddleHeight(int height1, int height2)
{
return ((height1 / 2) - (height2 / 2));
}

int main(int argc, char *argv[])
{
if (Init() == false)
return FAIL;

while (Run())
Draw();

DeInit();

return SUCCESS;
}

bool Init()
{
bool ret = (app.cApp_Init(SDL_INIT_VIDEO) &&
app.cApp_InitWindow(SCREEN_H, SCREEN_W, SDL_HWSURFACE | SDL_DOUBLEBUF) &&
app.cApp_AddImage("Paddle.bmp") &&
app.cApp_AddImage("Paddle.bmp") &&
app.cApp_AddImage("Ball.bmp"));

app.cApp_GetImage(BALL)->SetColorKey();

app.cApp_GetImage(P1)->Setx(MiddleWidth(SCREEN_W, app.cApp_GetImage(P1)->Getw()));

return ret; // by accident I have true
}

void DeInit()
{
app.cApp_DeInit();
}

bool Run()
{
SDL_Event event;

while (SDL_PollEvent(&event))
{
if (event.type == SDL_QUIT)
return false;

if (event.type == SDL_KEYDOWN)
{
if (event.key.keysym.sym == SDLK_ESCAPE)
return false;
}
}
}

void Draw()
{
app.cApp_RefreshScreen();

app.cApp_Draw(P1);
app.cApp_Draw(P2);
app.cApp_Draw(BALL);

app.cApp_Flip();
}

//cApp.h

#ifndef SDL_ENGINEMAIN_H
#define SDL_ENGINEMAIN_H

#include <SDL.h>

#include "cApp_Image.h"
#include "cApp_Text.h"

#include <vector>
#include <string>

using std::vector;

class cApp
{
public:
cApp(int numToReserve = 0, int numTextToReserve = 0);
~cApp();

bool cApp_InitWindow(int h, int w, unsigned int flags);

bool cApp_Init(unsigned int flags, bool text = false);
void cApp_DeInit();

void cApp_IncreaseGraphics(int numToReserve = 0);
void cApp_IncreaseText(int numToReserve = 0);

void cApp_AddText();

bool cApp_AddImage(const char *fileName);
Image *cApp_GetImage(int numOfImage);

Text *cApp_GetText(int i);

void cApp_RemoveLastText();
void cApp_RemoveText(int i);

void cApp_RemoveLastImage();
void cApp_RemoveImage(int imageToRemove);

void cApp_Draw(int i);
void cApp_DrawText(int i);

void cApp_Flip()//;
{
SDL_Flip(m_Screen);
// SDL_UpdateRect(m_Screen, 0, 0, 0, 0);
}
void cApp_RefreshScreen() {SDL_FillRect(m_Screen, NULL, 0xffffcc);}

bool cApp_Collide(int i, int j);
bool cApp_Collide(char direction, int i, int j);

void cApp_SetTitle(const char *title);

private:
vector<Image*> m_Graphics;
vector<Text*> m_Text;

bool _TextOn;

SDL_Surface *m_Screen;
};

#endif /*SDL_ENGINEMAIN_H*/

//cApp.cpp

#include <SDL.h>

#include <vector>

#include "cApp.h"

using std::vector;

cApp::cApp(int numToReserve, int numTextToReserve)
{
m_Graphics.reserve(numToReserve);
m_Text.reserve(numTextToReserve);
}

cApp::~cApp()
{
for (int i = 0; i < m_Graphics.size(); i++)
delete m_Graphics[i];
for (int j = 0; j < m_Text.size(); j++)
delete m_Text[j];
}

bool cApp::cApp_InitWindow(int h, int w, unsigned int flags)
{
m_Screen = SDL_SetVideoMode(w, h, 0, flags);

if (m_Screen == NULL)
return false;

return true;
}

bool cApp::cApp_Init(unsigned int flags, bool text)
{
if (SDL_Init(flags) == -1)
return false;

if (text)
{
if (TTF_Init() == -1)
return false;

_TextOn = true;
}
else
_TextOn = false;

return true;
}

void cApp::cApp_DeInit()
{
if (_TextOn)
{
TTF_Quit();
}

SDL_Quit();
}

void cApp::cApp_IncreaseGraphics(int numToReserve)
{
m_Graphics.reserve(numToReserve);
}

void cApp::cApp_IncreaseText(int numToReserve)
{
m_Text.reserve(numToReserve);
}

void cApp::cApp_AddText()
{
m_Text.push_back(new Text);
}

bool cApp::cApp_AddImage(const char *fileName)
{
Image *imageToAdd = new Image;

imageToAdd->SetSprite(IMG_Load(fileName));

if (imageToAdd->GetSprite() == NULL)
{
delete imageToAdd;

return false;
}

m_Graphics.push_back(imageToAdd);

return true;
}

Text *cApp::cApp_GetText(int i)
{
if (i < m_Text.size())
return m_Text[i];

return NULL;
}

Image *cApp::cApp_GetImage(int numOfImage)
{
if (numOfImage < m_Graphics.size())
return m_Graphics[numOfImage];

return NULL;
}

void cApp::cApp_RemoveLastText()
{
int textToRemove = m_Text.size() - 1;

delete m_Text[textToRemove];

m_Text.pop_back();
}

void cApp::cApp_RemoveText(int i)
{
delete m_Text[i];

m_Text[i] = m_Text[i + 1];

for (int iter = i + 1; iter < m_Graphics.size(); iter++)
{
if (m_Text[iter + 1] != NULL)
m_Text[iter] = m_Text[iter + 1];
}

m_Text.pop_back();
}

void cApp::cApp_RemoveLastImage()
{
int imageToRemove = m_Graphics.size() - 1;

delete m_Graphics[imageToRemove];

m_Graphics.pop_back();
}

void cApp::cApp_RemoveImage(int imageToRemove)
{
delete m_Graphics[imageToRemove];

m_Graphics[imageToRemove] = m_Graphics[imageToRemove + 1];

for (int i = imageToRemove + 1; i < m_Graphics.size(); i++)
{
if (m_Graphics[i + 1] != NULL)
m_Graphics[i] = m_Graphics[i + 1];
}

m_Graphics.pop_back();
}

void cApp::cApp_DrawText(int i)
{
if (i < m_Text.size())
{
if (m_Text[i]->GetTextSurface() != NULL)
{
SDL_Rect src, dst;

dst.x = m_Text[i]->Getx();
dst.y = m_Text[i]->Gety();
dst.w = m_Text[i]->Getw();
dst.h = m_Text[i]->Geth();

src.x = 0;
src.y = 0;
src.w = dst.w;
src.h = dst.h;

SDL_BlitSurface(m_Text[i]->GetTextSurface(), &src, m_Screen, &dst);
}
}
}

void cApp::cApp_Draw(int i)
{
if (i < m_Graphics.size())
{
if (m_Graphics[i]->GetSprite() != NULL)
{
SDL_Rect src, dst;

dst.x = m_Graphics[i]->Getx();
dst.y = m_Graphics[i]->Gety();
dst.w = m_Graphics[i]->Getw();
dst.h = m_Graphics[i]->Geth();

src.x = 0;
src.y = 0;
src.w = dst.w;
src.h = dst.h;

SDL_BlitSurface(m_Graphics[i]->GetSprite(), &src, m_Screen, &dst);
}
}
}

bool cApp::cApp_Collide(int i, int j)
{
if (i < m_Graphics.size() && j < m_Graphics.size())
{
SDL_Rect image1, image2;

image1.x = m_Graphics[i]->Getx();
image1.y = m_Graphics[i]->Gety();
image1.w = m_Graphics[i]->Getw();
image1.h = m_Graphics[i]->Geth();

image2.x = m_Graphics[j]->Getx();
image2.y = m_Graphics[j]->Gety();
image2.w = m_Graphics[j]->Getw();
image2.h = m_Graphics[j]->Geth();

if (image1.x >= (image2.x + image2.w) || image2.x >= (image1.x + image1.w))
return false; // They are not in the same horizontal space

if (image1.y >= (image2.y + image2.h) || image2.y >= (image1.y + image1.h))
return false; // They are not in the same vertical space

return true;
}

return false; // Huh? i || j are not in m_Images!
}

bool cApp::cApp_Collide(char direction, int i, int j)
{
if (i < m_Graphics.size() && j < m_Graphics.size())
{
SDL_Rect image1, image2;

image1.x = m_Graphics[i]->Getx();
image1.y = m_Graphics[i]->Gety();
image1.w = m_Graphics[i]->Getw();
image1.h = m_Graphics[i]->Geth();

image2.x = m_Graphics[j]->Getx();
image2.y = m_Graphics[j]->Gety();
image2.w = m_Graphics[j]->Getw();
image2.h = m_Graphics[j]->Geth();

if (direction == 'x')
if (image1.x >= (image2.x + image2.w) || image2.x >= (image1.x + image1.w))
return false;

if (direction == 'y')
if (image1.y >= (image2.y + image2.h) || image2.y >= (image1.y + image1.h))
return false;

return true;
}

return false; // Huh? i || j are not in m_Images!
}

void cApp::cApp_SetTitle(const char *title)
{
SDL_WM_SetCaption(title, NULL);
}





...

Anyways, notice my header file checks... SDL_ENGINEMAIN_H was the previous name, but now that I'm not gonna use it JUST for SDL and I'm gonna expand it I thought I might change it a little.

As I said, the little one works, but the big one doesnt... Maybe its something from the way I have my functions set up?

//Edit: Oh, you want to see if it'll crash on you pc too? Then I must have the other two files.. lol


//cApp_Image.h

#ifndef IMAGE_H
#define IMAGE_H

#include <SDL.h>

#include <SDL_image.h>

class Image
{
public:
Image(int x = 0, int y = 0): m_x(x), m_y(y), m_Sprite(NULL)
{
}
~Image()
{
if (m_Sprite != NULL)
SDL_FreeSurface(m_Sprite);
}

int Getx() {return m_x;}
void Setx(int x) {m_x = x;}

int Gety() {return m_y;}
void Sety(int y) {m_y = y;}

int Getw() {return m_Sprite->w;}
int Geth() {return m_Sprite->h;}

void SetSprite(SDL_Surface *sprite)
{
m_Sprite = sprite;
}
SDL_Surface *GetSprite() {return m_Sprite;}

void SetColorKey()
{
SDL_SetColorKey(m_Sprite, SDL_SRCCOLORKEY, 0xffffff);
}

private:
int m_x;
int m_y;

SDL_Surface *m_Sprite;
};

#endif /*IMAGE_H*/

//cApp_Text.h

#ifndef TEXT_H
#define TEXT_H

#include <SDL.h>

#include <SDL_ttf.h>

class Text
{
public:
Text(int x = 0, int y = 0): m_x(x), m_y(y), m_TextSurface(NULL)
{
}
~Text()
{
if (m_TextSurface != NULL)
SDL_FreeSurface(m_TextSurface);
}

int Getx() {return m_x;}
void Setx(int x) {m_x = x;}

int Gety() {return m_y;}
void Sety(int y) {m_y = y;}

int Getw() {return m_TextSurface->w;}
int Geth() {return m_TextSurface->h;}

SDL_Surface *GetTextSurface() {return m_TextSurface;}

void SetTextColor(int r, int g, int b)
{
m_TextColor.r = r;
m_TextColor.g = g;
m_TextColor.b = b;
}
SDL_Color GetTextColor() {return m_TextColor;}

void SetSize(int Size) {m_Size = Size;}
int GetSize() {return m_Size;}

void SetFont(const char *Font)
{
m_Font = TTF_OpenFont(Font, m_Size);
}

void SetText(const char *Text)
{
m_TextSurface = TTF_RenderText_Solid(m_Font, Text, m_TextColor);
}

private:
int m_x;
int m_y;

int m_Size;

TTF_Font *m_Font;

SDL_Color m_TextColor;

SDL_Surface *m_TextSurface;
};

#endif






I hope we can solve this mystery, lol.

[Edited by - dudedbz1 on November 6, 2005 8:35:17 AM]

Share this post


Link to post
Share on other sites
Quote:
Original post by rip-off
change your Run function to return true if nothing unusual happens

with that your code it works for me.

for some reason if you change SDL_Flip to SDL_UpdateRect it works aswell thats puzzeling...

see if that helps...


Yes! That works! I cant beleive I forgot something sooo simple... Aww well. Not to be any more annoying, but if the while loop exited with the Flip(), then why not exit with the Update?

Thanks to Drew_Benton and rip-off!

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