All posts by Matthias

New Version of SDL2-for-Pascal Units Released

Version 2.2 of the SDL2-for-Pascal Units got released! It took nearly two and a half years to update the SDL2-for-Pascal Units to be quite up-to-date with the latest version of SDL2. We got a quite updated package now. For you this means, there is no good reason not to start using SDL2 in Pascal to realize your (game) projects, be it with Free Pascal or Delphi, on Linux, Windows or MacOS. – Other compilers and OS’es work too, probably.

I’d like to thank all contributors for their efforts. I’d also like to thank suve, the co-maintainer, for the great cooperation, without which some large improvements would be missing in this release and some serious mistakes wouldn’t have been caught before merging the code :-)!

Happy New Year and Happy Coding!

Here are the offical release notes:

  • SDL2 unit is up-to-date with at least version 2.0.14 of the SDL2 library (exception sdlthread.inc)
  • many aliases got replaced by typed enums
  • add single and double pointers for all types (thanks furious-programming)
  • update SDL_ttf.pas to latest version 2.21.0
  • replace data types by c data types (see PR #29)
  • add folder structure (see PR #27)
  • many bugfixes
title image fairtris

Fairtris and an “Error Chapter” :-)

Added a new great project by Jarosław Baran, Fairtris! – It is purely done in the Lazarus IDE with Free Pascal and uses the SDL2-For-Pascal units to make use of graphic hardware acceleration. The full source code is available and poses a great opportunity to learn how to craft a SDL2 game with Free Pascal!

A brand new chapter about error handling in SDL2 and its combination with Pascal’s exception handling is released now and added to the SDL2 tutorial.

Updated the widgets (replaced legacy widgets) and added new links. Some tags got updated to reflect my new “naming policy” to use SDL2 instead of SDL 2.0.

The work on SDL3 has begun on the official development branch of the SDL project. I’m curious to see what comes from this.

Edit: Fairtris’ author’s name got corrected. (03/06/2023)

Error Handling

Last updated on March 5th, 2023

Error handling in Pascal means raising exceptions and catching them. SDL2 has also a way to treat errors. Both worlds can be combined and this chapter shows you how.

Let’s look at the whole program code:

program SDL_ErrorHandling;

uses SDL2, SysUtils;

type
  ESDLNilPointer = class(Exception);

var
  sdlWindow1: PSDL_Window;
  sdlRenderer: PSDL_Renderer;
  sdlSurface1: PSDL_Surface;

const
  filename = 'nofile.bmp'; // this file does not exist

begin
  // Initialize SDL2
  if SDL_Init(SDL_INIT_VIDEO) < 0 then Exit;

  // Create a window, renderer and a surface
  try
    SDL_CreateWindowAndRenderer(500, 500, SDL_WINDOW_SHOWN,
      @sdlWindow1, @sdlRenderer);

    if not Assigned(sdlWindow1) then
      raise ESDLNilPointer.CreateFmt(
        'sdlWindow1 is nil. SDL_GetError: %s', [SDL_GetError]);

    if not Assigned(sdlRenderer) then
      raise ESDLNilPointer.CreateFmt(
        'sdlRenderer is nil. SDL_GetError: %s', [SDL_GetError]);

    sdlSurface1 := SDL_LoadBMP(filename); // sdlSurface1 will be nil!
    if not Assigned(sdlSurface1) then
      raise ESDLNilPointer.CreateFmt(
        'sdlSurface1 is nil on loading %s. ' + sLineBreak + 'SDL_GetError: %s',
        [filename, SDL_GetError]);
  except
    on E: ESDLNilPointer do
    begin
      WriteLn('Exception ESDLNilPointer: ' + sLineBreak + E.Message);
      Readln;
    end;
  end;

  // Clean-up and quit SDL2
  if Assigned(sdlSurface1) then SDL_FreeSurface(sdlSurface1);
  if Assigned(sdlRenderer) then SDL_DestroyRenderer(sdlRenderer);
  if Assigned(sdlWindow1) then SDL_DestroyWindow(sdlWindow1);
  SDL_Quit;
end.

If you run this program, it will stop execution because it catches an exception. It will return several helpful information to make identification of the cause of the exception easier. It allows you to proceed running after the exception has been caught to free resources and prevent memory leaks. It will report the following exception messages:

sdlSurface1 is nil on loading nofile.bmp.

SDL_GetError: Parameter ‘src’ is invalid

Let’s start with the first part of the code:

program SDL_ErrorHandling;

uses SDL2, SysUtils;

type
  ESDLNilPointer = class(Exception);

var
  sdlWindow1: PSDL_Window;
  sdlRenderer: PSDL_Renderer;
  sdlSurface1: PSDL_Surface;

const
  filename = 'nofile.bmp'; // this file does not exist

The program “SDL_ErrorHandling” has three variables representing a SDL2 window, a SDL2 renderer and a SDL2 surface. It also has a constant “filename” which defines a file name of an imaginary file called “nofile.bmp”. As this file doesn’t exists, it will cause an exception on trying to load it (later in the code).

Right above the var block is an exception class declared whose names start by convention with a capital E instead of a capital T. It is called “ESDLNilPointer” and will be raised whenever a SDL2 function returns a nil pointer as error code. Nearly all function in SDL2 return an error code where 0 usually means sucess and -1 usually means failure. SDL2 function which create objects usually simply indicate failure by nil-pointers.

The main program’s begin .. end. code block starts with the initilization of the SDL2 system and ends with the clean up part and the quitting of the SDL2 system. I will not cover this in detail here again. Let’s instead have a detailed look into the core part of the begin .. end. block:

  // Create a window, renderer and a surface
  try
    SDL_CreateWindowAndRenderer(500, 500, SDL_WINDOW_SHOWN,
      @sdlWindow1, @sdlRenderer);

    if not Assigned(sdlWindow1) then
      raise ESDLNilPointer.CreateFmt(
        'sdlWindow1 is nil. SDL_GetError: %s', [SDL_GetError]);

    if not Assigned(sdlRenderer) then
      raise ESDLNilPointer.CreateFmt(
        'sdlRenderer is nil. SDL_GetError: %s', [SDL_GetError]);

    sdlSurface1 := SDL_LoadBMP(filename); // sdlSurface1 will be nil!
    if not Assigned(sdlSurface1) then
      raise ESDLNilPointer.CreateFmt(
        'sdlSurface1 is nil on loading %s. ' + sLineBreak + 'SDL_GetError: %s',
        [filename, SDL_GetError]);
 

Exception handling in Pascal

In short: Pascal’s exceptions are raised by the raise keyword and stop the program flow at this point. As this would terminate the program immediately, usually raised exception are caught and handled by try .. except or try .. finally blocks. After proper exception handling the program can run without termination although an exception occured.

As you can see, here the whole whole code is encapsuled by a try .. except statement.

Error handling in SDL2

SDL2 knows three error related functions: SDL_GetError, SDL_SetError(Format string, Arguments) and SDL_ClearError. They are completely independent of Pascal’s error handling but are very useful to gather the necessary information to fix issues.

Most SDL2 functions return an error code which indicated success or failure. SDL_GetError returns a string (as PAnsiChar) which gives you information about the error of the last function that returned an error code which indicated failure. Attention here, only fails will result in a message in SDL_GetError and they won’t be cleared autmatically if other functions run successully afterwards, hence you should use SDL_ClearError to clear the last error message from older functon calls. Hint: Sometimes SDL_GetError can be populated with a message even though functions were run successfully.

In the try-block of our code there are actually just two things tried:

  1. Create a renderer and a window
  2. Create a SDL2 surface from a bitmap file

After creating the renderer and window as known to you, we check for the error code (in these cases we check if one or both of them are nil). If the error code indicated a failure, an exception should be raised. Actually this code should not raise an exception and just run smoothly to the second step.

Creating a SDL2 surface will fail intentionally because there is no bitmap file to load. SDL_LoadBMP will return a nil pointer, hence “sdlSurface1” is nil. This will raise the previously declared “ESDLNilPointer” exception with a message as format string (see below if you don’t know about format strings).

The error message string is:


        'sdlSurface1 is nil on loading %s. ' + sLineBreak + 'SDL_GetError: %s'
 

The arguments are represented by an array of constants:


        [filename, SDL_GetError]
 

The error message has three parts. The first part states the failing variable and the associated file name. The second part (sLineBreak) is a cross-platform line break. The third part returns the message of the SDL_GetError function.

What is a Format string?

Coming from C, format strings are strings which contain data placeholders of defined type (string, integer, float, …) which are then combined to the final string. The data placeholders are preceded by a percent symbol (%) and followed by single symbol indicating its type (s for string, d for decimal integer, …)

Ex.: ‘This %s has more than %d words.’ [chapter, 20] will result in: “This chapter has more than 20 words.”

Back to the code:

  except
    on E: ESDLNilPointer do
    begin
      WriteLn('Exception ESDLNilPointer: ' + sLineBreak + E.Message);
      Readln;
    end;
  end;

The except-block handles the raised exception. In the example code it just prints the error message we composed on creation of the exception.

  // Clean-up and quit SDL2
  if Assigned(sdlSurface1) then SDL_FreeSurface(sdlSurface1);
  if Assigned(sdlRenderer) then SDL_DestroyRenderer(sdlRenderer);
  if Assigned(sdlWindow1) then SDL_DestroyWindow(sdlWindow1);
  SDL_Quit;
end.

Finally, the resources are free’d.

Combining Pascal exception and SDL2 error handling

The SDL2 error functions are a convenient way to have a good insight in errors related to the SDL2 functions. It builds a powerful symbiosis with Pascal’s exception handling capabilities.

By the way, SDL_SetError(Format string, Arguments) allows to create your own error messages. In Pascal this is usually not necessary though because the message is set in the exception class.

← previous Chapter | next Chapter →

Fairtris

The description of this project found on it’s Wiki page says it all, nothing to add other than that this project is really capable of spawning some good, nostalgic feelings (!):

Fairtris is a video game, a clone of the 32-year-old Tetris® game produced by Nintendo for the Famicom and NES consoles, designed for modern Windows and Linux systems. Fairtris is not an emulator — it is a full-fledged game, created from scratch in Free Pascal language (using the Lazarus IDE) and with Direct3D and OpenGL support via the SDL library. Thanks to this combination, it is super-fast and ultra-light.”

sdl2 news title image

SDL2 documentation

Thanks to suve a new documentation resource is available for the PGD SDL2 units at https://pascalgamedevelopment.github.io/SDL2-for-Pascal. The docs are generated directly from the source if new pull requests are merged into the master branch of the repository. Talking of the SDL2 units: They made good progress in 2022 and are still making good progress and soon the first official release will be available.

FFPlay4Laz2 has been added to the projects. It is a Free Pascal/Lazarus Media Player powered by the FFmpeg frame work and SDL2.

In the future I will not refer to SDL version 2 as “SDL 2.0” anymore as SDL’s version numbering scheme has changed with version 2.0.23 (now actually being 2.23.1). That means the minor version is not zero anymore and SDL 2.0 is misleading in that regard. I will update any reference by “SDL2”.

Updated Chapter 4 to reflect changes in the new PGD SDL2 units.

FFPlay4Laz2

FFPlay4Laz2 is the SDL2 version of the older SDL 1.2 based (Win32 only) FFPlay4Laz FFmpeg Video and Media Player. FFPlay4Laz2 is extended to have more features than FFPlay4Laz and provide better performance. It is designed to be cross-platform by replacing Win-API calls by SDL2 calls. The project is open source and can be found on the official Lazarus forums.

Console menue of FFPlay4Laz2. (Image source: Captured from FFPlay4Laz2_Images.pdf, see link below; 28/12/2022)

This project has no official website and the author provides updates via the official Lazarus forums (see link below).

sdl2repo-music-sound

Many updates, everywhere

The news title says nothing and everything :-).

