Demonstration

We combined several sections of sample code to produce program PutPixelDemo. We have added PPS comments where changes were necessary. The program places a pixel in the middle of our graphic. To compile this program, you need to download and unzip the zip file containing two images and put voxel.bmp in your program folder. (You may have already downloaded it to compile our two earlier SDL demonstration programs).

(When we copied and pasted code from the compiled help file into the Lazarus or Delphi editors, we lost the formatting and all the code appeared on a single line. We overcame this problem by copying first into a word processor such as OpenOffice.org Writer and then copying the formatted code from there into an editor).

program PutPixelDemo;
  {$mode Delphi} {PPS: Delete this in Delphi
                 Delphi 'forgives' omissions of dereferencing caret}
  {$Apptype Console} 
uses
  Classes, SysUtils, Windows, SDL;  //PPS: Windows needed for MessageBox
var
    x, y : integer;
    yellow : Uint32;
    Screen_ : PSDL_Surface;
    Filename : PChar = 'voxel.bmp';

 // Code to set a yellow pixel at the center of the screen
 (*
 * Set the pixel at (x, y) to the given value
 * NOTE: The surface must be locked before calling this!
 *)
procedure putpixel( surface_ : PSDL_Surface; x : integer; y : integer; pixel : Uint32 );
type
  TByteArray = array[0..2] of Byte;
  PByteArray = ^TByteArray;
var
  bpp : integer;
  p : PInteger;
begin
  bpp := surface_.format.BytesPerPixel; //PPS: Underscore appended to surface
  // Here p is the address to the pixel we want to set
  p := Pointer(Uint32(surface_.pixels) + y * surface_.pitch + x * bpp);
  case bpp of
    1: LongWord(p^) := pixel;
    2: PUint16(p)^ := pixel;
    3: if (SDL_BYTEORDER = SDL_BIG_ENDIAN) then
         begin
           PByteArray(p)[0] := (pixel shr 16) and $FF;
           PByteArray(p)[1] := (pixel shr 8) and $FF;
           PByteArray(p)[2] := pixel and $FF;
         end
       else
         begin
           PByteArray(p)[0] := pixel and $FF;
           PByteArray(p)[1] := (pixel shr 8) and $FF;
           PByteArray(p)[2] := (pixel shr 16) and $FF;
         end;
      4: PUint32(p)^ := pixel;
    end;
end;

procedure display_bmp( file_name : PChar );
var
  image : PSDL_Surface;
begin
  // Load the BMP file into a surface
  image := SDL_LoadBMP(file_name);
  if ( image = nil ) then
    begin
      MessageBox(0, PChar(Format('Couldn''t load %s : %s',
          [file_name, SDL_GetError])), 'Error', MB_OK or MB_ICONHAND);
  exit;
end;

  (*
  * Palettized screen modes will have a default palette (a standard
  * 8*8*4 colour cube), but if the image is palettized as well we can
  * use that palette for a nicer colour matching
  *)
  {if (image.format.palette and screen_.format.palette) then
  begin
  SDL_SetColors(screen_, @image.format.palette.colors[0], 0, image.format.palette.ncolors);
  end; } //PPS: Commented out because did not compile and we do not use a palette.

  // Blit onto the screen surface
  if (SDL_BlitSurface(image, nil, screen_, nil) < 0) then
    MessageBox(0, PChar(Format('BlitSurface error : %s', [SDL_GetError])), 'Error', MB_OK or MB_ICONHAND);
  SDL_UpdateRect(screen_, 0, 0, image.w, image.h);

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

begin
  // 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);
      // Clean up on exit
      SDL_Quit;
      exit;
    end;

(*
* Initialize the display in a 640x480 8-bit palettized mode,
* requesting a software surface
*)
{PPS: Changed to 789 x 532 24 bit mode to match our graphic}
  screen_ := SDL_SetVideoMode(789, 532, 24, SDL_SWSURFACE);
  if ( screen_ = nil ) then
    begin
      MessageBox(0, PChar(Format('Couldn''t set 789 x 532 x 24 video mode : %s',
          [SDL_GetError])), 'Error', MB_OK or MB_ICONHAND);
    SDL_Quit;
    exit;
end;
  Display_BMP(Filename);
  (* Map the color yellow to this display (R := $ff, G := $FF, B := $00)
  Note:  If the display is palettized, you must set the palette first.
  *)
  yellow := SDL_MapRGB(screen_.format, $ff, $ff, $00);
  x := screen_.w div 2;
  y := screen_.h div 2;
  // Lock the screen for direct access to the pixels
  if ( SDL_MustLock(screen_) ) then
    begin
      if ( SDL_LockSurface(screen_) < 0 ) then
        begin
          MessageBox(0, PChar(Format('Can''t lock screen : %s',
                  [SDL_GetError])), 'Error', MB_OK or MB_ICONHAND);
          exit;
        end;
    end;
  putpixel(screen_, x, y, yellow);

  if ( SDL_MustLock(screen_) ) then //PPS: Deleted >0
    begin
      SDL_UnlockSurface(screen_);
    end;
  // Update just the part of the display that we've changed
  SDL_UpdateRect(screen_, x, y, 1, 1);
  //PPS: Deleted end;
  readln;
  SDL_Quit;
end.  


Programming - a skill for life!

Discussion of help in the header file download