Screen buffering problem: CreateRGBSurface/BlitSurface

Hello,

I am having trouble ‘backing up’ my screen area to another buffer and
then restoring it. Attached is test.c which attempts to copy the screen
into another SDL_Surface; modify the screen then restore the copy, which
would therefore remove traces of the second rectangle.

I think I am misunderstanding either how the SDL_BlitSurface call should
be used, or SDL_CreateRGBSurface. I have attempted to glean the mask
information from my screen object to minimize error.

Thanks for any advice you can offer - a few hours googling have not
helped :confused:

(Sorry if the puts output is lost when compiled in windows- not strictly
needed to understand what is going on).—

#include “SDL.h” // not sdl.h
#include <stdlib.h> // rand, abs
#include <time.h> // time

void random_rects(SDL_Surface * screen) {
SDL_Rect rect;
Uint32 colour;

rect.x = rand()%400;
rect.y = rand()%400;
rect.w = rand()%400;
rect.h = rand()%400;
colour =  SDL_MapRGB(screen->format, rand()%255, 
                                     rand()%255, 
                                     rand()%255);
SDL_FillRect(screen, &rect, colour);

}

int main(int argc, char **argv) {
SDL_Surface *screen;
SDL_Surface *bbuffer;
Uint32 del = 2000;

SDL_Init(SDL_INIT_VIDEO);
screen = SDL_SetVideoMode(640,480,8,0); 
bbuffer = SDL_CreateRGBSurface(0, 640, 480,
			    screen->format->BitsPerPixel, 
			    screen->format->Rmask,
			    screen->format->Gmask,
			    screen->format->Bmask,
			    screen->format->Amask);
srand(time(NULL));

// draw first rectangle
random_rects(screen);
SDL_Flip(screen);
puts("* Drawn first rectangle");
SDL_Delay(del);

// save up rectangle
if( SDL_BlitSurface(screen, NULL, bbuffer, NULL) == 0 ) 
    puts("  (blit successful)");
else puts("  (blit failed!)");
random_rects(screen);
SDL_Flip(screen);
puts("* backed up screen\n* drawn a new rectangle");
SDL_Delay(del);

// restore original buffer
if( SDL_BlitSurface(bbuffer, NULL, screen, NULL) == 0 ) 
    puts("  (blit successful)");
else puts("  (blit failed!)");
SDL_Flip(screen);
puts("* restored the original buffer");
SDL_Delay(del);

SDL_FreeSurface(bbuffer);
SDL_Quit();
return 0;

}


Jonathan Dowland

You create an 8 bits surface. SDL will create an empty palette, so you
should copy your screen palette to you backbuffer palette. You can add these
lines after the sruface creation :

bbuffer->format->palette->ncolors = screen->format->palette->ncolors;

memcpy(bbuffer->format->palette->colors,screen->format->palette->colors,scre
en->format->palette->ncolors);

I don’t know if SDL has a function to do that, so it may be incorrect to
procede like this but it works on my computer.

If you set the video mode to 16 bits your program works without other
changes

Bye

Julien> ----- Original Message -----

From: jon@jon.dowland.name (Jon Dowland)
To:
Sent: Thursday, February 27, 2003 10:10 PM
Subject: [SDL] screen buffering problem: CreateRGBSurface/BlitSurface

Hello,

I am having trouble ‘backing up’ my screen area to another buffer and
then restoring it. Attached is test.c which attempts to copy the screen
into another SDL_Surface; modify the screen then restore the copy, which
would therefore remove traces of the second rectangle.

I think I am misunderstanding either how the SDL_BlitSurface call should
be used, or SDL_CreateRGBSurface. I have attempted to glean the mask
information from my screen object to minimize error.

Thanks for any advice you can offer - a few hours googling have not
helped :confused:

(Sorry if the puts output is lost when compiled in windows- not strictly
needed to understand what is going on).


#include “SDL.h” // not sdl.h
#include <stdlib.h> // rand, abs
#include <time.h> // time

void random_rects(SDL_Surface * screen) {
SDL_Rect rect;
Uint32 colour;

rect.x = rand()%400;
rect.y = rand()%400;
rect.w = rand()%400;
rect.h = rand()%400;
colour =  SDL_MapRGB(screen->format, rand()%255,
                                     rand()%255,
                                     rand()%255);
SDL_FillRect(screen, &rect, colour);

}

