Kleine EinfŘhrung in die Dreamcast-Programmierung mit SDL

Aus SEGA-DC.DE

An wen richtet sich diese Anleitung?

Diese Anleitung richtet sich an alle, die grundlegende Kenntnisse in der Programmierung mit C oder C++ haben und ihre Dreamcast-Entwicklungsumgebung bereits konfiguriert haben. Eure Kenntnisse m├╝ssen nicht ├╝berragend sein, es reicht v├Âllig, wenn ihr wisst was Variablen, Klassen, Header, Zeiger und Funktionen sind. In dieser Anleitung lernt ihr, wie man mit Hilfe von SDL f├╝r die Dreamcast-Konsole programmiert.

Fangen wir mit ein paar Headerdateien an:

#include <kos.h>
#include <stdio.h>
#include <SDL.h>
#include <SDL_dreamcast.h>

kos.h ist der Standard-Header von KallistiOS, stdio.h ist eion Header aus der C-Standardbibliothek, SDL.h ist der Header der SDL-Bibliothek und SDL_dreamcast.h enth├Ąlt Dreamcast-spezifische Teile von SDL. Das ganze ist also nichts wirklich neues.

SDL_Surface *screen = NULL;
SDL_Surface *bild= NULL;

Hier deklarieren wir 2 Objekte der Klasse SDL_Surface. SDL_Surface ist eine Klasse aus SDL und kann Bilder und ├ähnliches enthalten. Die gesamte Anzeige des Bildschirms wird auch als ein Objekt gesehen. Auf dieser screen-Variable werdet ihr die Variable "bild" auch sp├Ąter "blitten" - sprich in die screen-Variable laden. Dazu aber sp├Ąter.

Hier erstellen wir eine Funktion, die f├╝r uns sp├Ąter eine Datei "hallo_welt.bmp" ausliest, in das aktuelle Anzeigeformat konvertiert und dann diese in das Objekt "bild" speichert.

SDL_Surface *bild_laden( const char* dateiname)  {
   
   SDL_Surface* BildGeladen = NULL;
   SDL_Surface* optimiertesBild = NULL;

   BildGeladen = SDL_LoadBMP( filename );
    
   if( BildGeladen != NULL ) {

       optimiertesBild = SDL_DisplayFormat( BildGeladen );
       

       SDL_FreeSurface( BildGeladen );
        
   }
    
   return optimiertesBild;
}


Diese Funktion gibt ein SDL_Surface zur├╝ck - was n├Âtig ist, damit das ganze auch in die bild-Variable geladen werden kann. Die ersten zwei Variablen, die wir hier definieren sind nur ein Zwischenspeicher. Richtig interessant wird's erst hier: BildGeladen = SDL_LoadBMP( dateiname );. Hier wird in die weiter oben definierte Variable Bild mit Hilfe der Funktion SDL_LoadBMP ein Bild geladen. dateiname ist hierbei das Argument vom char-Typ, das der Funktion bild_laden am Anfang ├╝bergeben wird. SDL_LoadBMP l├Ądt nur Bitmaps, andere Dateiformate k├Ânnen mit Hilfe einer weiteren Funktion aus einer weiteren Header-Datei der SDL-Bibliothek benutzt werden, allerdings werden wir in dieser kleinen Einf├╝hrung vorerst nicht darauf zu sprechen kommen. In der n├Ąchsten if-Abfrage pr├╝fen wir, ob in BildGeladen erfolgreich ein Bild gespeichert werden konnte. Falls ja wird mit Hilfe von SDL_DisplayFormat das Bild, das momentan in BildGeladen gespeichert ist, in das Format der aktuellen Anzeige umgewandelt und dann in optimiertesBild gespeichert. Sprich: Wenn das Bild ein 24bit-Bitmap ist und das Zielsystem auf 32bit-Aufl├Âsung l├Ąuft, dann erledigt diese Funktion die Umwandlungs-Arbeit f├╝r euch. Mit SDL_FreeSurface( BildGeladen ); l├Âschen wir das alte Objekt, das nun nicht mehr gebraucht wird. Zu guter letzt geben wir das optimierte Objekt als R├╝ckgabewert der Funktion bild_laden mit return optimiertesBild; zur├╝ck. Jetzt ist unsere Funktion einsatzbereit.

Jetzt k├╝mmern wir uns mal um die Hauptunkfunktion:

