All posts by Matthias

Savage Vessels

Impressive rogue-like 2D space shooter with pixel-art, physics and hard survival.

Interview with developer KPas

Could you please give a short description of Savage Vessels for those who have never heard of it?

Within fields of asteroids and fragmented freighters you scavenge and
combat against robot vessels. At the same time you have to keep away
from the surrounding void. With your carrier you got into this
threatening area. In order to escape you have to determine your location
repeatedly: leave the carrier, visit some navpoints, land again and move
on. But the robots won’t let you. So you have to arm against them by
gathering and crafting.

The visuals are based on top down pixel-art and a dynamic field of view.
Modern physics provide inertia and collision. Sound fx creates an eerie
atmosphere. It’s a spiritual successor to Teleglitch.

Why did you decide to choose Pascal as a programing language and SDL/SDL2 as a library for this project?

Pascal is my mother tongue. It’s capable of everything I need and I’m
feeling comfortable with it.

SDL is versatile, platform-agnostic and plain.

What do you think is the most interesting Pascal/SDL/SDL2 project out there (besides of your own, of course :-D)?

My nomination for now: DoomRL (https://drl.chaosforge.org/)

Are there any further steps for Savage Vessels and/or are any new projects planned? What will they be?

Savage Vessels is in development and I want to release it on Steam end
of year 2019 or so. You can wishlist it on Steam by the way.

The GoldSrc BSP Loader

Last updated on August 15th, 2018

This project is a program to load GoldSrc BSP files. The GoldSrc BSP file format has been derived from the id’s Quake 2 file format by Valve Software for their Half-Life game series.

It has been realized with

  • Lazarus, Free Pascal
  • SDL2, OpenGL.

 

The BSP Loader powered by Lazarus.
Loading a WAD file and displaying a selected texture from it.
Textured rendering of a scene (estate). The blue colorkey is not interpreted to be transparent yet.
Scene: Oilrig.
Scene: Assault.

02/08/2018, v0.1 alpha

  • Capabilities
    • Load BSP files and show contents of data lumps (exception: VIS Lump)
    • Load WAD files and render contained textures
    • Load BSP file and all WAD files which are necessary to render the fully textured scene
    • Navigate by simple camera through scene
  • To-Do’s
    • lightmapping from lightmap data
    • VIS Lump: treat it at all
    • collision detection
    • face culling
    • have spaces between textures in atlas texture to prevent bleeding-effect (esp. in tiled textures recognizable)
    • make blue colorkey transparent
    • sky cube
    • release the source code (if beta stadium reached)

Important Sources

BSP and WAD File Formats

I cannot state how important these documents were in understanding the structure of the BSP and WAD file formats. Without them, this project wouldn’t have been possible.

Matrix and Vector Functions

I used the SupraEngine.Math Unit by Benjamin ‘BeRo’ Rosseaux (benjamin@rosseaux.com) for this.

Implementation Hints

SDL2 title image

SDL2 Tutorial Improvements

I did a major update to the whole SDL2 tutorial, added some new, restructed and split up many old chapters to have a better learning experience. Instead of ten big learning chunks, there are now 18 smaller chunks which are dedicated to clearly outlined topics. I’m looking forward to do a lot of fine tuning and extending the SDL2 tutorial. If you find errors, just drop me a line.

Every article now shows a date of the last update. This makes it easier to estimate how up to date the article’s information are.

I decided to change the basic font size from 18 to 24 points since the text appears too small on common high resolution displays. I adapted point sizes for other elements accordingly. Also, I made license information available for many images (CC-BY 4.0).

The drop-down menu is gone since it got too long and it has been hard to reach all entries on some devices.

Thanks to MattCash Chapter 6 got some necessary updates.

Rectangles, Image Movement and Scaling

Last updated on August 11th, 2018

Screens and Images are rectangular, so this shape has a special importance to SDL2 and graphics programming in particular.

Rectangles: TSDL_Rect and PSDL_Rect in SDL 2.0

Often functions require an argument of PSDL_Rect type. This is the pointer counterpart to TSDL_Rect. It is declared as follows.

Simply, this record describes a rectangle, hence the name. The variables x and y correspond to the x/y coordinates of the left upper corner of the rectangle, related to the origin 0/0 which is the left upper corner of, e.g. a texture, window,… The variable w is the width and h the height of the rectangle. That’s it. The next step is to define the rectangle by assign some values for x, y, w and h.

If you use PSDL_Rect, you free the required memory by Pascal’s new procedure as you would for any simple record pointer.

Using Rectangles for Movement and Scaling

The following code demonstrates the basic principle how to achieve the impression of movement of images (sprites) and how scaling works. You will be impressed how simple it actually is.

We will get this as a result.

Creative Commons License This image by https://www.freepascal-meets-sdl.net is licensed under a Creative Commons Attribution 4.0 International License.
The result of the example program (500×500 px window). A part of the full image is stretched in the background while the full image is also squeezed into an area above the word “Free”.

For comparison, here is the original 200×200 px image.

Free Pascal meets SDL sample image bmp format
Original image (200×200 px).

Let’s disect the code.

In the var clause we declare the known variables for window, renderer and a texture. Also we have a new variable of TSDL_Rect type.

After initializing SDL2 and setting up the window and renderer as known, the rectangle is getting some values. It just encloses the words “Free Pascal meets SDL” in the original image (see above).

 

Scaling in SDL2

Scaling Quality

Right before creating the surface and texture, there is this line in code.

It sets the render quality. It has to be set before creating the texture. The SDL_SetHint(hint name, hint value) function is no specific function for setting scaling quality, but here we use it for exactly that. Possible values are

  1. nearest or 0
    • nearest pixel sampling
  2. linear or 1
    •  linear filtering
    • support by OpenGL and Direct3D
  3. best or 2
    • anisotropic filtering
    • support by Direct3D.

All of the values have to be set as string values, so ‘nearest’ or ‘0’. Here is a comparision of the nearest- and the linear filter.

The anisotropic filter doesn’t do anything for me, even if I used Direct3D.

Scaling by using Rectangles

At this point happens the magic that leads to the resulting image. By the way, since the SDL_RenderCopy() function requires the rectangle arguments to be of PSDL_Rect, we use the @-operator (pointer operator) here.

This means, copy the area described by “sdlRectangle” from the source (“sdlTexture1” here) to the whole area (because of nil value) of the destination, hence the window.

Since the window has a width and height of 500 px each, the source rectangle just a width of 178 px and a height of 116 px, SDL2 automatically scales the image to fit into the larger (or smaller) dimensions of the destination.

This means, copy the whole source (because of nil value) to the area described by “sdlRectangle”. The source is the 200×200 px image, which has to squeezed to the 178×116 px rectangle at position (12/25). This is just what you see in the resulting image (above) where the whole image is squeezed into this area.

Movement of Images (Sprites)

Although not covered directly by this code example, you get the picture how movement works. Every frame you adjust the (x/y) coordinates of the rectangle for the destination to bring the sprite about to move.

After cleaning up the memory the program finishes.

← previous Chapter | next Chapter →

Loading and Rendering a Bitmap File

Last updated on August 11th, 2018

Loading of bitmap image files (BMP files) is natively supported by SDL2. The way to go is as follows (from the flow diagram).

 

Creative Commons License This image by https://www.freepascal-meets-sdl.net is licensed under a Creative Commons Attribution 4.0 International License.
Flow diagram of the loading and rendering of a bitmap file in SDL2.

Let’s start on the left in the diagram. The easiest way to get a bitmap (BMP) image file for a game or application ready for usage is to create one in a drawing application. Or use the example bitmap “fpsdl.bmp” we used in the code.

Free Pascal meets SDL sample image bmp format
Creative Commons License This image by https://www.freepascal-meets-sdl.net is licensed under a Creative Commons Attribution 4.0 International License.
The original image is 200×200 pixels wide.

The bmp image file is stored on your hard drive and can be loaded by SDL_LoadBMP function to a SDL2 surface. This SDL2 surface is then transformed into a SDL2 texture by SDL_CreateTextureFromSurface function (whose name is just explaining what is does). And finally this texture is rendered by SDL_RenderPresent, this function we know already.

And now let’s see how it is done in code.

The result is this:

Result screenshot for chapter 4
Creative Commons License This image by https://www.freepascal-meets-sdl.net is licensed under a Creative Commons Attribution 4.0 International License.
This is the result of the code.

The var clause,

contains two new variables, namely “sdlSurface1” and “sdlTexture1” of the pointer types PSDL_Surface and PSDL_Texture, respecitvely.

After setting up SDL2, a window and a renderer as known, we find this.

Step 1: Loading the BMP file to a SDL2 Surface

SDL_LoadBMP(name of bmp image file) does what you expect, it loads the image file and generates a SDL2 surface from it. Attention though, if you just give a file name, it is assumed that the file is found in the same folder as the executing application. Optionally you can also give a full file path, e.g. in Windows something like ‘C:\MyImages\fpsdl.bmp’. The function is declared as

and return nil on error, e.g. if the file is not found.

Step 2: Creating a SDL2 Texture from the SDL2 Surface

The next step is to get a SDL2 texture. That’s achieve as follows.


The function to use is SDL_CreateTextureFromSurface(renderer, surface)

It just does what you expect and transforms the SDL2 surface into a SDL2 texture with the help of the given renderer.

Step 3: Prepare the SDL2 Texture to be Rendered

Before actually rendering the texture, we need to copy it to the rendering target (our window) by SDL_RenderCopy(renderer, texture, source rectangle (texture), destination rectangle (rendering target)).

So the texture is copied to the rendering target (which is the window). The first nil argument means that we want to copy the whole rectangle. The second nil means that we want to copy to the whole dimensions of the rendering target. Let’s have a closer look at the function.

You see here, that you could use arguments of type PSDL_Rect, which basically describes rectangles.

Step 4: The Rendering

And finally the rendering is done by the known SDL_RenderPresent().

Step 5: Destroying Surfaces and Textures

It is important to free the memory occupied by the surface and texture by SDL_FreeSurface(surface) and SDL_DestroyTexture(texture) right after .

Now you know how to load and render a bmp file to a window. 🙂

Remark: DO NEVER combine SDL_CreateTextureFromSurface() and SDL_LoadIMG!

Do never combine step 1 and step 2 to avoid declaring and freeing a surface. DO NEVER do this:

This will run without any problem, though SDL_CreateTextureFromSurface() will not free the surface created by SDL_LoadBMP(). And you have no handle to free this surface. This creates a memory leak. 

← previous Chapter | next Chapter →

Surfaces and Textures

Last updated on August 8th, 2018

This chapter treats some basics you should know to understand the way SDL2 works.

Briefly: The Basics of Graphics Programming

Loading and the movement of images in a game (or other applications) is a major concept in (game) programming. These images are then refered to as sprites, usually. Let’s have a look at a simple example:

left: ball and paddle erased between each frame; right: ball and paddle not erased between frames
Left: Window is cleared between each new drawn frame. Right: Window is not cleared.

Here are two screenshots from a simple game. The player has to move the yellow-green paddle up- and downwards to prevent the blue ball from getting through to the right side. The game uses two sprites, the blue ball sprite and the yellow-green paddle sprite (see left screenshot). The background color is set to black. The left screenshot is how the game usually appears to the player, here between each frame that got drawn, the former frame has been cleared. The right screenshot demonstrates what happens if the former frame hasn’t been erased before the next one is drawn. – Now it is clearly visible that the sprites are redrawn again and again with sligthly different coordinates, and that is how (game) graphics work (even for the most sophisticated 3d games):

  1. Draw the frame
  2. Show the frame (in a window on screen)
  3. Clear the frame (and go back to step 1)

Briefly: The Relation between Graphic Objects (e.g. Sprites) and Hardware

Actually there are just three locations where these images are stored in your computer system. All images (photo images, drawings, sprites for 2d games, textures for 3d games) are stored on your harddrive somewhere. If you start a photo viewer, a paint program, a 2d game or a 3d game, in all cases the corresponding images need to be loaded from your harddrive to RAM (Random-Access Memory) since displaying and manipulation (e.g. rotation of a photo image by 90°) of images loaded to RAM is much, much faster. Especially for games a fast access to the image data is highly important! And finally there isn’t just one RAM but two, a CPU controlled one located on the motherboard used by every program/application that needs some RAM. The second RAM is located right at your graphic board and controlled by the so-called GPU (graphics processing unit). This is what we want to use if we develop games since it is dedicated, optimized and just hungry for tasks related to fast image processing.

Many games and applications do not only target at common computer systems, but for mobile devices, e.g. smart phones. The principles described are also true for these devices even though there may be differences in detail.

The SDL2 Surface

The SDL2 surface allows you to represent graphic objects like sprites. Every SDL2 surface has a width and height, a pixel format and other properties. Nevertheless, it is a concept which originates from the outdated SDL 1.2 and therefore should not be used anymore. Still, there are reasons why we need to introduce it here. This will be clear soon.

The SDL2 Texture

The SDL2 texture allows you to represent graphic objects just like the SDL2 surface does, although there is a major difference: It is hardware accalerated. So the graphic object is stored in the graphic board’s RAM and any manipulation is done by the graphic board’s GPU.

So as a rule,

always use SDL2 Textures to store your graphic objects (sprites) for SDL 2.0,

then you go for high performance!

Three ways to SDL_Texture

So, how to get a SDL_Texture? In principle there are three ways to create SDL2 textures. For way 2 and 3 the flow diagram may illustrate how it works.

Way 1: From Scratch

You create a SDL_Texture from scratch, so you set a pixel format and texture access format and have to fill in your texture data manually. This is the most sophisticated way and is usually not necessary, unless you work with raw pixel data.

Way 2: The path from the file to the surface, to the texture and to the screen. Way 3: The path rom the file to the texture and to the screen.

Way 2: From SDL2 Surface

2) You have or create a SDL_Surface from an image file first and then you create the SDL_Texture from the SDL_Surface. This way is shown in the diagram but it means two steps.