After an PHP update the syntax plugin doesn’t work anymore. I added a better plugin and updated all chapters to display code in a reader friendly way. I also removed the description how to copy source code using the old plugin in the introductory chapter. I adapted code snippet length in some chapters (Chapter 4, Chapter 15). Updated Chapter 18 about music and sound.

I added a new SDL2 powered Free Pascal project: SuperSakura. It’s a nice visual novel engine to run retro-style Japanese games by Kirinn.

I updated some chapters (Introduction, Windows Installation, Linux Installation), mainly because of the repository change to the PGD Community SDL2 units. The units got a lot of updates lately, and help is needed to improve them even further. While this news post was waiting to be published, it appears Tim is back. Now, we have the unfortunate situation that there are two active repositories for the SDL2 headers and the situation has not been resolved, yet.

Also, I changed some stylings.

SuperSakura

Menue screen of the engine. (Image: With permission of the author.)

Well, the introduction for this amazing project over at the Kirinn’s (developer) website says it all!

SuperSakura is a free, open-source visual novel engine that can run quite a few old games, mostly published by JAST, one of the first developers in the field. In addition to well-known localised titles, Japanese companies produced lots of fairly good games in the 90’s that were never translated.

And this project is fully written in Free Pascal and uses SDL2. Amazing work! I was happy to hear, the author got started with Free Pascal and SDL2 right here, with these tutorials :-)!

