Can't see the result of a blit on the screen

/* HERE IS THE HEADER OF MY PROGRAM */

#ifndef CUDDLY_H
#define CUDDLY_H
#include <stdio.h>
#include <stdlib.h>
#include <SDL/SDL.h>
#endif

int lsquare[8][8][3] = {

{{0x0,0x0,0x40},{0x0,0x0,0x40},
{0x0,0x0,0x40},{0x0,0x0,0x40},
{0x0,0x0,0x40},{0x0,0x0,0x40},
{0x0,0x0,0x40},{0x0,0x0,0x20}},

{{0x0,0x0,0x80},{0x0,0x0,0x80},
{0x0,0x0,0x80},{0x0,0x0,0x80},
{0x0,0x0,0x80},{0x0,0x0,0x80},
{0x0,0x0,0x40},{0x0,0x0,0x20}},

{{0x0,0x0,0x80},{0x0,0x0,0xC0},
{0x0,0x0,0xC0},{0x0,0x0,0xC0},
{0x0,0x0,0xC0},{0x0,0x0,0x80},
{0x0,0x0,0x40},{0x0,0x0,0x20}},

{{0x0,0x0,0x80},{0x0,0x0,0xC0},
{0x0,0x0,0xE0},{0x0,0x0,0xE0},
{0x0,0x0,0xC0},{0x0,0x0,0x80},
{0x0,0x0,0x40},{0x0,0x0,0x20}},

{{0x0,0x0,0x80},{0x0,0x0,0xC0},
{0x0,0x0,0xE0},{0x0,0x0,0xE0},
{0x0,0x0,0xC0},{0x0,0x0,0x80},
{0x0,0x0,0x40},{0x0,0x0,0x20}},

{{0x0,0x0,0x80},{0x0,0x0,0xC0},
{0x0,0x0,0xC0},{0x0,0x0,0xC0},
{0x0,0x0,0xC0},{0x0,0x0,0x80},
{0x0,0x0,0x40},{0x0,0x0,0x20}},

{{0x0,0x0,0x80},{0x0,0x0,0x80},
{0x0,0x0,0x80},{0x0,0x0,0x80},
{0x0,0x0,0x80},{0x0,0x0,0x80},
{0x0,0x0,0x40},{0x0,0x0,0x20}},

{{0x0,0x0,0x20},{0x0,0x0,0x20},
{0x0,0x0,0x20},{0x0,0x0,0x20},
{0x0,0x0,0x20},{0x0,0x0,0x20},
{0x0,0x0,0x20},{0x0,0x0,0x20}}
};

int fontshape[8][8][3] = {

{{0x0,0x0,0x0},{0x40,0x40,0x40},
{0x80,0x80,0x80},{0xC0,0xC0,0xC0},
{0xE0,0xE0,0xE0},{0xC0,0xC0,0xC0},
{0x80,0x80,0x80},{0x40,0x40,0x40}},

{{0x0,0x0,0x0},{0x40,0x40,0x40},
{0x80,0x80,0x80},{0xC0,0xC0,0xC0},
{0xE0,0xE0,0xE0},{0xC0,0xC0,0xC0},
{0x80,0x80,0x80},{0x40,0x40,0x40}},

{{0x0,0x0,0x0},{0x40,0x40,0x40},
{0x80,0x80,0x80},{0xC0,0xC0,0xC0},
{0xE0,0xE0,0xE0},{0xC0,0xC0,0xC0},
{0x80,0x80,0x80},{0x40,0x40,0x40}},

{{0x0,0x0,0x0},{0x40,0x40,0x40},
{0x80,0x80,0x80},{0xC0,0xC0,0xC0},
{0xE0,0xE0,0xE0},{0xC0,0xC0,0xC0},
{0x80,0x80,0x80},{0x40,0x40,0x40}},

{{0x0,0x0,0x0},{0x40,0x40,0x40},
{0x80,0x80,0x80},{0xC0,0xC0,0xC0},
{0xE0,0xE0,0xE0},{0xC0,0xC0,0xC0},
{0x80,0x80,0x80},{0x40,0x40,0x40}},

{{0x0,0x0,0x0},{0x40,0x40,0x40},
{0x80,0x80,0x80},{0xC0,0xC0,0xC0},
{0xE0,0xE0,0xE0},{0xC0,0xC0,0xC0},
{0x80,0x80,0x80},{0x40,0x40,0x40}},

{{0x0,0x0,0x0},{0x40,0x40,0x40},
{0x80,0x80,0x80},{0xC0,0xC0,0xC0},
{0xE0,0xE0,0xE0},{0xC0,0xC0,0xC0},
{0x80,0x80,0x80},{0x40,0x40,0x40}},

{{0x0,0x0,0x0},{0x40,0x40,0x40},
{0x80,0x80,0x80},{0xC0,0xC0,0xC0},
{0xE0,0xE0,0xE0},{0xC0,0xC0,0xC0},
{0x80,0x80,0x80},{0x40,0x40,0x40}}
};