Way 3: Directly from Image File

3) You create a SDL_Texture from and image file directly. This is shown in the diagram, too. This is the simplest way to create a SDL_Texture.

← previous Chapter | next Chapter →

Window and Renderer

Last updated on August 7th, 2018

Every SDL2 program that shall show some graphic output has to have at least one SDL2 window and a SDL2 renderer. The window is the entity that is showing the graphic output and the renderer is the “machine” that is generating the output to be shown in the window. The code to set up a window and a renderer is as follows.

Let’s have closer look at the var clause.

The SDL2 Window

In SDL 2.0 you can create as many windows as you like, and each window is adressed by its PSDL_Window variable. We just need one window for now, let’s call it “sdlWindow1”. It defines the window’s properties, e.g. size, appearance, border, title name and so on. And it holds the content it shows.

Creation of a Window

The creation of a SDL2 window is simple as using the function SDL_CreateWindow(title, x, y, width, height, flags) or more specific:

In our example the window is titled “Window1”, it is located at position x = 50 and y = 50 pixels (relative to your screen). It has a width and height of 500 pixels respecitvly. And we have used the flag SDL_WINDOW_SHOWN. More about these flags later. First let’s get an understanding of the coordinate system in SDL2.

The Coordinate System in SDL 2.0

This rule applies:

