I need to improve the drawing performance in my BASIC emulator which uses
SDL for it’s output (on a Linux system).
Because I don’t know what the foreground and background colours will be
until I actually come to draw the character I’m not keeping a set of memory
mapped character images and just blitting them. Instead, (partly for
historical reasons) I have a set of 8 byte pixel masks for each of the 8x8
characters.
My (extraneous logic stripped out) code looks like this:
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER) < 0) {
fprintf(stderr, “Unable to init SDL: %s\n”, SDL_GetError());
return FALSE;
}
screen0 = SDL_SetVideoMode(SCREEN_WIDTH, SCREEN_HEIGHT, 32, 0);
if (!screen0) {
fprintf(stderr, “Failed to open screen: %s\n”, SDL_GetError());
return FALSE;
}
fontbuf = SDL_CreateRGBSurface(SDL_SWSURFACE, 8, 8, 32,
0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff);
sdl_fontbuf = SDL_ConvertSurface(fontbuf, screen0->format, 0);
/* copy surface to get same format as main windows */
SDL_FreeSurface(fontbuf);
The idea being that I will draw the character in fontbuf and then blit it
into screen0. The char drawing code looks like:
void sdlchar(char ch) {
int32 y, line;
place_rect.x = xtext * 8;
place_rect.y = ytext * 8;
SDL_FillRect(sdl_fontbuf, NULL, tb_colour);
for (y = 0; y < 8; y++) {
line = sysfont[ch-’ '][y];
if (line != 0) {
if (line & 0x80) ((Uint32)sdl_fontbuf->pixels + 0 +y8) = tf_colour;
if (line & 0x40) ((Uint32)sdl_fontbuf->pixels + 1 +y8) = tf_colour;
if (line & 0x20) ((Uint32)sdl_fontbuf->pixels + 2 +y8) = tf_colour;
if (line & 0x10) ((Uint32)sdl_fontbuf->pixels + 3 +y8) = tf_colour;
if (line & 0x08) ((Uint32)sdl_fontbuf->pixels + 4 +y8) = tf_colour;
if (line & 0x04) ((Uint32)sdl_fontbuf->pixels + 5 +y8) = tf_colour;
if (line & 0x02) ((Uint32)sdl_fontbuf->pixels + 6 +y8) = tf_colour;
if (line & 0x01) ((Uint32)sdl_fontbuf->pixels + 7 +y8) = tf_colour;
}
}
SDL_BlitSurface(sdl_fontbuf, &font_rect, screen0, &place_rect);
if (echo) SDL_Flip(screen0);
}
The “echo” flag is there so that I only do the buffer flip when I need to
actually see the output (so it’s clear when I’m outputting multiple chars
until the last one).
Comments and suggestions please.
Colin–
Colin Tuckley | @Colin_Tuckley | PGP/GnuPG Key Id
+44(0)1903 236872 | +44(0)7799 143369 | 0x1B3045CE
Banging your head against the wall uses 120 calories an hour.