FAU UnivIS
Techn. Fak. Dep. Informatik
Aufgabe 7: Eine Anwendung für OO/MPStuBS (freiwillig)

Lernziel

  • Anwendung von Programmfäden und Semaphoren

Aufgabenbeschreibung

Im Rahmen dieser Aufgabe sollt ihr eine OOStuBS-Anwendung eurer Wahl implementieren. Dabei sollten möglichst mehrere Fäden zum Einsatz kommen, die über Semaphore synchronisiert werden.

Vorgabe

Die Vorgabe enthält einen Zufallszahlengenerator (random.*) und einen einfachen Grafikmodus. Wenn ihr den Grafikmodus verwenden wollt, müsst ihr dazu jedoch noch ein wenig Hand anlegen:

Analog zu CGAScreen benötigt ihr ein globales Objekt der Klasse Guarded_VESAGraphics (sinnigerweise in main.cc) und ruft im Rahmen der Systeminitalisierung in main die Methode Guarded_VESAGraphics::init() auf. Mit Guarded_VESAGraphics::find_mode() könnt ihr nun nach den Kriterien Auflösung und Farbtiefe einen Grafikmodus aussuchen und falls ein valider Modus gefunden wird mit Guarded_VESAGraphics::set_mode() setzen.

#include "syscall/guarded_vesagraphics.h"

char buffer1[1280*1024*4];
char buffer2[1280*1024*4];

Guarded_VESAGraphics vesa(buffer1, buffer2);

...

void main() {
...
    vesa.init();
    VBEModeData_t* mode = vesa.find_mode(1024, 768, 24);
    if (mode != 0) {
        vesa.set_mode(mode);
    }
...
}

Jetzt müsst ihr noch dafür sorgen, dass der Inhalt der Puffer auch in den Speicher der Grafikkarte geschrieben wird. Dazu dient die Methode Guarded_VESAGraphics::scanout_frontbuffer(). Diese ruft ihr entweder als Teil des Zeichenloops auf, immer dann wenn ein neuer Frame fertiggezeichnet wurde, oder führt sie im Watch-Epilog (dort allerdings die Variante ohne Guard) aus, was dafür sorgt, dass der Framebuffer der Grafikkarte mit einer festen Frequenz aktualisiert wird. Wenn ihr die mitgelieferte Beispielapplikation (user/santas_house.h) ohne Modifikationen ausführen wollt, dann müsst ihr zweitere Variante implementieren.

Damit die Systemlast durch den Scanout nicht zu hoch wird, empfielt es sich, den Scanout nicht bei jedem Timerinterrupt durchzuführen, Ca. 40ms sind ein tragbarer Kompromiss zwischen der Bildschirmaktualisierungsfrequenz und dem Overhead durch die vielen Kopiervorgänge. Dabei sollte die Timerfrequenz im Bereich von ca. 10ms belassen, den Scanout, dann aber nur noch jedes zweite oder dritte mal durchführen.

Einbinden von Bitmaps

Wenn man analog zum Beispielprogramm eigene Bitmaps einbinden möchte, so kann man diese mit GIMP einfach als C-Sourcecode (*.c) exportieren. Dabei sollte man keine Glib Typen verwenden. Darüberhinaus muss das Bild mit Alpha-Kanal exportiert werden. In der *.c Datei findet man dann die entsprechenden Binärdaten, welche die Grafikbibliothek darstellen kann.

Durch die Verwendung von Bitmapgraphiken direkt im Sourcecode kann das erzeugte Systemimage jedoch sehr groß werden (allein das mit Optimierungen übersetzte Image der Beispielapplikation mit Grafik ist schon fast 500kb groß!).

Lösungen früherer Jahre

Die Lösungen für Aufgabe 7 aus den Vorjahren findet ihr auf dem Testrechner im CIP-Pool im Netzwerkbootmenü unter 'Aufgabe 7 Beispiele'