Video | Events | OpenGL | Audio | CD-ROM | Threads | Time
# Video Examples
Introduction | Function List | Function Reference | Examples
Initializing the video display Initializing the best video mode Loading and displaying a BMP file Fading a palette Drawing directly to the display Fastest possible surface blit code Initializing the video display
            SDL_Surface *screen;

            /* Initialize the SDL library */
            if ( SDL_Init(SDL_INIT_VIDEO) < 0 ) {
                    fprintf(stderr,
                            "Couldn't initialize SDL: %s\n", SDL_GetError());
                    exit(1);
            }

            /* Clean up on exit */
            atexit(SDL_Quit);

            /* Initialize the display in a 640x480 8-bit palettized mode */
            screen = SDL_SetVideoMode(640, 480, 8, SDL_SWSURFACE);
            if ( screen == NULL ) {
                    fprintf(stderr, "Couldn't set 640x480x8 video mode: %s\n",
                                                            SDL_GetError());
                    exit(1);
            }
Initializing the best 640x480 video mode
            /* Have a preference for 8-bit, but accept any depth */
            screen = SDL_SetVideoMode(640, 480, 8, SDL_SWSURFACE|SDL_ANYFORMAT);
            if ( screen == NULL ) {
                    fprintf(stderr, "Couldn't set 640x480x8 video mode: %s\n",
                                                            SDL_GetError());
                    exit(1);
            }
            printf("Set 640x480 at %d bits-per-pixel mode\n",
                                            screen->format->BitsPerPixel);
Loading and displaying a BMP file
            SDL_Surface *image;
            SDL_Rect dest;
            int ncolors, i;
            SDL_Color *colors;

            /* Load the BMP file into a surface */
            image = SDL_LoadBMP("sample.bmp");
            if ( image == NULL ) {
                    fprintf(stderr, "Couldn't load sample.bmp: %s\n",
                                                            SDL_GetError());
                    return;
            }

            /* Set the display colors -- SDL_SetColors() only does something on
               palettized displays, but it doesn't hurt anything on HiColor or
               TrueColor displays.
               If the display colors have already been set, this step can be
               skipped, and the library will automatically map the image to
               the current display colors.
            */
            if ( image->format->palette ) {
                    ncolors = image->format->palette->ncolors;
                    colors  = (SDL_Color *)malloc(ncolors*sizeof(SDL_Color));
                    memcpy(colors, image->format->palette->colors, ncolors);
            } else {
                    int       r, g, b;

                    /* Allocate 256 color palette */
                    ncolors = 256;
                    colors  = (SDL_Color *)malloc(ncolors*sizeof(SDL_Color));

                    /* Set a 3,3,2 color cube */
                    for ( r=0; r<8; ++r ) {
                            for ( g=0; g<8; ++g ) {
                                    for ( b=0; b<4; ++b ) {
                                            i = ((r<<5)|(g<<2)|b);
                                            colors[i].r = r<<5;
                                            colors[i].g = g<<5;
                                            colors[i].b = b<<6;
                                    }
                            }
                    }
                    /* Note: A better way of allocating the palette might be
                             to calculate the frequency of colors in the image
                             and create a palette based on that information.
                    */
            }
            /* Set colormap, try for all the colors, but don't worry about it */
            SDL_SetColors(screen, colors, 0, ncolors);
            free(colors);

            /* Blit onto the screen surface
            */
            dest.x = 0;
            dest.y = 0;
            dest.w = image->w;
            dest.h = image->h;
            SDL_BlitSurface(image, NULL, screen, &dest);

            SDL_UpdateRects(screen, 1, &dest);

            /* Free the allocated BMP surface */
            SDL_FreeSurface(image);
            return;
Fading a palette
    /* Note:  This fading process is really slow when the display cannot
              allocate all of the requested colors, i.e. warp_colors isn't
              set in SDL_SetColors()
    */
            SDL_Palette *palette;
            SDL_Color *orig_colors;
            SDL_Color *fade_colors;
            int ncolors, i;

            /* Get the current colormap */
            palette = screen->format->palette;
            if ( palette == NULL ) {        /* The display is not palettized */
                    return;
            }
            ncolors = palette->ncolors;
            orig_colors = (SDL_Color *)malloc(ncolors*sizeof(SDL_Color));
            fade_colors = (SDL_Color *)malloc(ncolors*sizeof(SDL_Color));
            memcpy(orig_colors, palette->colors, ncolors*sizeof(SDL_Color));

            /* Copy the original colors to the faded colors */
            memcpy(fade_colors, orig_colors, ncolors*sizeof(SDL_Color));

            /* Fade the colormap to black and back
               Note: A more sophisticated fading routine would detect the speed
                     of the palette change and base the number of fading steps
                     on that to provide a consistent fade time on all displays.
            */
            for ( i=32-1; i>=0; --i ) {     /* 32 step fade out */
                    int c;
                    for ( c=0; c<ncolors; ++c ) {
                            fade_colors[c].r = ((int)orig_colors[c].r*i)/32;
                            fade_colors[c].g = ((int)orig_colors[c].g*i)/32;
                            fade_colors[c].b = ((int)orig_colors[c].b*i)/32;
                    }
                    SDL_SetColors(screen, fade_colors, 0, ncolors);
            }
            for ( i=0; i<32; ++i ) {        /* 32 step fade in */
                    int c;
                    for ( c=0; c<ncolors; ++c ) {
                            fade_colors[c].r = ((int)orig_colors[c].r*i)/32;
                            fade_colors[c].g = ((int)orig_colors[c].g*i)/32;
                            fade_colors[c].b = ((int)orig_colors[c].b*i)/32;
                    }
                    SDL_SetColors(screen, fade_colors, 0, ncolors);
            }
            free(orig_colors);
            free(fade_colors);
            return;
