Jump to content
  • Advertisement
Sign in to follow this  
PotatoPie

Segmentation fault in SDL golf game

This topic is 4442 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

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
Advertisement
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
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!