SDL: Die erste SDL-Anwendung
Aus Wikibooks
[Bearbeiten] Quelltext der ersten SDL-Anwendung
#include <stdlib.h> #include "SDL.h" int main(int argc, char *argv[]) { SDL_Surface *screen; if (SDL_Init(SDL_INIT_VIDEO) == -1) { printf("Can't init SDL: %s\n", SDL_GetError()); exit(1); } atexit(SDL_Quit); screen = SDL_SetVideoMode(640, 480, 16, SDL_HWSURFACE); if (screen == NULL) { printf("Can't set video mode: %s\n", SDL_GetError()); exit(1); } SDL_Delay(3000); SDL_Quit(); return 0; }
[Bearbeiten] Erläuterungen
In den ersten beiden Zeilen werden die benötigten Header eingebunden, SDL.h für die SDL-Funktionen und die stdlib.h für die Funktionen exit und atexit. Eingeleitet wird das Programm durch die main-Funktion, deren Parameter vorerst ignoriert werden dürfen. Danach kommt der erste für uns neue Funktionsaufruf, SDL_Init, welcher zur Initialisierung der SDL dient. Als Parameter werden Flags übergeben, um zu bestimmen, welche Subsysteme von SDL zu initialisieren sind. Durch Verbindung mit dem logischen oder |-Operator können mehrere Flags gleichzeitig angegeben werden.
Mögliche Flags sind:
SDL_INIT_TIMER // Initialisiert Timer-Subsystem SDL_INIT_AUDIO // Initialisiert Audio-Subsystem SDL_INIT_VIDEO // Initialisiert Video-Subsystem SDL_INIT_CDROM // Initialisiert CD-Subsystem SDL_INIT_JOYSTICK // Initialisiert Joystick-Subsystem SDL_INIT_EVERYTHING // Initialisiert alles oben genannte SDL_INIT_NOPARACHUTE // Verhindert, dass die SDL falsche Signale auffängt SDL_INIT_EVENTTHREAD // Lässt den Event-Manager in einem einzelnen Thread laufen
Beispiel:
SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO);
Im obenstehenden Code werden wir nur das Video-Subsystem initialiseren, da wir die anderen noch nicht benötigen. Für die ganz pfiffigen unter euch liefert die SDL auch noch die geniale Funktion SDL_InitSubSystem, die z.b dann zum Einsatz kommt, wenn ein Subsystem erst später in der Anwendung benötigt wird oder in der Laufzeit optional initialisiert werden soll. Ein perfektes Beispiel dafür ist das Subsystem Joystick, denn ob man auf diesen zugreifen will, weiß man meist erst während der Laufzeit, z.B. wenn es im Menü ausgewählt wird (zum vorzeitigen Beenden einzelner Subsysteme gibt es auch die SDL_QuitSubSystem Funktion).
Nun kann es aber mal passieren, dass die Initialisierung fehlschlägt und uns die SDL_Init-Funktion das durch -1 als Rückgabewert mitteilt. Wenn dies der Fall ist lassen wir aus Debug-Gründen eine ausführliche Fehlermeldung in eine Textdatei schreiben. Danach beenden wir das Ganze mit Fehlercode 1.
Wenn jedoch kein Fehler auftrat, sagen wir dem Computer durch die atexit-Funktion, dass er im Falle einer Beendigung des Programmes die Funktion SDL_Quit aufruft, da ja jetzt die SDL initialisiert wurde und somit alles noch von der SDL im Speicher befindliche löscht.
In der nächsten Zeile kommt dann auch schon der erste unbekannte Datentyp: SDL_Surface. Er steht für eine Oberfläche, wobei man sich jetzt schon merken sollte, dass aus Geschwindigkeitsgründen Zeiger verwendet werden (die meisten Funktionen der SDL geben Pointer zurück).
Nun setzen wir den Video-Modus mit der Funktion SDL_SetVideoMode, die als Parameter zuerst Bildschirmbreite, -Höhe, Farbtiefe und Flags übergeben bekommen will. Während die ersten drei Dinge wohl jedem bekannt sein sollten, so ist das 4. auf den ersten Blick etwas Neues. Denn der übergebene Flag unterscheidet sich sehr von den für die SDL_Init-Funktion bekannten Flags, weil es sich bei diesen Flags nicht um solche für die Festlegung der benutzten Subsysteme handelt, sondern um welche für die Eigenschaften des Videomodus. Welche Flags hier möglich sind werde ich im nächsten Kapitel erklären, wer es nicht erwarten kann, sollte sich einfach mal in der Dokumentation umschauen. Aber wie schon an dem Prototyp der SDL_SetVideoMode-Funktion in der Doku zu erkennen ist, gibt diese einen Pointer zurück, der die Adresse der Videooberfläche darstellt. Darum richten wir auch unseren Pointer screen auf dieses SDL_Surface. Nun müssen wir leider wieder eine Fehlerabfrage einbauen, denn es kann schon einmal passieren, dass auf bestimmten Rechnern bestimmte Auflösungen oder Modi einfach nicht funktionieren wollen. Für den Fall das etwas schief gegangen ist gibt die SDL_SetVideoMode-Funktion NULL, also keine Adresse zurück und somit bleibt unser Pointer screen ungerichtet.
Wenn alles gut gegangen ist, dann haben wir jetzt die SDL initialisiert und einen Bildschirmmodus gesetzt und beim Ausführen sollte sich jetzt auch ein Fenster zeigen. Damit dieses jedoch nicht sofort verschwindet rufen wir noch die Funktion SDL_Delay auf, die in unserem Fall die Ausführung der Anwendung auf genau 3000 Milisekunden verzögert.
Anmerkung: Wer unter Windows Probleme beim Kompilieren hat, sollte Folgendes vor der main-Funktion benutzen:
#ifdef _WIN32 #undef main #endif
Wer immer noch Fehlermeldungen bekommt, sollte es hiermit versuchen:
#ifdef _WIN32 #pragma comment(lib, "SDL.lib") #pragma comment(lib, "SDLmain.lib") #endif
Man kompiliert die Datei unter Linux im Terminal wie folgt:
gcc datei.c -o datei `sdl-config --cflags --libs`
Dann muss man sie noch starten:
./datei