Segfault when blitting near edges of screen

Repost: Whoops, I sent this message a few minutes ago but from the wrong
adress, so I’m reposting from the correct user.

I’m just getting started with SDL and I’ve written a small PCX loader and
I’m working on blitting the image to the screen and doing some clipping code
for the edges of the screen. However, when I try to blit the image “almost
completely outside the screen” the application just quits and I get a
stderr.txt with the contents “Fatal signal: Segmentation Fault (SDL
Parachute Deployed)”.

Another wierd thing is that it only happens on the “sides” of the screen. My
boundary checking code works for the top and bottom of the screen. Another
(!) wierd thing is that it doens’t happen when the image is completely
outside the screen but rather when there are something like 15 och 16 pixels
left to blit. It is very hard to describe so here is a link to the simple
app. Move the image with the arrow keys. Notice how it works in y but not in
x and how it quits 15 or 16 pixels from the edge?

http://kennel.dyndns.org/~kennel/dload.pl?test.zip

Hope someone can help me.

Regards
Rickard Andersson, Sweden

I have included the blitting function in my PCXLoader class. The member
variables are imgHeight, imgWidth, scrHeight, scrWidth and data (the pointer
to the image that is to be blitted to the surface).

Parameters:

screen = the pointer to the surface (called with (int*)screen->pixels)

x, y = the coordinates where the image is to be blitted (center of image)

bool PCXLoader::blit( int *screen, short x, short y )
{
// If the x-, and y-coordinates would put the image outside the screen
completely
// REMARK: This obviously doesn’t do the job.
if( (x-imgWidth/2) > scrWidth || (y-imgHeight/2) > scrHeight )
return false;
if( (x+imgWidth/2) < 0 || (y+imgHeight/2) < 0 )
return false;

// Use a copy of the object data pointer
unsigned char *temp = data;

// Default values
int copyLenX = 4imgWidth,
copyLenY = imgHeight,
imgOffX = 0,
imgOffY = 0,
screenOffX = x - imgWidth/2,
screenOffY = y - imgHeight/2,
imgOffNextRow = imgWidth
4;

// If part of the image is outside on the left
if( x < (imgWidth/2) )
{
copyLenX = 4*(imgWidth/2 + x);
screenOffX = 0;
imgOffX = 4*(imgWidth/2 - x);
}
// If part of the image is outside on the right
else if( (x+imgWidth/2) > scrWidth )
copyLenX = 4*(scrWidth - x + imgWidth/2);

// If part of the image is outside the top
if( y < (imgHeight/2) )
{
copyLenY = imgHeight/2 + y;
screenOffY = 0;
imgOffY = imgHeight/2 - y;
}
// If part of the image is outside the bottom
else if( (y+imgHeight/2) > scrHeight )
copyLenY = scrHeight - y + imgHeight/2;

// Move pointers with the offsets we just determined
screen += screenOffYscrWidth + screenOffX;
temp += imgOffY
imgOffNextRow + imgOffX;

// Blit image line by line to screen
for( int line = 0; line < copyLenY; line++ )
{
Global::memcpy_mmx( screen, temp, copyLenX );
screen += scrWidth;
temp += imgOffNextRow;
}

return true;
}

Nevermind. I discovered that it was a problem with my memcpy_mmx(). Thanks
anyway!

/Rickard> ----- Original Message -----

From: arpen@home.se (Rickard Andersson)
To:
Sent: Sunday, November 11, 2001 3:40 PM
Subject: [SDL] Segfault when blitting near edges of screen

Repost: Whoops, I sent this message a few minutes ago but from the wrong
adress, so I’m reposting from the correct user.

I’m just getting started with SDL and I’ve written a small PCX loader and
I’m working on blitting the image to the screen and doing some clipping
code
for the edges of the screen. However, when I try to blit the image “almost
completely outside the screen” the application just quits and I get a
stderr.txt with the contents “Fatal signal: Segmentation Fault (SDL
Parachute Deployed)”.

Another wierd thing is that it only happens on the “sides” of the screen.
My
boundary checking code works for the top and bottom of the screen. Another
(!) wierd thing is that it doens’t happen when the image is completely
outside the screen but rather when there are something like 15 och 16
pixels
left to blit. It is very hard to describe so here is a link to the simple
app. Move the image with the arrow keys. Notice how it works in y but not
in
x and how it quits 15 or 16 pixels from the edge?

http://kennel.dyndns.org/~kennel/dload.pl?test.zip

Hope someone can help me.

Regards
Rickard Andersson, Sweden

I have included the blitting function in my PCXLoader class. The member
variables are imgHeight, imgWidth, scrHeight, scrWidth and data (the
pointer
to the image that is to be blitted to the surface).

Parameters:

screen = the pointer to the surface (called with (int*)screen->pixels)

x, y = the coordinates where the image is to be blitted (center of

image)

bool PCXLoader::blit( int *screen, short x, short y )
{
// If the x-, and y-coordinates would put the image outside the screen
completely
// REMARK: This obviously doesn’t do the job.
if( (x-imgWidth/2) > scrWidth || (y-imgHeight/2) > scrHeight )
return false;
if( (x+imgWidth/2) < 0 || (y+imgHeight/2) < 0 )
return false;

// Use a copy of the object data pointer
unsigned char *temp = data;

// Default values
int copyLenX = 4imgWidth,
copyLenY = imgHeight,
imgOffX = 0,
imgOffY = 0,
screenOffX = x - imgWidth/2,
screenOffY = y - imgHeight/2,
imgOffNextRow = imgWidth
4;

// If part of the image is outside on the left
if( x < (imgWidth/2) )
{
copyLenX = 4*(imgWidth/2 + x);
screenOffX = 0;
imgOffX = 4*(imgWidth/2 - x);
}
// If part of the image is outside on the right
else if( (x+imgWidth/2) > scrWidth )
copyLenX = 4*(scrWidth - x + imgWidth/2);

// If part of the image is outside the top
if( y < (imgHeight/2) )
{
copyLenY = imgHeight/2 + y;
screenOffY = 0;
imgOffY = imgHeight/2 - y;
}
// If part of the image is outside the bottom
else if( (y+imgHeight/2) > scrHeight )
copyLenY = scrHeight - y + imgHeight/2;

// Move pointers with the offsets we just determined
screen += screenOffYscrWidth + screenOffX;
temp += imgOffY
imgOffNextRow + imgOffX;

// Blit image line by line to screen
for( int line = 0; line < copyLenY; line++ )
{
Global::memcpy_mmx( screen, temp, copyLenX );
screen += scrWidth;
temp += imgOffNextRow;
}

return true;
}


SDL mailing list
SDL at libsdl.org
http://www.libsdl.org/mailman/listinfo/sdl