SDL_Surface *background;
SDL_Surface *screen;

/**

  • This function allows the programmer to lock the screen surface if needed.
  • @param s, the SDL_Surface we want to lock.
  • @return nothing.
    */
    void ScreenLock(SDL_Surface *s)
    {
    if (SDL_MUSTLOCK(s))
    {
    if (SDL_LockSurface(s) < 0)
    {
    return;
    }
    }
    }

/**

  • This function does the opposite as the first function described before, that
  • is, if we need to lock the screen surface, this function will do that.
  • @param s, the SDL_Surface we want to unlock.
  • @return nothing.
    */
    void ScreenUnlock(SDL_Surface *s)
    {
    if (SDL_MUSTLOCK(s))
    {
    SDL_UnlockSurface(s);
    }
    }

/**

  • This function draws a Uint8 Color pixel on a given position.
  • @param s, the SDL_Surface we want to draw the pixel to.
  • @param x, the x position.
  • @param y, the y position.
  • @param R, the Red component value.
  • @param G, the Green component value.
  • @param B, the Blue component value.
  • @return nothing.
    */
    void DrawPixel(SDL_Surface s,
    int x,
    int y,
    Uint8 R,
    Uint8 G,
    Uint8 B)
    {
    Uint32 color = SDL_MapRGB(s->format, R, G, B);
    switch (s->format->BytesPerPixel)
    {
    case 1: /
    Assuming 8-bpp */
    {
    Uint8 *bufp;
    bufp = (Uint8 )s->pixels + ys->pitch + x;
    bufp = color;
    }
    break;
    case 2: /
    15-bpp or 16-bpp */
    {
    Uint16 *bufp;
    bufp = (Uint16 )s->pixels + ys->pitch/2 + x;
    bufp = color;
    }
    break;
    case 3: /
    Slow 24-bpp mode, usually not used */
    {
    Uint8 bufp;
    bufp = (Uint8 )s->pixels + ys->pitch/2 + x;
    if(SDL_BYTEORDER == SDL_LIL_ENDIAN)
    {
    bufp[0] = color;
    bufp[1] = color >> 8;
    bufp[2] = color >> 16;
    } else {
    bufp[2] = color;
    bufp[1] = color >> 8;
    bufp[0] = color >> 16;
    }
    }
    break;
    case 4: /
    Probably 32-bpp */
    {
    Uint32 *bufp;
    bufp = (Uint32 )s->pixels + ys->pitch/4 + x;
    *bufp = color;
    }
    break;
    }
    }

/**

  • This function draws an horizontal line from the blue tile sprite.
  • @param x, x position from where we want to draw the sprite line.
  • @param y, y position from where we want to draw the sprite line.
  • @param n, line number of the line we want to draw from the tile sprite.
  • @param s, the SDL_Surface we want to draw a Tile’s Line to.
  • @return nothing.
    */
    void DrawTileLine(int x, int y, int n, SDL_Surface *s)
    {
    for (int i = 0; i < 8; i++)
    {
    DrawPixel(s, x + i, y, lsquare[n][i][0], lsquare[n][i][1], lsquare[n][i][2]);
    }
    }

/**

  • This function draws the tile sprite starting from the upper left corner
    coordinates.
  • @param s, pointer to the SDL_Surface we want to draw to.
  • @param x, x coordinate of the upper left corner of the tile.
  • @param y, y coordinate of the upper left corner of the tile.
  • @return nothing.
    */
    void DrawSprite_X_Y(int x, int y, SDL_Surface *s)
    {
    for (int i = 0; i < 8; i++)
    {
    DrawTileLine(x, y + i, i, s);
    }
    }

/**

  • This function draws a screen full of these little blue tiles.
  • @return nothing.
    */
    void DrawPlentyOfTiles(SDL_Surface *s)
    {

/* We can draw 40 8-pixels lines on a 320-pixels screen line /
/
We can draw 25 8-pixels lines on a 200-pixels screen line */
ScreenLock(s);
for (int i = 0; i < 320; i+=8)
{
for (int j = 0; j < 200; j+=8)
{
DrawSprite_X_Y(i, j, s);
}
}
ScreenUnlock(s);
SDL_Flip(s);
}

