/* 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