int main(int narg,char**arg) {

  SDL_Init( SDL_INIT_EVERYTHING );
  screen = SDL_SetVideoMode( 640, 480, 32, SDL_SWSURFACE );
  
  bild = bild_laden("/rd/hallo_welt.bmp");
  
  SDL_Rect offset;
  
   offset.x = 0;
   offset.y = 0;
   
   SDL_BlitSurface( bild, NULL, screen, &offset );
  
  SDL_Flip( screen );
}

Die main()-Funktion wird ganz normal wie auf dem PC aufgerufen. mit SDL_Init( SDL_INIT_EVERYTHING ); initialisieren wir die SDL-Bibliothek und mit screen = SDL_SetVideoMode( 640, 480, 32, SDL_SWSURFACE ); setzten wir den Video-Modus. Die Argumente, die an die Funktion ├╝bergeben werden sind: Breite, H├Âhe, Bit und um das letzte Argument m├╝sst ihr euch vorerst gar nicht k├╝mmern.

Als n├Ąchstes rufen wir unsere oben definierte Funktion auf. SDL_Rect offset ist ein Rechteck, das wir brauchen, um festzulegen, ab welchen Koordinaten sp├Ąter das Bild angezeigt werden soll. Da das ganze ab dem oberen Bildschirmrand angezeigt werden soll, setzen wir die x- und y-Koordinaten auf 0. Mit SDL_BlitSurface( bild, NULL, screen, &offset ); "blitten" wir unser Objekt bild auf das Objekt screen.

SDLTut1.gif

screen beinhaltet also nun unser Objekt bild.

screen ist wie bereits oben gesagt, der gesamte Bildschirm. Das erste Argument von SDL_BlitSurface( bild, NULL, screen, &offset ); ist das Objekt, das in das andere Objekt kopiert bzw "geblittet" werden soll. Das zweite Argument w├╝rde angeben ob nur ein bestimmter Teil des im ersten Argument ├╝bergebenen Bildes kopiert werden soll. Da wir aber das gesamte Objekt kopieren m├Âchten, nehmen wir hier NULL. Das dritte Objekt hier ist das Objekt, in das das erste Objekt kopiert werden soll. Das vierte Argument, vom Typ SDL_Rect, gibt an, an welcher Position das ganze dann angezeigt werden soll. Danach w├Ąre das Objekt screen auch fertig. Doch dann m├╝sst ihr mit SDL_Flip( screen ); noch den Bildschirm "aktualisieren". Dann ist euer Programm fertig und eure Dreamcast-Konsole zeigt ein schmuckes Bild aus der Datei hallo_welt.bmp an! Was ihr in diese Datei malt, bleibt letztendlich euch ├╝berlassen....

Dieses Programm wird sich leider auch nicht selbst beenden, dass hei├čt, wenn ihr genug von eurem Bild habt, dann m├╝sst ihr eure Konsole mit einem Druck auf die Powertaste ausschalten.

Die Datei main.c, k├Ânnt ihr einfach erstellen, in dem ihr den Inhalt der mit "Code" markierten Beispiele einfach in eine Datei kopiert und diese dann main.c nennt.

Das Makefile, das ihr zum Kompilieren ben├Âtigt, ist hier:

TARGET = main

OPTFLAGS=-O3 -fomit-frame-pointer

KOS_CFLAGS+= -I$(KOS_BASE)/../kos-ports/include/SDL-1.2.9 $(OPTFLAGS) 

all: $(TARGET).bin

include $(KOS_BASE)/Makefile.rules

.SRCS   =   main.c \

OBJS = $(.SRCS:.c=.o)

clean:
  rm -f $(OBJS) $(TARGET).elf $(TARGET).bin

$(TARGET).elf: $(OBJS)
  $(KOS_CC) $(KOS_CFLAGS) $(KOS_LDFLAGS) -o $(TARGET).elf $(KOS_START) \
     $(OBJS) -lSDL_129 -lm $(OBJEXTRA) $(KOS_LIBS)

$(TARGET).bin: $(TARGET).elf
  $(KOS_OBJCOPY) -R .stack -O binary $(TARGET).elf $(TARGET).bin

run: $(TARGET).bin
  $(KOS_LOADER) $(TARGET).bin


Die Dateien "Makefile" und "main.c" m├╝ssen irgendwo in eurem Cygwin-Ordner sein. ├ľffnet einfach die Cygwin-Konsole, geht in den Ordner in dem ihr die beiden Dateien abgespeichert habt und gebt "make" ein. Kurz darauf d├╝rftet ihr eine "main.elf"-Datei haben, eine ausf├╝hrbare Dreamcast-Datei!

Abgerufen von ÔÇ×ÔÇť