Monday, 24 September 2012

In the last post we talked about how to install SDL in this post we will create a simple program to create initialise SDL and create a simple window.

All the code for this post can be found here and downloaded via version control using bzr

SDL.h

The first thing we need to do when using SDL is to include the SDL.h header file. This is done using the following line

#include <SDL/SDL.h>

Note that the directory prefix SDL/ is part of this path, as we shall see later the sdl-config script will give us the correct include paths when we compile the program relative to this directory.

SDL_main

Depending upon the operating system, SDL uses different native code to generate the window / interactions with the operating system. Under linux this is done be default, however under Mac OSX and Windows we need to include a different version of main. To allow this and make the code portable we can use the C/C++ conditional compilation pre-processor. To do this we use the following code

/// note that under mac osx (and windows) there is a different
/// way to build SDL so we need to use SDL_main under linux
/// normal main is fine so we use this conditional compilation
/// to incude the correct version (DARWIN being mac os x)
#if defined (DARWIN) || defined (WIN32)
int SDL_main(int argc, char **argv)
#else
int main(int argc, char **argv)
#endif

SDL_Init

The first thing we need to do when using SDL is to initialise the library, to do this we use the SDL_Init function, this is passed one parameter which is a flag to indicate which sub-systems should be initialised. These values are combined together using a logical or ( | ). The subsystems available are as follows

For example if we wish to initialise both the video and joystick sub sytems we would use the following code

SDL_Init( SDL_INIT_VIDEO | SDL_INIT_JOYSTICK);

In the following examples we will use just the video subsystem but we will also check to see if the initialisation actually worked by checking the return value from SDL_init and making sure it's a zero

Setting Video mode

To give us a video surface we use the SDL_SetVideoMode function, it has 4 parameters width and height, bits per pixel (bpp) and flags.

If the bpp value is set to 0 it will attempt to use the system value for the current display, the flags parameter can be a logical or combination of the values below, however some of these flags will cancel each other out.

SDL_SWSURFACE

Surface is stored in system memory

SDL_HWSURFACE

Surface is stored in video memory

SDL_ASYNCBLIT

Surface uses asynchronous blits if possible

SDL_ANYFORMAT

Allows any pixel-format (Display surface)

SDL_HWPALETTE

Surface has exclusive palette

SDL_DOUBLEBUF

Surface is double buffered (Display surface)

SDL_FULLSCREEN

Surface is full screen (Display Surface)

SDL_OPENGL

Surface has an OpenGL context (Display Surface)

SDL_OPENGLBLIT

Surface supports OpenGL blitting (Display Surface)

SDL_RESIZABLE

Surface is resizable (Display Surface)

SDL_HWACCEL

Surface blit uses hardware acceleration

SDL_SRCCOLORKEY

Surface use colorkey blitting

SDL_RLEACCEL

Colorkey blitting is accelerated with RLE

SDL_SRCALPHA

Surface blit uses alpha blending

SDL_PREALLOC

Surface uses preallocated memory

This function will return an SDL_Surface structure if successful which will be referred to in other drawing functions. If this fails NULL will be returned to we can check if there was an error.

In this example we are setting the video to be a Hardware surface (in GPU memory) and to use double buffering which should give use better graphics performance in the later examples.

Setting the window caption

To set the text in the titlebar of the window created by SDL we can use the following code

// next we set the window bar caption to the text 2nd param is for an icon
// this is a char * to a pixmap data but if we use 0 none is loaded
SDL_WM_SetCaption( "A Simple SDL Window", 0 );

Event processing

SDL uses an event structure called SDL_Event to store all the information about the various events the host system / Windows manager is passing. This structure is actually a structure or many other structures and we can process the information in a number of ways. For these first simple examples we are going to look for a key down press and the windows system passing a Quit message. The structure of this is a continuous while loop, where we check a flag to see if we should exit.

SDL is an ideal cross platform API for basic games development and other non GUI graphics systems. To quote the website above

"Simple DirectMedia Layer is a cross-platform multimedia library designed to provide low level access to audio, keyboard, mouse, joystick, 3D hardware via OpenGL, and 2D video framebuffer. It is used by MPEG playback software, emulators, and many popular games, including the award winning Linux port of "Civilization: Call To Power."
In this series of blog posts I will look at the basic use of SDL with a focus on using it on the Raspberry Pi, however all the code should work under all linux distributions as well as Mac OSX ( Windows should also just work, however I don't have a windows machine to test against).

Installing SDL using apt-get

The easiest way to install SDL on the rpi is to use apt-get and install the pre-build development packages. To do this use the following commands

sudo apt-get install libsdl1.2-dev

To check that this has been successful we can now execute the sdl-config script as follows

Installing from Source

The source code for SDL is available from this link http://www.libsdl.org/download-1.2.php. This is the easiest way to get SDL working on Linux system without apt as well as for Mac OSX. To build from the .tgz version do the following

Once this is done we can again check to ensure that things are working by testing the sdl-config program above.

Raspberry Pi user config for the console

If you intend to use SDL on the raspberry pi without using X windows the SDL library will attempt to access the framebuffer directly. By default only the root user has access to the framebuffer device so we need to add the current user (i.e. what you logged in as) to this group. To do this we need to add the user to the group video, input and audio groups (audio if we use it later) for a minimum you must have video and input.

sudo usermod -a -G video,input,audio [your username]

Once this is done logout and the user will be added to the group on the next login.