Sign in to follow this  
PotatoPie

Segmentation fault in SDL golf game

Recommended Posts

I've been using tutorials from http://sol.gfxile.net/gp/index.html to help me out, and as far as i know, the code that draws the level/hole should work, but instead i seem to be getting a segmentation fault. Its probably something really simple, but ive be staring at this for about 4 hours now, not getting anywhere, so any help is really appreciated, thank you :) Code: (in render function)
  /* draw level hole*/
  int i, j;
  for (i = 0; i < LEVELHEIGHT; i++)
  {
    for (j = 0; j < LEVELWIDTH; j++)
    {
      int color;
      switch (hole[i * LEVELWIDTH + j])
      {
      case LEVELBG:
        color = BLACK;
        break;
      case LEVELGRASS:
        color = GREEN;
        break;
      }
      drawHole(j * TILESIZE, i * TILESIZE, TILESIZE, TILESIZE, color);
    }
  }  


void drawHole(int x, int y, int tWidth, int tHeight, int colour)
{
  int i, j;
  for (i = 0; i < tHeight; i++)
  {
      for (j = 0; j < tWidth; j++)
        ((unsigned int*)surface->pixels)[i+j] = colour;
  }
    
    
}

Share this post


Link to post
Share on other sites
Your pixel calculation seems wrong, it should be either i * width + j, or i * pitch + j, depending if SDL surfaces use a pitch or not...

[Edit - removed stupid comments ;) didn't read the code properly]

Hope this helps

[Edited by - xEricx on May 17, 2006 4:07:59 PM]

Share this post


Link to post
Share on other sites
A segmentation fault generally occurs when you attempt to dereference a null pointer - as far as I can see this is probably occuring in your drawHole function. Lets go ahead and add in some checks to make sure we don't do anything bad -

void drawHole(int x, int y, int tWidth, int tHeight, int colour) {
int i, j;

#ifdef _DEBUG

if ( !surface ) {
// do something
fprintf( stderr, "Surface is null.\n" );
return;
}

if ( tWidth > surface->w ) {
// do something
fprintf( stderr, "Width exceeds surface dimensions.\n" );
return;
}

if ( tHeight > surface->h ) {
// do something
fprintf( stderr, "Height exceeds surface dimensions.\n" );
return;
}

#endif

for (i = y; i < tHeight; i++)
{
for (j = x; j < tWidth; j++) {
// fixed your index access, as mentioned above
// not entirely sure about the syntax though, I'll
// have to check on it.
((unsigned int*)surface->pixels)[i*tWidth*surface->pitch+j*surface->format->BytesPerPixel] = colour;
// EDIT: Yeah, that looks right.
}
}
}









I'd actually take the time to write functions dedicated to modifying the state of a surface (like, setting the value of a pixel) so that code duplication is reduced. It'll clean up the code a lot, and increase code reusability.

So you'd have a function like -
void setPixel( SDL_Surface* tex, int x, int y, SDLGfxAdapter::ColorType color ) {
char* pixel;

pixel = (char*) tex->pixels;
pixel += y*tex->pitch;
pixel += x*tex->format->BytesPerPixel;
memcpy( pixel, &color, tex->format->BytesPerPixel );
}

And use that function to clarify things a little. It would reduce the nasty line in the first function to

setPixel( surface, i, j, colour );

Which is unarguably nicer.

Hope that helps some :)

EDIT: Made some changes based on xEricx's points (basically, about the x and y in the loop). Didn't catch that ;)

[Edited by - Mushu on May 17, 2006 4:26:19 PM]

Share this post


Link to post
Share on other sites
There's also other problems with the code you posted...

First, x and y are ignored.

Your loops should look something like:



const int maxHeigth = min(y + tHeight, surface->height);
const int maxWidth = min(x + tWidth, surface->width);
for(int i = y, i < maxHeight; ++i)
{
for(int j = x; j < maxWidth; ++j)
{
// draw at j, i... if SDL surfaces use a pitch it would be something like:
((unsigned int*)surface->pixels)[i * surface->pitch + j] = colour;
}
}


if SDL surfaces does not use a pitch, use the width of the surface

Edit: oh true, I forgot about BPP :P follow Mushu's advise! except that I think you need to cast to char* if you wanna use BPPs, using unsigned int asusmes you're using 32bits. Optionnaly you might wanna test if your x,y are within the range of your surface (assert) in setPixel

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