The origin from where to count to place a window is always the left upper corner of your screen.

So if you choose (0/0) as coordinates the window’s left upper corner will be placed right at the left upper corner of your screen. The diagram below may help to understand this. You may try SDL_WINDOWPOS_CENTERED for each or both coordinates which will lead to a centered window with respect of the screen. If you choose SDL_WINDOWPOS_UNDEFINED you don’t care for the window’s position.

SDL2 window and coordinates diagram
Creative Commons License This image by https://www.freepascal-meets-sdl.net is licensed under a Creative Commons Attribution 4.0 International License.
The window is placed with respect to the left upper corner of the screen.

SDL 2.0 windows and their properties

Now let’s talk about the flags. They decide for the properties of the window. Look at the following table (source) of possible flags and you may get an idea what they do.

Flag
Description
SDL_WINDOW_FULLSCREENfullscreen window
SDL_WINDOW_FULLSCREEN_DESKTOPfullscreen window at the current desktop resolution
SDL_WINDOW_OPENGLwindow usable with OpenGL context
SDL_WINDOW_SHOWNwindow is visible
SDL_WINDOW_HIDDENwindow is not visible
SDL_WINDOW_BORDERLESSno window decoration
SDL_WINDOW_RESIZABLEwindow can be resized
SDL_WINDOW_MINIMIZEDwindow is minimized
SDL_WINDOW_MAXIMIZEDwindow is maximized
SDL_WINDOW_INPUT_GRABBEDwindow has grabbed input focus
SDL_WINDOW_INPUT_FOCUSwindow has input focus
SDL_WINDOW_MOUSE_FOCUSwindow has mouse focus
SDL_WINDOW_FOREIGNwindow not created by SDL
SDL_WINDOW_ALLOW_HIGHDPIwindow should be created in high-DPI mode if supported (available since SDL 2.0.1)

