For this tutorial it is presumed, that you are familiar with procedures, functions, loops, pointers and usual commands of Free Pascal or its dialects. If this is not the case you may face problems because this tutorial deals with the features and usage of the SDL 2.0 library and will not explain basic concepts of Pascal programming. For a quick refresh on some Pascal basics, have a look into this (good) article Modern Object Pascal Introduction For Programmers by Michalis Kamburelis.
You can easily copy the example source code directly from the source code box for each chapter.
The SDL2 unit and the first application
Let’s start now. The most important rule to get ready for SDL 2.0 in your Pascal programs is:
Always include the SDL2 unit in the uses clause.
The SDL2 unit is the heart of every SDL 2.0 application! If you do so, you are perfectly prepared to start coding.
The different features of SDL 2.0 (screen/video handling, audio handling, keyboard handling, and so on) have to be initilized individually using this function.
It will return 0 on success and a negative error code on failure. You may wonder about the variable types SInt32 and UInt32 in the SDL_Init function declaration. Such integer types (which we will see in other chapters again) originate from the original C-language SDL 2.0 code. For an easier translation to Free Pascal they were kept. The S and U mean “signed” (negative values possible) and “unsigned” (values greater or equal zero only), the Int stands for “integer” and the number stands for the bit value. So UInt32 is an 32 bit unsigned integer (which corresponds to Free Pascal’s longword).
In the first example we want to initialize the SDL 2.0 video subsystem for screen handling. The following code example shows the frame of a typical SDL 2.0 application.
program Chapter3_SDL2; uses SDL2; begin //initilization of video subsystem if SDL_Init( SDL_INIT_VIDEO ) < 0 then HALT; //your SDL2 application/game //shutting down video subsystem SDL_Quit; end.
Instead of SDL_INIT_VIDEO you could initilize the respective subsystem by using SDL_INIT_AUDIO for audio subsystem, SDL_EVENTS for event subsystem, and so on. The table shows an overview of all the possible flags and their meaning:
|SDL_INIT_TIMER||Initilizes timer subsystem for handling of time related events.|
|SDL_INIT_AUDIO||Initilizes audio subsystem for playing music or sound effects.|
|SDL_INIT_VIDEO||Initilizes video subsystem for drawing/showing/manipulating of graphics, textures and screen, usually the most important subsystem.|
|SDL_INIT_JOYSTICK||Initilizes joystick subsystem for handling of joysticks.|
|SDL_INIT_HAPTIC||Initilizes haptic (force feedback) subsystem.|
|SDL_INIT_GAMECONTROLLER||Initilizes game controller subsystem.|
|SDL_INIT_EVENTS||Initilizes events subsystem for handling of mouse or keyboard input.|
|SDL_INIT_EVERYTHING||Initilizes all the subsystems above.|
|SDL_INIT_NOPARACHUTE||Ignores fatal signals. In SDL2 this is set by default and it isn’t possible to change this state. The explanation is given in the official migration guide I will cite here:There’s no SDL parachute anymore. What 1.2 called SDL_INIT_NOPARACHUTE is a default and only state now. This would cause problems if something other than the main thread crashed, and it would interfere with apps setting up their own signal/exception handlers. On the downside, some platforms don’t clean up fullscreen video well when crashing. You should install your own crash handler, or call SDL_Quit() in an atexit() function or whatnot if this is a concern. Note that on Unix platforms, SDL still catches SIGINT and maps it to an SDL_QUIT event.|
Of course you are allowed to combine several components by OR, e.g. “SDL_Init(SDL_INIT_VIDEO OR SDL_INIT_AUDIO)” to initilize video and audio support. If you are running some subsystems already but need to load further ones you would use
respectivly. Again 0 ist returned on success and the negativ error code in case of failure.
Quitting your programs
Every SDL program has to be closed by
It cleans up your system. Never forget it! This procedure ensures that all subsystems initilized get unloaded. There is a corresponding procedure to unload specific subsystems defined as
You are allowed to quit two or more subsystems by this function by using OR operator. It is advised to always quit SDL 2.0 applications by SDL_Quit even if you quit all of them individually by SDL_QuitSubSystem before.
Now you can try the example program. You will not see much but if you didn’t get an error message you was successful. Before proceeding, let’s have a quick look into error handling.
SDL 2.0 functions and errors
Every SDL 2.0 function returns an error value for you to check if the function runs properly at runtime. The values returned are of integer or pointer type. There is no general rule what values correspond to which status. In SDL 2.0 usually an integer value of 0 means “function runs/ran succesfully”, values lower than 0 correspond to a status “function couldn’t be run, something is wrong”. For pointers nil means error and any non-nil pointer means success. However, in most cases I won’t do error checking to keep code examples short. I will mention the error values to be expected though.
You should know that there is a function called
which translates the last error received into a message (of type PAnsiChar) that can be read out and printed to the screen by any function that can handle strings as well (e.g. the Pascal’s common write() function). Since SDL 2.0 is written in C originally, the PAnsiChar type is used in contrast to the String type (which is more common among Pascal programmers for message storage and handling).
A quick way to return the error message is to use the SDL2 message box feature:
SDL_ShowSimpleMessageBox(flags: UInt32; title: PAnsiChar; _message: PAnsiChar; window: PSDL_Window): Integer
The flags for the message box could be:
While the flags indicate the reason for the message box, the title and the message argument are used to set a box title and a message. The window argument can be set to the nil pointer.
The following short code snippet demonstrates a convenient way of using the box for showing error messages in the case of SDL2 initialization as done above.
//initilization of video subsystem if SDL_Init( SDL_INIT_VIDEO ) < 0 then begin SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, 'Error Box', SDL_GetError, nil); Halt; end;
Well, we have initilized the video subsystem and released it afterwards, and we learned about showing error messages in a simple message box. Simple Directmedia Layer deserves its name, isn’t it?
Only if you agree, you may proceed the next chapter ;-)!