Drawing directly to the display
            /* Code to set a yellow pixel at the center of the screen */

            Sint32   X, Y;
            Uint32   pixel;
            Uint8   *bits, bpp;

            /* Map the color yellow to this display (R=0xFF, G=0xFF, B=0x00)
               Note:  If the display is palettized, you must set the palette first.
            */
            pixel = SDL_MapRGB(screen->format, 0xFF, 0xFF, 0x00);

            /* Calculate the framebuffer offset of the center of the screen */
            if ( SDL_MUSTLOCK(screen) ) {
                    if ( SDL_LockSurface(screen) < 0 )
                            return;
            }
            bpp = screen->format->BytesPerPixel;
            X = screen->w/2;
            Y = screen->h/2;
            bits = ((Uint8 *)screen->pixels)+Y*screen->pitch+X*bpp;

            /* Set the pixel */
            switch(bpp) {
                    case 1:
                            *((Uint8 *)(bits)) = (Uint8)pixel;
                            break;
                    case 2:
                            *((Uint16 *)(bits)) = (Uint16)pixel;
                            break;
                    case 3: { /* Format/endian independent */
                            Uint8 r, g, b;

                            r = (pixel>>screen->format->Rshift)&0xFF;
                            g = (pixel>>screen->format->Gshift)&0xFF;
                            b = (pixel>>screen->format->Bshift)&0xFF;
                            *((bits)+screen->format->Rshift/8) = r;
                            *((bits)+screen->format->Gshift/8) = g;
                            *((bits)+screen->format->Bshift/8) = b;
                            }
                            break;
                    case 4:
                            *((Uint32 *)(bits)) = (Uint32)pixel;
                            break;
            }

            /* Update the display */
            if ( SDL_MUSTLOCK(screen) ) {
                    SDL_UnlockSurface(screen);
            }
            SDL_UpdateRect(screen, X, Y, 1, 1);

            return;
Fastest possible surface blit code There are three different ways you can draw an image to the screen: Create a surface and use SDL_BlitSurface() to blit it to the screen Create the video surface in system memory and call SDL_UpdateRect() Create the video surface in video memory and call SDL_LockSurface() The best way to do this is to combine methods:
    #include <stdio.h>
    #include <stdlib.h>
    #include "SDL.h"
    #include "SDL_timer.h"

    void ComplainAndExit(void)
    {
            fprintf(stderr, "Problem: %s\n", SDL_GetError());
            exit(1);
    }

    int main(int argc, char *argv[])
    {
            SDL_PixelFormat fmt;
            SDL_Surface *screen, *locked;
            SDL_Surface *imagebmp, *image;
            SDL_Rect dstrect;
            int i;
            Uint8 *buffer;

            /* Initialize SDL */
            if ( SDL_Init(SDL_INIT_VIDEO) < 0 ) {
                    ComplainAndExit();
            }
            atexit(SDL_Quit);

            /* Load a BMP image into a surface */
            imagebmp = SDL_LoadBMP("image.bmp");
            if ( imagebmp == NULL ) {
                    ComplainAndExit();
            }

            /* Set the video mode (640x480 at native depth) */
            screen = SDL_SetVideoMode(640, 480, 0, SDL_HWSURFACE|SDL_FULLSCREEN);
            if ( screen == NULL ) {
                    ComplainAndExit();
            }

            /* Set the video colormap */
            if ( imagebmp->format->palette != NULL ) {
                    SDL_SetColors(screen,
                                    imagebmp->format->palette->colors, 0,
                                    imagebmp->format->palette->ncolors);
            }

            /* Convert the image to the video format (maps colors) */
            image = SDL_DisplayFormat(imagebmp);
            SDL_FreeSurface(imagebmp);
            if ( image == NULL ) {
                    ComplainAndExit();
            }

            /* Draw bands of color on the raw surface */
            if ( SDL_MUSTLOCK(screen) ) {
                    if ( SDL_LockSurface(screen) < 0 )
                            ComplainAndExit();
            }
            buffer=(Uint8 *)screen->pixels;
            for ( i=0; i<screen->h; ++i ) {
                    memset(buffer,(i*255)/screen->h,
                            screen->w*screen->format->BytesPerPixel);
                    buffer += screen->pitch;
            }
            if ( SDL_MUSTLOCK(screen) ) {
                    SDL_UnlockSurface(screen);
            }

            /* Blit the image to the center of the screen */
            dstrect.x = (screen->w-image->w)/2;
            dstrect.y = (screen->h-image->h)/2;
            dstrect.w = image->w;
            dstrect.h = image->h;
            if ( SDL_BlitSurface(image, NULL, screen, &dstrect) < 0 ) {
                    SDL_FreeSurface(image);
                    ComplainAndExit();
            }
            SDL_FreeSurface(image);

            /* Update the screen */
            SDL_UpdateRects(screen, 1, &dstrect);

            SDL_Delay(5000);        /* Wait 5 seconds */
            exit(0);
    }