As you can see, these flags determine different properties of  the window. E.g. SDL_WINDOW_FULLSCREEN will create a fullscreen window and SDL_WINDOW_BORDERLESS will create a borderless window. You may combine several flags by OR (if appropriate). For our purpose SDL_WINDOW_SHOWN is a good choice because we just create a shown window without any further restrictions.

The SDL2 Renderer

In computer graphics rendering means the process of synthesizing the final image on your screen from the individual basic data structures. To draw some content to the window, we need therefore a renderer. The PSDL_Renderer (which we declared in the var clause) is responsible for synthesizing all the content in a window, be it some lines, a flat background, a texture, a 3d object, or whatever. We call our PSDL_Renderer “sdlRenderer”.

Creation of a Renderer

The creation of the renderer is as simple as one function call of SDL_CreateRenderer(window, index, flags) or

First we need the renderer to know where to render the finished/rendered output. That will be “Window1” in our case. Next the shown function asks for a cryptic “index”. Well, each driver which is capable of rendering (e.g. OpenGL, Direct3d, Software,…) is indexed in SDL 2.0. In principle you could choose one specific driver here by choosing the corresponding index. Since we don’t know too much about the drivers at the moment the best choice is -1. -1 means that the first driver which is supporting the chosen flag(s) is chosen. Talking about flags, there are four flags you may choose:

  1. SDL_RENDERER_SOFTWARE
  2. SDL_RENDERER_ACCELERATED
  3. SDL_RENDERER_PRESENTVSYNC
  4. SDL_RENDERER_TARGETTEXTURE

