Getting started with C programming - Sample window (with SDL)
-
Certain things like opening a new window, drawing graphics, read mouse input, etc. cannot be done with C alone, they require you to make calls to the operating system. SDL is a library that does those things for you and tries to simplify the process a little bit, but most importantly it works on many different operating systems so you can use the same code for Linux and Windows for example.
If you want to learn how to do things yourself without relying on SDL, click here for a Win32 example.
The program in this page will open a window, draws a rectangle, and responds to mouse and keyboard input to move that rectangle. It will look like this:
This page is for Windows. You can also check the
Linux version.
Setting up SDL
First, download SDL Development Libraries (alternate link). The name should be something like SDL2-devel-X.XX.X-mingw.zip
.
Extract the zip contents. Go to SDL2-X.XX.X/x86_64-w64-mingw32
and move the include
and lib
folders to the same place as your code files, then go to SDL2-X.XX.X/x86_64-w64-mingw32/bin
and move SDL2.dll
into the same place. (More specifically, SDL2.dll will need to be in the same place as your program .exe file after you compile it).
Now we need to tell GCC to link your program with SDL. You can do it by modifying your build file like this:
@ECHO OFF set libaries=-I"include" -L"lib" -lSDL2 gcc main.c %libaries% -o testprogram && ( testprogram )
You could just add paths directly to the SDL2-X.XX.X... folders that came out of the .zip file, however libraries tend to have have an include
folder, and sometimes lib
too. If you add more libraries (which we will do later), it's more convenient to just merge all the lib and include folders instead of adding extra -I
and -L
options for every library. You may need to do it sometimes though,
The program
Copy the below into your main.c file:
#include <stdio.h> #define SDL_MAIN_HANDLED #include <SDL2/SDL.h> // This will include the file from /includes/SDL2/SDL.h // If you want to know more about what some function or type does or how to use it, just search it on a search engine. For example "SDL_CreateWindow" will lead you to a page explaining that function: https://wiki.libsdl.org/SDL2/SDL_CreateWindow void main () { // Initialize SDL. SDL_Init(0); // Create window. SDL_WINDOWPOS_UNDEFINED will let your operating system decide what position to put the window on. SDL_Window* window = SDL_CreateWindow("Test window", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 400, 300, SDL_WINDOW_SHOWN); // Create window surface, you can think of SDL_Surface as a canvas or an image where you can draw pixels. SDL_Surface* windowsurface = SDL_GetWindowSurface(window); // Store some colors into variables to make them easier to use. Uint32 white = SDL_MapRGB(windowsurface->format, 255, 255, 255); Uint32 black = SDL_MapRGB(windowsurface->format, 0, 0, 0); Uint32 gray = SDL_MapRGB(windowsurface->format, 125, 125, 125); // Rectangle position. int x = 0; int y = 0; // Main loop. This is where most of the action happens. while (1) { // Handle input and other events, see the following links for more event types and other information about SDL_Event. // https://wiki.libsdl.org/SDL2/SDL_Event // https://wiki.libsdl.org/SDL2/SDL_EventType SDL_Event event = {0}; while (SDL_PollEvent(&event)) { // There can be all kinds of events, like the window resizing. switch (event.type) { // When mouse is clicked, set rectangle x/y to that position. case SDL_MOUSEBUTTONDOWN: x = event.button.x; y = event.button.y; break; // When arrow keys or WASD are pressed, move the rectangle. case SDL_KEYDOWN: switch (event.key.keysym.sym) { case SDLK_UP: case SDLK_w: y -= 10; break; case SDLK_DOWN: case SDLK_s: y += 10; break; case SDLK_LEFT: case SDLK_a: x -= 10; break; case SDLK_RIGHT: case SDLK_d: x += 10; break; } break; // Program is being closed, so just return out from the main function. case SDL_QUIT: return; } } // Fill the screen with gray (NULL results in a rectangle that fills the entire screen). SDL_FillRect(windowsurface, NULL, gray); // Draw rectangle, use the x and y variables as the position. SDL_Rect rect = { .x=x, .y=y, .w=100, .h=100 }; SDL_FillRect(windowsurface, &rect, white); // Draw the window's surface onto the window. SDL_UpdateWindowSurface(window); // Make the program wait 16 milliseconds before continuing to the next loop iteration (this causes the loop to run at roughly 60 FPS). SDL_Delay(16); } }
And then just compile. Feel free to experiment with this code.