Sprites - Erweitert (Vorkenntnisse)


Bevor wir in der nächsten Lektion richtig loslegen, möcht ich euch hier noch ein paar Grundkenntnisse vermitteln, die ihr brauchen werdet. Es gibt auch keine richtigen Beispiele; ihr solltet euch lediglich die Funktionsweisen verinnerlichen.

a) Eigene Funktionen

Bisher bestanden unsere Programme lediglich aus einer Funktion (oder Routine), der _main-Funktion. Wir haben aber auch andere Funktionen, wie z.B. prontf() benutzt, die allerdings bereits in der TIGCC-Bibliothek vorhanden sind. Nun ist es bei größeren Programmen unerlässlich (allein schon der Übersicht wegen), eigene Funktionen zu benutzen. Eine Funktion, die man selbst definiert, ist wie folgt aufgebaut:

[RÜCKGABE-TYP] Funktionsname ([ARGUMENTE]) { [OPERATIONEN] }

Nehmen wir als kleines Beispiel eine Warte-Funktion:

// Dies ist eine übliche Warte-Funktion 
void Wait(short delay) 
{ 
   short t1, t2; 
   randomize(); 
   for (t1 = 0; t1 < delay; t1++) 
      t2 = random(delay); 
}


Als Rückgabetyp ist hier void gegeben, was in etwa so viel bedeutet wie "nichts", es wird also kein Wert zurückgegeben. Das Argument ist vom Typ short und gibt die Wartezeit an. Die Funtionsweise ist einfach: Mit randomize() wird der Zufallsgenerator aktiviert und für die mit delay gegebene Zeit werden einfache Zufallswerte generiert.
Wozu wir dies Funktion brache, wird später noch erklärt.
Auf jeden Fall ist noch wichtig, wie wir die Funktion aufrufen, z.B. so:

Wait(100);


Weiterhin ist zu beachten, dass selbst erstellte Funktionen in der Regel vor der Funktion, aus der sie aufgerufen werden, definiert sein müssen. Einzigste Ausnahme: man definiert vor der Funktion, die sie aufruft z.B. in diesem Fall

void Wait(short delay);


Dann weiss der Compiler, dass die Funktion 'Wait()' folgt und bringt keine ärgerlichen Error-Meldungen.

b) Interrupt-Handler

Im Allgemeinen ist ein Interrupt etwas (mehr oder weniger) Wichtiges, das die CPU ausführt, selbst wenn andere Sachen gerade berechnet oder ausgeführt werden. Er hat also einen höheren Stellenwert als andere, normale Prozesse (vgl. Interrupt = deutsch: Unterbechung).
Ein Handler ist etwas, mit dem Programmierer auf bestimmte Sachen zugreifen kann (das enlische Verb to handle bedeutet soviel wie handhaben).
Mit Hilfe eines Interrupt-Handlers können wir also auf Interrupts zugreifen. Neben Interrupts, die man selbst definieren kann (s. intr.h in der TIGCC-Doc), hat das TIOS auch eigene Interrupts (genannt AUTO-INTs). Auch auf diese können wir zugreifen.

Doch wozu?
Ihr kennt ja die kleinen [2ND]- oder [DIAMOND]-Symbole in der Statusleiste. Die Anzeige dieser Symbole lässt sich durch bestimmte Handhabung des AUTO-INT 1 (der Haupt-CPU-Timer) "deaktivieren". Zudem sollte man, wenn man _rowread-Funktionen benutzt, ebenfalls den AUT-INT 5 (der System-Timer) umleiten.

Das alles macht man wie folgt:

// Die Handler (als Variablen) 
INT_HANLDER saveint1, saveint5; 

// Aktuellen Status der Auto-Interrupts 1 und 5 speichern 
saveint1 = GetIntVec(AUTO_INT_1); 
saveint5 = GetIntVec(AUTO_INT_5); 

// Die Auto-Interrupts werden umgleitet (entspricht deaktivieren) 
SetIntVec(AUTO_INT_1, DUMMY_HANDLER); 
SetIntVec(AUTO_INT_5, DUMMY_HANDLER); 

// Hier kommt das Programm 
/*......*/ 

// Die Auto-Interrupts werden wieder hergestellt 
SetIntVec(AUTO_INT_1, saveint1); 
SetIntVec(AUOT_INT_5, saveint5);


Nun ja, das wars schon wieder. Nächstes Mal werden wir dann unser erstes kleines eigens Spiel programmieren.