You should always prefer SDL_RENDERER_ACCELERATED because this means the graphics board is responsible for rendering, SDL_RENDERER_SOFTWARE in contrast means, the CPU has to do the rendering. As discussed before for best performance the graphic board is the best choice for rendering/graphic related tasks. SDL_RENDERER_PRESENTVSYNC allows for so called vertical synchronization which means that the display of the rendered image is synchronized with the refresh rate of the monitor. SDL_RENDERER_TARGETTEXTURE allows for rendering to a texture. You may have noticed that none of these flags but 0 was used in the example code. This automatically gives priority to hardware accelerated renderers.

Quick Creation of a Window and a Renderer

Instead of creating the window and the renderer separately as demonstrated, you may use SDL_CreateWindowAndRenderer(width, height, window flags, window pointer pointer, renderer pointer pointer). This has the advantage that you just need one line to set up a window and a renderer, though setting a window title, a window position or specific renderer flags have to be done afterwards if necessary.

Just remove the curly brackets and enclose the “full set up” -part to try it.

This function returns 0 on success and -1 on failure.

Rendering a SDL2 Scene

The actual rendering is achieved by SDL_RenderPresent(renderer). As a sidenote for people coming from SDL 1.2, this is what formerly has been achieved by SDL_Flip().

Freezing (delaying) a running program in SDL 2.0

SDL_Delay(time in milliseconds) is a simple, yet powerful and important procedure to stop the program running for a certain time in milliseconds. 2000 milliseconds are two seconds. This is kind of a twin of Pascal’s Delay procedure.

Clean up the memory in SDL 2.0

Now the final lines of code are discussed. One of the most important rules for sophisticated programming is followed here:

Always clean up the memory on program finish.

For nearly any pointer type generated by SDL 2.0, there is a destroy procedure to remove it from memory. These procedures are comparable to Pascal’s dispose procedure to remove pointer types from memory. Make sure to destroy the objects in the opposite sequence of their generation. We first created a window, then a renderer. So now we go the opposite way, first destroy the renderer and then the window by the procedures SDL_DestroyRenderer(renderer) and SDL_DestroyWindow(window) respectively.