/**

  • This function blits a full SDL_Surface onto another SDL_Surface.
  • @param source, the source we want to blit from.
  • @param destination the destination we want to blit to.
  • @param x, x coordinate of the upper left corner of source we want to blit from.
  • @param y, y coordinate of the upper left corner of source we want to blit from.
  • @return nothing.
    */
    void FullBlit(SDL_Surface *source, SDL_Surface *destination, int x, int y)
    {
    SDL_Rect destination_selector;
    destination_selector.x = x;
    destination_selector.y = y;
    SDL_BlitSurface(source, NULL, destination, &destination_selector);
    }

void DrawBackground()
{
background = SDL_CreateRGBSurface(SDL_HWSURFACE, screen->w,
screen->h,
screen->format->BitsPerPixel,
screen->format->Rmask,
screen->format->Gmask,
screen->format->Bmask,
screen->format->Amask);
DrawPlentyOfTiles(background);
}

void DrawScene()
{
ScreenLock(screen);
FullBlit(background, screen, 0, 0);
ScreenUnlock(screen);
SDL_Flip(screen);
SDL_UpdateRect(screen, 0, 0, 320, 200);
}

/* HERE IS THE REST OF THE SOURCE CODE, WRITTEN IN MAIN.C */
#include “cuddly.h”

int main(int argc, char *argv[])
{
if (SDL_Init(SDL_INIT_AUDIO | SDL_INIT_VIDEO) < 0)
{
printf(“Unable to init SDL: %s\n”, SDL_GetError());
exit(1);
}
atexit(SDL_Quit);

screen = SDL_SetVideoMode(320, 200, 8, SDL_HWSURFACE | SDL_DOUBLEBUF |
SDL_FULLSCREEN);
if ( screen == NULL )
{
printf(“Unable to set 320x200 video: %s\n”, SDL_GetError());
exit(1);
}
int done = 0;
DrawBackground();
while (done == 0)
{
SDL_Event event;
while ( SDL_PollEvent(&event))
{
if ( event.type == SDL_QUIT) {done = 1; }
if ( event.type == SDL_KEYDOWN )
{
if ( event.key.keysym.sym == SDLK_ESCAPE ) { done = 1; }
}
}
//DrawPlentyOfTiles(screen);
DrawScene();
}
return 0;
}

QUESTION : When I’m using DrawPlentyOfTiles(screen) (5 last lines of the code
above), I can see my tiles nicely on the screen. But when I change to
DrawScene(), I get a black flickering screen. Why ? What I want to do is to
create a SDL_Surface as a buffer containing all the tiles (wich is the
background), so I only have to blit it on the screen surface, and not draw draw
the frame pixel by pixel, 'cause I think it is too slow. Please answer me.

ESPOSITO Julien

Quoth djulzz <julien.esposito at gmail.com>, on 2005-05-23 04:32:12 +0000:

void DrawPlentyOfTiles(SDL_Surface *s)
{
[drawing code…]
SDL_Flip(s);
}

When applied to screen, this draws on screen, then flips it. That is
reasonable enough, but you should probably not put the flip in
DrawPlentyOfTiles if it is to operate on any surface; see below.

void DrawBackground()
{
background = SDL_CreateRGBSurface(SDL_HWSURFACE, screen->w,
screen->h,
screen->format->BitsPerPixel,
screen->format->Rmask,
screen->format->Gmask,
screen->format->Bmask,
screen->format->Amask);
DrawPlentyOfTiles(background);
}

When applied to background, this draws on background, then flips it.
However, flipping background makes no sense. Flip transfers the back
buffer of a double-buffered surface to the front buffer (possibly by
flipping them; the contents of the back buffer are subsequently
undefined). background is a software surface, and does not have a
back buffer. SDL_Flip is generally applied only to the screen after a
frame has been drawn, and only then when it is double-buffered and not
an OpenGL video mode.

void DrawScene()
{
ScreenLock(screen);
FullBlit(background, screen, 0, 0);
ScreenUnlock(screen);
SDL_Flip(screen);
SDL_UpdateRect(screen, 0, 0, 320, 200);
}

SDL_Flip updates the front buffer from the back buffer, possibly by
flipping them, and then SDL_UpdateRect updates the front buffer from
the back buffer, which is now possibly the previous front buffer. If
you are using double-buffering (as you seem to be), perform a flip;
otherwise, perform rectangle updating. Do not do both, as this will
cause problems.

—> Drake Wilson
-------------- next part --------------
A non-text attachment was scrubbed…
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: Digital signature
URL: http://lists.libsdl.org/pipermail/sdl-libsdl.org/attachments/20050523/5f55a0c9/attachment.pgp