Download SDL2 units on GitHub

Important: New SDL2 Repo!

IMPORTANT: The repository to get the newest, up to date, SDL2 units has changed. It is found here: https://github.com/PascalGameDevelopment/SDL2-for-Pascal. It is now hosted by our Partner site Pascal Game Development, where you can find many resources if you are interested in game development with Delphi or Free Pascal.

Background: The old repository by Tim Blume has been an up to date source for these units for many years since its establishment (Thanks Tim!), but lately no more pull requests were integrated and so a new repository maintainer had to be found. Long time contributor to the units, Super Vegeta (suve), came up with the great idea to integrate it to the PGD repository, which is now reality (Thanks AthenaOfDelphi!).

What now: Please, if you are a Pascal SDL2 developer, pull from, commit to, fork and star the new repository over at https://github.com/PascalGameDevelopment/SDL2-for-Pascal and update your links accordingly. 🙂

Updated the Linux installation chapter. Now you can get the environment running rather quickly.

Added a new widget “Quality Pascal Articles” (right sidebar) where I add carefully chosen Pascal articles, I appreciate.

WASD title image

Keyboard and Key States Chapter added

Added a new chapter about the keyboard state and the key states for simple key input handling. Updated the Text and Font chapter.

It seems the author of p_daniel’s (or danpla’s) SDL 2.0 units has deleted his github account (EDIT, 06/10/2019: The user name got changed.), hence I updated the discussion page about which unit to choose. Also the official website of the Bare game project seems to be offline. Thanks for the hints Stéphane.

A new impressive, commercial SDL2 based Pascal project called Savage Vessels has been added to the project list. The project list itself got restructured for better readability and loading times.