Video Examples

Initializing the video display

    screen_ : PSDL_Surface;

// Initialize the SDL library
if ( SDL_Init( SDL_INIT_VIDEO ) < 0 ) then
begin
MessageBox( 0, PChar(Format('Couldn''t initialize SDL : %s', [SDL_GetError] ) ), 'Error', MB_OK or MB_ICONHAND );
SDL_Quit;
halt(1);
end;

// Initialize the display in a 640x480 8-bit palettized mode
screen_ := SDL_SetVideoMode( 640, 480, 8, SDL_SWSURFACE );
if ( screen_ = nil ) then
begin
MessageBox( 0, PChar( Format( 'Couldn''t set 640x480x8 video mode : %s', [SDL_GetError] ) ), 'Error', MB_OK or MB_ICONHAND );
SDL_Quit;
halt(1);
end;

Initializing the best video mode

    // Have a preference for 8-bit, but accept any depth
screen_ := SDL_SetVideoMode( 640, 480, 8, SDL_SWSURFACE or SDL_ANYFORMAT );
if ( screen_ = nil ) then
begin
MessageBox( 0, PChar( Format( 'Couldn''t set 640x480x8 video mode : %s', [SDL_GetError] ) ), 'Error', MB_OK or MB_ICONHAND );
SDL_Quit;
halt(1);
end;
MessageBox( 0, PChar( Format( 'Set 640x480 at %d bits-per-pixel mode.', [screen_.format.BitsPerPixel] ) ), 'Error', MB_OK or MB_ICONHAND );

Loading and displaying a BMP file

  procedure LoadBmp( FileName : string );
var
image : PSDL_Surface;
dest : TSDL_Rect;
ncolors, i : integer;
colors : PSDL_Color;
r, g, b : integer;
begin
// Load the BMP file into a surface
image := SDL_LoadBMP( PChar( FileName ) );
if ( image = nil ) then
begin
MessageBox( 0, PChar( Format( 'Couldn''t load Bitmap : %s', [FileName] ) ), 'Error', MB_OK or MB_ICONHAND );
exit;
end;

{ 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 > 0 ) then
begin
ncolors := image.format.palette.ncolors;
colors := (SDL_Color *)malloc(ncolors*sizeof(SDL_Color));
Move(image.format.palette.colors, colors, ncolors);
end
else
begin
// Allocate 256 color palette
ncolors := 256;
SetLength( colors, ncolors*sizeof(SDL_Color) );

// Set a 3,3,2 color cube
for r := 0 to 7 do
begin
for g := 0 to 7 do
begin
for b := 0 to 3 do
begin
i := ( ( r shl 5) or ( g shl 2) or b );
colors[i].r := r shl 5;
colors[i].g := g shl 5;
colors[i].b := b shl 6;
end;
end;
end;
(* 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.
*)
end;
// 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, nil, screen_, @dest );

SDL_UpdateRects( screen_, 1, @dest );

// Free the allocated BMP surface
SDL_FreeSurface( image );
end;

Drawing directly to the display

  var
// Code to set a yellow pixel at the center of the screen
X, Y : Sint32;
pixel : Uint32;
bits : PUint8;
bpp, r, g, b : Uint8;
.
.
.
(* 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, $FF, $FF, $00 );

// Calculate the framebuffer offset of the center of the screen
if ( SDL_MUSTLOCK( screen_ ) > 0 ) then
begin
if ( SDL_LockSurface( screen_ ) < 0 ) then
exit;
end;
bpp := screen_.format.BytesPerPixel;
X := screen_.w div 2;
Y := screen_.h div 2;
bits := ( PUint8( screen_.pixels ) ) + Y * screen_.pitch + X * bpp;

// Set the pixel
case bpp of
1:
begin
PUint8( bits )^ := Uint8( pixel );
end;

2:
begin
PUint16(bits)^ := Uint16( pixel );
end;

3:
begin // Format/endian independent

r := ( pixel shr screen_.format.Rshift ) and $FF;
g := ( pixel shr screen_.format.Gshift ) and $FF;
b := ( pixel shr screen_.format.Bshift ) and $FF;
bits^ + (screen_.format.Rshift div 8) := r;
bits^ + (screen_.format.Gshift div 8) := g;
bits^ + (screen_.format.Bshift div 8) := b;
end;

4:
begin
PUInt32(bits)^ := Uint32( pixel );
end;
end;

// Update the display
if ( SDL_MUSTLOCK( screen_ ) > 0 ) then
begin
SDL_UnlockSurface( screen_ );
end;
SDL_UpdateRect( screen_, X, Y, 1, 1 );

Fastest possible surface blit

There are three different ways you can draw an image to the screen:

1.Create a surface and use SDL_BlitSurface to blit it to the screen
2.Create the video surface in system memory and call SDL_UpdateRect
3.Create the video surface in video memory and call SDL_LockSurface

The best way to do this is to combine methods:
uses 
SDL;

procedure ComplainAndExit;
begin
MessageBox(0, PChar(Format('Problem : %s', [SDL_GetError])), 'Error', MB_OK or MB_ICONHAND);
SQL_Quit;
halt( 1 );
end;

var
fmtg : TSDL_PixelFormat;
screen_, locked : PSDL_Surface;
imagebmp, image : PSDL_Surface;
dstrect : TSDL_Rect;
i : integer;
buffer : PUint8;
begin
// Initialize SDL
if ( SDL_Init( SDL_INIT_VIDEO ) < 0 ) then
begin
ComplainAndExit;
end;

// Load a BMP image into a surface
imagebmp := SDL_LoadBMP( 'image.bmp' );
if ( imagebmp = nil ) then
begin
ComplainAndExit;
end;

// Set the video mode (640x480 at native depth)
screen_ := SDL_SetVideoMode( 640, 480, 0, SDL_HWSURFACE or SDL_FULLSCREEN );
if ( screen_ = nil ) then
begin
ComplainAndExit;
end;

// Set the video colormap
if ( imagebmp.format.palette <> nil ) then
begin
SDL_SetColors( screen_, @imagebmp.format.palette.colors, 0, imagebmp.format.palette.ncolors );
end;

// Convert the image to the video format (maps colors)
image := SDL_DisplayFormat( imagebmp );
SDL_FreeSurface( imagebmp );
if ( image = nil ) then
begin
ComplainAndExit;
end;

// Draw bands of color on the raw surface
if ( SDL_MUSTLOCK( screen_ ) > 0 ) then
begin
if ( SDL_LockSurface( screen_ ) < 0 ) then
ComplainAndExit;
end;

buffer := PUnit8( screen_.pixels );
for i := 0 to screen_.h - 1 do
begin
memset(buffer, ( i * 255 ) / screen_.h, screen_.w * screen_.format.BytesPerPixel );
buffer := buffer + screen_.pitch;
end;

if ( SDL_MUSTLOCK( screen_ ) > 0 ) then
begin
SDL_UnlockSurface( screen_ );
end;

// Blit the image to the center of the screen
dstrect.x := ( screen_.w-image.w ) div 2;
dstrect.y := ( screen_.h-image.h ) div 2;
dstrect.w := image.w;
dstrect.h := image.h;

if ( SDL_BlitSurface( image, nil, screen_, @dstrect ) < 0 ) then
begin
SDL_FreeSurface( image );
ComplainAndExit;
end;

SDL_FreeSurface( image );

// Update the screen
SDL_UpdateRects( screen_, 1, @dstrect );

SDL_Delay( 5000 ); // Wait 5 seconds
end;