Blitting to a surface created with SDL_CreateRGBSurface()

Hi!
When i create a surface with SDL_CreateRGBSurface() the program crashes when
i try to blit to it with SDL_BlitSurface().
According to the docs the create… function allocates memory for the surface
but does this include allocating memory for pixeldata? I tried to allocate
that myself but no result. Anybody has any idea about what might be wrong?

Thanx
–Anders Folkesson

When i create a surface with SDL_CreateRGBSurface() the program crashes when
i try to blit to it with SDL_BlitSurface().

Hm. “It Works For Me” :wink:

There’s probably a bug in your code; so post that and we’ll tell you where
it is :wink: For reference, this is the relevant part of my test code for
this; hopefully it does something along the lines of what you’re wanting to
do. It’s a modifed version of my earlier ‘sprite.c’. The only change I made
was that it will make a new surface with four copies of the Mouse Cursor
Blob Icon Thing™; the relevant code snippet is:

icon and in_icon are both pointers to an SDL_Surface; in_icon is an already
loaded surface passed to the function; icon is the icon we create, and
screen is the video surface (passed to the function, but you can get it with
SDL_GetVideoSurface())

posnow is a pointer to an SDL_Rect, obviously :slight_smile:

icon = SDL_CreateRGBSurface (screen->flags,
in_icon->w * 2,
in_icon->h * 2,
screen->format->BitsPerPixel,
screen->format->Rmask,
screen->format->Gmask,
screen->format->Bmask,
screen->format->Amask);
if (icon == NULL)
{
fprintf (stderr, “SDL_CreateRGBSurface(): %s.\n”,
SDL_GetError());
icon = in_icon;
}
else
{
// top left
posnow->x = posnow->y = 0;
posnow->w = in_icon->w;
posnow->h = in_icon->h;
SDL_BlitSurface (in_icon, NULL, icon, posnow);
// top right
posnow->x += posnow->w;
SDL_BlitSurface (in_icon, NULL, icon, posnow);
// bottom right
posnow->y += posnow->h;
SDL_BlitSurface (in_icon, NULL, icon, posnow);
// bottom left
posnow->x = 0;
SDL_BlitSurface (in_icon, NULL, icon, posnow);
}

// and when you’re done

if (icon != in_icon)
SDL_FreeSurface (icon);On Tue, 15 Jan 2002, Anders Folkesson wrote:

Mike.

Mike wrote:> On Tue, 15 Jan 2002, Anders Folkesson wrote:

When i create a surface with SDL_CreateRGBSurface() the program crashes when
i try to blit to it with SDL_BlitSurface().

Simple info : CreateRGBSurface() convert an image with his palette
to a new image with a “universal palette” (All CreatedRGBSurface got
the same palette) or I’m wrong ?? (I’m never utilize it yet, but if it’s
that I’ll surely utilize it!)

Thx!

Simple info : CreateRGBSurface() convert an image with his palette
to a new image with a “universal palette” (All CreatedRGBSurface got
the same palette) or I’m wrong ?? (I’m never utilize it yet, but if it’s
that I’ll surely utilize it!)

Umm… I don’t think so. I’m not 100% sure, but I’m at least 90% sure that
CreateRGBSurface() doesn’t create a palette for you. (This is from running
v2.0 of sprite.c with an 8bpp video surface - I just got a black box)

In my quick testing, I’ve found that after calling SDL_CreateRGBSurface(),
you have to set the palette yourself before blitting to it if you want to
actually get an image onto it.

Strangely enough, using SDL_DisplayFormat() on a >8bit image to convert it
into an 8 bit image for display seems to work fine, even before I set the
video surface’s palette. How exactly does DisplayFormat() convert RGB
surfaces to palettized surfaces?

Oh I see now (don’t you love writing emails while playing around? :P) - the
video surface gets a default palette when it’s created. That explains
everything :slight_smile:

So finally, I can actually answer this question! whew

No, SDL_CreateRGBSurface() does not automatically use a “global” palette; it
looks like it just gets filled in with zeroes, so unless you want to paint
in pure black, you’ll have to set it yourself.

If you want to use a global palette, you can do something like:

void set_palette (SDL_Surface *surface, SDL_Surface *screen)
{
if (screen == NULL)
screen = SDL_GetVideoSurface();

SDL_SetPalette (surface, SDL_LOGPAL | SDL_PHYSPAL,
		screen->format->palette->colors,
		0, screen->format->palette->ncolors);

} // end set_palette()

If you call that right after you create the surface (before attempting to
blit to/draw on it) then you will essentially have what you wanted. You’d
also better make sure you only call it if you really have a palettized
surface and display, otherwise it’ll probably crash (I think the palette is
NULL for RGB surfaces…?)

Hope this helps… :-)On Tue, 15 Jan 2002, Gerard wrote:

Mike.

There’s probably a bug in your code; so post that and we’ll tell you where
it is :wink:

Hay, no need to be insulting :wink: btw, my code is ALWAYS bugfree…even from
scratch :wink: hmm…

what i am trying to do is to copy most of the screen to a temporary surface
and blit it back on the screen, just moved a bit according to the scrollinfo
(doing a map module for my CRPG)
here is the relevant part of the code:

//set the correct positions
srcrect->x = 0;
srcrect->y = 32;
srcrect->w = 2232;
srcrect->h = 17
32;
dstrect->x = 0;
dstrect->y = 0;

//create temp screen buffer

oldscreen = SDL_CreateRGBSurface(screenptr->flgs, screenptr->w,
screenptr->h,screenptr->format->BytesPerPixel, screenptr->format->Rmask,
screenptr->format->Gmask, screenptr->format->Bmask,
screenptr->format->Amask)))

//copy screen to buffer
SDL_BlitSurface(screenptr,srcrect,oldscreen,dstrect);

///HERE IS WHERE THE PROGRAM CRASCHES!!

//move and copy buffer to screen
SDL_BlitSurface(oldscreen,NULL,screenptr,dstrect);

Shit…i forgot to say thanx and all that :wink:

have a nice day

–Anders Folkesson