int main(int argc, char **argv) {
SDL_Surface *screen;
SDL_Surface *bbuffer;
Uint32 del = 2000;

SDL_Init(SDL_INIT_VIDEO);
screen = SDL_SetVideoMode(640,480,8,0);
bbuffer = SDL_CreateRGBSurface(0, 640, 480,
screen->format->BitsPerPixel,
screen->format->Rmask,
screen->format->Gmask,
screen->format->Bmask,
screen->format->Amask);
srand(time(NULL));

// draw first rectangle
random_rects(screen);
SDL_Flip(screen);
puts("* Drawn first rectangle");
SDL_Delay(del);

// save up rectangle
if( SDL_BlitSurface(screen, NULL, bbuffer, NULL) == 0 )
    puts("  (blit successful)");
else puts("  (blit failed!)");
random_rects(screen);
SDL_Flip(screen);
puts("* backed up screen\n* drawn a new rectangle");
SDL_Delay(del);

// restore original buffer
if( SDL_BlitSurface(bbuffer, NULL, screen, NULL) == 0 )
    puts("  (blit successful)");
else puts("  (blit failed!)");
SDL_Flip(screen);
puts("* restored the original buffer");
SDL_Delay(del);

SDL_FreeSurface(bbuffer);
SDL_Quit();
return 0;

}


Jonathan Dowland


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

Sorry a miss cut and paste :

memcpy(bbuffer->format->palette->colors,screen->format->palette->colors,scre
en->format->palette->ncolors*sizeof(SDL_Color));

Julien> ----- Original Message -----

From: jon@jon.dowland.name (Jon Dowland)
To:
Sent: Thursday, February 27, 2003 10:10 PM
Subject: [SDL] screen buffering problem: CreateRGBSurface/BlitSurface

Hello,

I am having trouble ‘backing up’ my screen area to another buffer and
then restoring it. Attached is test.c which attempts to copy the screen
into another SDL_Surface; modify the screen then restore the copy, which
would therefore remove traces of the second rectangle.

I think I am misunderstanding either how the SDL_BlitSurface call should
be used, or SDL_CreateRGBSurface. I have attempted to glean the mask
information from my screen object to minimize error.

Thanks for any advice you can offer - a few hours googling have not
helped :confused:

(Sorry if the puts output is lost when compiled in windows- not strictly
needed to understand what is going on).


#include “SDL.h” // not sdl.h
#include <stdlib.h> // rand, abs
#include <time.h> // time

void random_rects(SDL_Surface * screen) {
SDL_Rect rect;
Uint32 colour;

rect.x = rand()%400;
rect.y = rand()%400;
rect.w = rand()%400;
rect.h = rand()%400;
colour =  SDL_MapRGB(screen->format, rand()%255,
                                     rand()%255,
                                     rand()%255);
SDL_FillRect(screen, &rect, colour);

}

int main(int argc, char **argv) {
SDL_Surface *screen;
SDL_Surface *bbuffer;
Uint32 del = 2000;

SDL_Init(SDL_INIT_VIDEO);
screen = SDL_SetVideoMode(640,480,8,0);
bbuffer = SDL_CreateRGBSurface(0, 640, 480,
screen->format->BitsPerPixel,
screen->format->Rmask,
screen->format->Gmask,
screen->format->Bmask,
screen->format->Amask);
srand(time(NULL));

// draw first rectangle
random_rects(screen);
SDL_Flip(screen);
puts("* Drawn first rectangle");
SDL_Delay(del);

// save up rectangle
if( SDL_BlitSurface(screen, NULL, bbuffer, NULL) == 0 )
    puts("  (blit successful)");
else puts("  (blit failed!)");
random_rects(screen);
SDL_Flip(screen);
puts("* backed up screen\n* drawn a new rectangle");
SDL_Delay(del);

// restore original buffer
if( SDL_BlitSurface(bbuffer, NULL, screen, NULL) == 0 )
    puts("  (blit successful)");
else puts("  (blit failed!)");
SDL_Flip(screen);
puts("* restored the original buffer");
SDL_Delay(del);

SDL_FreeSurface(bbuffer);
SDL_Quit();
return 0;

}


Jonathan Dowland


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