Segmentation fault in SDL golf game

Started by
4 comments, last by PotatoPie 17 years, 11 months ago
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)
      {
      <span class="cpp-keyword">case</span> LEVELBG:
        color = BLACK;
        <span class="cpp-keyword">break</span>;
      <span class="cpp-keyword">case</span> LEVELGRASS:
        color = GREEN;
        <span class="cpp-keyword">break</span>;
      }
      drawHole(j * TILESIZE, i * TILESIZE, TILESIZE, TILESIZE, color);
    }
  }  


<span class="cpp-keyword">void</span> drawHole(<span class="cpp-keyword">int</span> x, <span class="cpp-keyword">int</span> y, <span class="cpp-keyword">int</span> tWidth, <span class="cpp-keyword">int</span> tHeight, <span class="cpp-keyword">int</span> colour)
{
  <span class="cpp-keyword">int</span> i, j;
  <span class="cpp-keyword">for</span> (i = <span class="cpp-number">0</span>; i &lt; tHeight; i++)
  {
      <span class="cpp-keyword">for</span> (j = <span class="cpp-number">0</span>; j &lt; tWidth; j++)
        ((<span class="cpp-keyword">unsigned</span> <span class="cpp-keyword">int</span>*)surface-&gt;pixels)[i+j] = colour;
  }
    
    
}
</pre></div><!–ENDSCRIPT–> 
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]
Also, I'd rename drawHole to drawTile or something ;)
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]
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) = colour;<br>    }<br>}<br></pre><br><br>if SDL surfaces does not use a pitch, use the width of the surface<br><br>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
Thank you so much for your help guys, I REALLY appreciate it :)

This topic is closed to new replies.

Advertisement