Grabframe

Hi guys,
I studied from a book a good function that grabs the frame of sprite.
This function is write using the allegro libraries, so I translated it
in SDL:

SDL_Surface *grabframe(SDL_Surface *source, int width, int height, int
startx, int starty,
int columns, int frame)
{
SDL_Surface *temp = NULL;

int x = startx + (frame % columns) * width;
int y = starty + (frame / columns) * height;

src.w = width;
src.h = height;
src.x = x;
src.y = y;
dest = src;
SDL_BlitSurface(source,&src,temp,&dest);
return temp;
}

now I’ve a problem… when I use the function in this way

SDL_BlitSurface(grabframe(tiles, TILEW, TILEH, 0, 0, COLS, 1), NULL,
scr, NULL);

that doesn’t work…
Anybody can say me why?
tnx

You’re blitting to a NULL pointer rather than a destination surface. A
segfault/GP fault is to be expected. Also, that function shouldn’t
even compile, unless ‘src’ and ‘dest’ are global temporary variables

  • which would be a shooting offence! :slight_smile:

You should replace ‘NULL’ in the first line with a call to
SDL_CreateRGBSurface(), or otherwise create a surface of the right
size (one sprite frame) and pixel format. You should also replace the
line “dest = src;” with something like “dest.x = dest.y = 0;”, or
you’ll just blit all except the first frame outside the temp surface,
for no effect.

Furthermore, you should use this function only once per sprite frame
(at load time), and you should use SDL_DisplayFormat() or
SDL_DisplayFormatAlpha(). Otherwise, all you achieve is adding a lot
of overhead instead of avoiding the (potentially expensive) “source
surface clip”, which is one of very few reasons to do anything like
this at all.

If you aren’t optimizing for speed, are blitting opaque rectangles, or
have the luxury of controlling exactly what platform and hardware
your code will run on, you can just blit directly from the source
"palette" surface to the screen:

void blitframe(SDL_Surface *source, int fwidth, int fheight, int
frame, SDL_Surface *dest, int x, int y)
{
SDL_Rect sr;
SDL_Rect dr;
int columns = source->width / fwidth;
sr.x = (frame % columns) * fwidth;
sr.y = (frame / columns) * fheight;
sr.w = fwidth;
sr.h = fheight;
dr.x = x;
dr.y = y;
SDL_BlitSurface(source, &sr, dest, &dr);
}

(Not tested - beware of typos.)

//David Olofson - Programmer, Composer, Open Source Advocate

.- Audiality -----------------------------------------------.
| Free/Open Source audio engine for games and multimedia. |
| MIDI, modular synthesis, real time effects, scripting,… |
`-----------------------------------> http://audiality.org -’
http://olofson.nethttp://www.reologica.se —On Sunday 23 January 2005 01.25, NighTiger wrote:

Hi guys,
I studied from a book a good function that grabs the frame of
sprite. This function is write using the allegro libraries, so I
translated it in SDL:

SDL_Surface *grabframe(SDL_Surface *source, int width, int height,
int startx, int starty,
int columns, int frame)
{
SDL_Surface *temp = NULL;

int x = startx + (frame % columns) * width;
int y = starty + (frame / columns) * height;

src.w = width;
src.h = height;
src.x = x;
src.y = y;
dest = src;
SDL_BlitSurface(source,&src,temp,&dest);
return temp;
}

now I’ve a problem… when I use the function in this way

SDL_BlitSurface(grabframe(tiles, TILEW, TILEH, 0, 0, COLS, 1),
NULL, scr, NULL);

that doesn’t work…
Anybody can say me why?