The demos use SDL for four jobs: a window, the keyboard and the mouse, drawing, and text. Everything else, from a vector's length to a pixel's depth, is the book's own code. This appendix lists every SDL and SDL_ttf function the demos call, with what it does, and the chapter whose demo uses it first. The book was built with SDL 3.4.4 and SDL3_ttf 3.2.2, and any later 3.x release will do.
Each call is shown as the demos write it. Where a table says Chapter 1, the call is the skeleton's, and Appendix B prints it in place. The mouse click and the line are Plotter's.
Starting and Stopping
These open the window and load the font at the start, and undo it all at the end:
| Call | What it does | First used |
|---|---|---|
SDL_Init(SDL_INIT_VIDEO) |
Starts SDL's video, returning false if it fails |
1 |
TTF_Init() |
Starts SDL_ttf, returning false if it fails |
1 |
SDL_CreateWindow(title, w, h, 0) |
Makes the window | 1 |
SDL_CreateRenderer(window, nullptr) |
Makes the renderer that draws into the window | 1 |
SDL_SetRenderVSync(renderer, 1) |
Makes each present wait for the screen's refresh | 1 |
SDL_GetBasePath() |
Gives the program's folder, where the font is | 1 |
TTF_OpenFont(path, 16) |
Loads a font at a size in points | 1 |
SDL_Log(format, ...) |
Writes a message, as printf does |
1 |
SDL_GetError() |
Says why the last SDL call failed | 1 |
TTF_CloseFont(font) |
Frees the font | 1 |
SDL_DestroyRenderer(renderer) |
Frees the renderer | 1 |
SDL_DestroyWindow(window) |
Closes and frees the window | 1 |
TTF_Quit(), SDL_Quit() |
Shut SDL_ttf and SDL down | 1 |
The cleanup goes in the reverse order of the making, since each thing may depend on the ones made before it.
Time
Delta time comes from SDL's high-resolution counter:
| Call | What it does | First used |
|---|---|---|
SDL_GetPerformanceCounter() |
Gives the counter's value now, in ticks | 1 |
SDL_GetPerformanceFrequency() |
Gives the number of ticks in a second | 1 |
The seconds between two readings are their difference, divided by the frequency.
Events
Things that happen once arrive as events, and SDL_PollEvent(&event) takes the next one waiting, returning false when there are none. The event's type says what happened, and a field for that type holds the details:
| Type | What happened, and its details | First used |
|---|---|---|
SDL_EVENT_QUIT |
The window's close button was clicked | 1 |
SDL_EVENT_KEY_DOWN |
A key went down: event.key.key is its keycode |
1 |
SDL_EVENT_MOUSE_BUTTON_DOWN |
A button went down: event.button.button is which, at event.button.x and .y |
1 |
SDL_EVENT_MOUSE_BUTTON_UP |
A button came up, with the same details | 4 |
SDL_EVENT_MOUSE_WHEEL |
The wheel turned: event.wheel.y is how far, positive away from you |
27 |
SDL_EVENT_MOUSE_MOTION |
The mouse moved: event.motion.xrel and .yrel are how far |
28 |
A keycode is a key's name, such as SDLK_ESCAPE, SDLK_SPACE or SDLK_R, and a letter's keycode is the same with Shift held or not. The buttons are SDL_BUTTON_LEFT and SDL_BUTTON_RIGHT.
The Mouse and the Keyboard, Read Each Frame
What's held, rather than what happened, is read once a frame:
| Call | What it does | First used |
|---|---|---|
SDL_GetMouseState(&mx, &my) |
Gives the mouse's position, and returns which buttons are held | 1 |
SDL_GetKeyboardState(nullptr) |
Gives an array that's true for each key held |
7 |
SDL_SetWindowRelativeMouseMode(window, true) |
Hides the mouse, so that only its movement counts | 31 |
The buttons that SDL_GetMouseState returns are tested with masks, as in buttons & SDL_BUTTON_LMASK, from Chapter 2. The keyboard's array is indexed by scancodes, such as SDL_SCANCODE_LEFT or SDL_SCANCODE_W, which name a key by its place on the keyboard, rather than by what's printed on it.
Drawing
Every frame clears the window, draws, and presents. These draw in the renderer's current color:
| Call | What it does | First used |
|---|---|---|
SDL_SetRenderDrawColor(renderer, r, g, b, a) |
Sets the color for what's drawn next | 1 |
SDL_RenderClear(renderer) |
Fills the whole window with the color | 1 |
SDL_RenderPresent(renderer) |
Shows the finished frame | 1 |
SDL_RenderLine(renderer, x1, y1, x2, y2) |
Draws a line | 1 |
SDL_RenderRect(renderer, &rect) |
Draws a rectangle's outline | 8 |
SDL_RenderFillRect(renderer, &rect) |
Fills a rectangle | 8 |
SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_BLEND) |
Lets a color's alpha show what's beneath it | 15 |
SDL_RenderRects(renderer, rects, n) |
Draws many outlines in one call | 19 |
SDL_RenderFillRects(renderer, rects, n) |
Fills many rectangles in one call | 19 |
SDL_RenderGeometry(renderer, texture, verts, n, indices, m) |
Fills triangles, colored or textured | 24 |
A rectangle is an SDL_FRect: its left and top, and its width and height, in floats. The triangles of SDL_RenderGeometry are made of SDL_Vertexes, each a position, a color and a texture coordinate. Its color is an SDL_FColor, with each part from 0 to 1, not from 0 to 255. With nullptr for the texture, the colors fill the triangles, as Chapter 26's square and Chapter 27's tiles are filled.
Textures
A texture is a picture the renderer can draw. The skeleton's text is drawn through one, and from Chapter 24, the demos make their own:
| Call | What it does | First used |
|---|---|---|
SDL_CreateTextureFromSurface(renderer, surface) |
Makes a texture from a surface, such as a line of text | 1 |
SDL_RenderTexture(renderer, texture, nullptr, &dst) |
Draws a texture into a rectangle | 1 |
SDL_DestroyTexture(texture), SDL_DestroySurface(surface) |
Free a texture and a surface | 1 |
SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA32, access, w, h) |
Makes an empty texture | 24 |
SDL_UpdateTexture(texture, nullptr, pixels, pitch) |
Copies pixels into a texture | 24 |
SDL_SetTextureScaleMode(texture, mode) |
Chooses nearest or linear sampling | 24 |
SDL_SetRenderTextureAddressMode(renderer, u, v) |
Chooses clamping or wrapping, for coordinates past the edge | 24 |
The access is SDL_TEXTUREACCESS_STATIC for a texture filled once, as Chapter 24's atlas is. Chapter 33's picture, filled again every frame, is SDL_TEXTUREACCESS_STREAMING. In SDL_PIXELFORMAT_RGBA32, each pixel is four bytes in memory: red, green, blue and alpha. The pitch is the length of a row in bytes, four times the width in pixels. The scale modes are SDL_SCALEMODE_NEAREST and SDL_SCALEMODE_LINEAR, and the address modes SDL_TEXTURE_ADDRESS_CLAMP and SDL_TEXTURE_ADDRESS_WRAP.
Text
SDL_ttf turns a string into pixels, and the skeleton's drawText does the rest:
| Call | What it does | First used |
|---|---|---|
TTF_RenderText_Blended(font, text, 0, color) |
Draws a string onto a new surface, with smooth edges | 1 |
TTF_GetStringSize(font, text, 0, &w, &h) |
Gives the size a string would be, without drawing it | 13 |
The 0 is the string's length, and 0 means that it ends at its null character, as every C++ string's c_str() does.
Small Helpers
SDL also has a few small functions that the demos use for convenience:
| Call | What it does | First used |
|---|---|---|
SDL_min(a, b) |
Gives the smaller of two values | 2 |
SDL_clamp(x, lo, hi) |
Keeps a value between two limits | 4 |
SDL_snprintf(buf, size, format, ...) |
Writes formatted text into a buffer, as snprintf does |
4 |
SDL_max(a, b) |
Gives the larger of two values | 25 |
The SDL_min, SDL_max and SDL_clamp helpers are macros. So each of their arguments may be worked out more than once. That's harmless for the plain values the demos give them, but a call that rolls a random number, given to SDL_min, could roll twice. Pass such a call's result in a variable instead.