Here we go:

Do not forget to quit SDL2 finally (which we don’t).

That’s it. And now things are going to get really interesting :-).

← previous Chapter | next Chapter →

Viewports

Last updated on August 11th, 2018

SDL2 allows for viewports. Have a look at the following screenshot of a SDL2 game (Battle for Wesnoth).

Modified screenshot of Battle of Wesnoth. (Original source image, as found in the Wesnoth Wiki by Wesnoth developers. Image license: GFDL.)

This is a classical situation to use viewports. The game screen is clearly parted into three distinguished areas. The main screen is the large part left with the mountains and the castles. Then there is the minimap in the right-upper corner. And a statistics overview under the minimap. These areas and the corresponding viewports are highlightened in the following screenshot.

Modified screenshot of Battle of Wesnoth. (Original source image, as found in the Wesnoth Wiki by Wesnoth developers. Image license: GFDL.)

The advantage of viewports is that each of them behaves like an own window, so if you draw to the right outside of viewport 1 in the screenshot above, the texture will just be clipped and there is no overlap into viewport 2 oder 3.

SDL2 window and viewport coordinates diagram
The relation of your screen, a SDL2 window and a viewport within this window are outlined here.

Let’s have a look at the code.

The result will look like this:

Creative Commons License This image by https://www.freepascal-meets-sdl.net is licensed under a Creative Commons Attribution 4.0 International License.
There are three viewports with different background colors and a black dot in the left upper corner.

First we set up some SDL2 rectangles by

“Viewport1” represents the red viewport (left), “Viewport2” the yellow (upper-right) and “Viewport3” the green (lower-right) viewport in the result image.

Notice how we just prepare one “BlackDot” rectangle for a black dot of 3×3 px dimension at location (10/10).

After setting up SDL2, a renderer and a window as known, we start to set up the first (red, left) viewport.

It is simple as that. Use the function SDL_RenderSetViewport(renderer, rectangle pointer) to set up a viewport. This function returns 0 on success or -1 on failure.

After we set up the viewport, we set the draw color by SDL_SetRenderDrawColor(renderer, red, green, blue, alpha) to red (255/0/0/no transparency). Then we use SDL_RenderFillRect(renderer, rectangle pointer) to fill the whole viewport by not specifying a rectangle (nil). Both functions are known from a previous chapter.

Then the color is set to black and a tiny 3×3 rectangle is drawn at location (10/10).

This procedure is repeated for the other two viewports. Notice again, how we use the same rectangle for the black dot though and where it is shown in the result image. The black dot is always drawn at location (10/10) relative to the respective viewport’s location!

As general rule it applies:

The coordinates are always relative to the currently set viewport.

Well, the remaining parts of the code provides nothing new, just the rendering for 2 seconds and some clean up.

Let’s close with some helpful remarks.

No SDL_RenderClear for Viewports!

Do not use SDL_RenderClear(renderer). It will ignore the viewports and clear the whole window with the set drawing color.

Resetting the Viewport

The resetting is done simple by SDL_RenderSetViewport(renderer, nil) as one would expect.

← previous Chapter | next Chapter →

A Custom Mouse Cursor

Last updated on August 8th, 2018

Any good game has a custom mouse cursor. You may think it would be a good idea to have a SDL2 surface or SDL2 texture and render it as any other sprite right at the mouse position to simulate a mouse cursor. DO NOT do this! The mouse cursor is handled separatly from the other rendering to have it smooth and working in critical situations. 

The following code shows how to set up a custom mouse cursor with SDL2 the correct way.

To have a custom mouse cursor we need a variable of type PSDL_Cursor. We call it “sdlMouseCursor” here.

The result looks like this:

Custom Mouse Cursor in SDL2
Creative Commons License This image by https://www.freepascal-meets-sdl.net is licensed under a Creative Commons Attribution 4.0 International License.
The blue cross with the yellow outline is the mouse cursor on the grey canvas/window. 

This is the interesting part of the code with regard to creating a custom mouse cursor. The cursor’s image is defined by a SDL surface. We create the SDL surface as known from a previous chapter from a png image file to “sdlSurface1” here.

The custom mouse cursor is created by the following function, which returns nil on error.

It needs the surface to use as cursor image and two coordinates (hot_x/hot_y) as arguments. They determine where the actual hitting point for this cursor is. Since the example cursor image is of dimensions 16×16 px and represents a cross, the “hot” (hitting) coordiates are (8/8), hence the cross’ center is used for hitting a button or something. In contrast you may imagine a typical arrow shaped mouse cursor, where the hitting point has to be adjusted to be right on the tip of the arrow in the arrow’s image.

If the cursor creation has been successful, it is necessary to set it to be the actual cursor. You may have created many different cursors, so tell SDL which one to use by the following procedure.

The remaining part of the code is just rendering a 500 by 500 pixels window with a grey (128, 128, 128) background that is updated as long as no mouse button has been pressed.

Finally do not forget to free the mouse cursor by SDL_FreeCursor(mouse cursor) as shown.

← previous Chapter | next Chapter →

Which SDL2 unit to choose?

Right now I’m aware of four translation projects that provide SDL2 units (if you know a further one, let me know):

Project
Link
Description
Tim Blume's SDL 2.0 units Pure translation of SDL 2.0 source files. The original, modular structure of the header files is preserved, so the SDL2.pas is composed of many include files. Translations of SDL2_mixer, SDL2_ttf and SDL2_image are available, SDL_net seems to be missing so far. It provides MacOS X support.
p_daniel's (or danpla's) SDL 2.0 units Pure translation of the SDL 2.0 source files. All the header files of the original SDL 2.0 source code are combined into one large SDL2.pas (similar to JEDI-SDL's SDL.pas for SDL). Translations of SDL2_mixer, SDL2_ttf, SDL2_image and SDL2_net are available. The MacOS X support is unproven.
Imants Gulis' SDL 2.0 units Heavily modified SDL 2.0 units to allow for dynamic loading of the library.
Bare Game Library Bare Game is a game library which is put on top of the SDL2 library. It also allows for easy combination of SDL2 with Lazarus, which is a great plus.

Now we go for a detailed discussion of them.

Modified header translations

Well, the Bare Game Library is a great project and I like the idea to provide an easy-to-use game development library  very much but it isn’t suitable to learn pure SDL 2.0. Many functions are wrapped by new function names, you would learn much about the usage of Bare Game, fewer about SDL 2.0 itself. Also, the ease of use is traded for flexibility, e.g. there is just support for Windows and Linux, no Mac support, and you are more or less forced to use Lazarus IDE (which is an excellent choice, no question!) but for some reason you might not want to use Lazarus. The usage of libraries always trades ease for flexibility. And finally you are dependent upon a second project. If SDL 2.0 is updated, will Bare Game have updates, too? Bare Game is a great project at all, but for learning SDL 2.0 and if you keep the downsides in mind, it is not the best choice here.

Imant’s Gulis units allow for dynamic loading of SDL 2.0, hence your application decides during run-time if SDL 2.0 has to be loaded. This led to heavily modified unit files compared to the original header files. Also it is expected to use Lazarus. Although there are numerous cases where dynamic loading can be a great plus, for the tutorial and a wide variety of applications this is not necessary.

Pure header translations

So there are two projects left. The beauty of p_daniel’s SDL 2.0 units is the fact that there are exactly five files you need. They contain all the translations for basic SDL 2.0 and the official extensions SDL2_mixer, SDL2_ttf, SDL2_image and SDL_net. Tim Blume’s SDL 2.0 units are trying also to support the MacOS X ability of SDL 2.0. That is one important plus for Tim Blume’s SDL 2.0 units. Furthermore, the original comments are kept in the translated files, whereas in p_daniel’s SDL 2.0 units they are cut out! This is a major drawback for p_daniel’s SDL 2.0 units to my mind. Sometimes you need just a quick look at the implementation of a function in the source to get how it works or what is wrong, and these comments are really quite descriptive. In Tim Blume’s SDL 2.0 units though, I don’t like that the file names got changed, e.g. SDL_audio.h got sdlaudio.inc instead of SDL_audio.inc. Anyway, this is acceptable to me.

Conclusion

This said, to my mind, the best choice to start with pure SDL 2.0 and Free Pascal: Go for Tim Blume’s SDL 2.0 units. For other purposes, other units may be the better choice.