^1HOW 2 CODE KEWL FADE EFFECTZ ...written by The Real Adok Im letzten Hugi hab' ich ja beleuchtet, wie Maussteuerung funktioniert und wie sie in C-Programme eingebunden werden kann. Diesmal geht's um was anderes, n„mlich 'nen echt coolen Demo-Effekt: Fadein und Fadeout. Dazu gibt's wie immer ein C-Beispielproggy. Es geht natrlich auch in anderen Prospen, aber das mát ihr selbst machen ;-). So, beginnen wir mal! Viele Demos und auch "ernsthafte" Programme beginnen damit, daá der Bildschirm langsam ausgeblendet und danach der Bildschirm des eigentlichen Programms eingebunden wird. Sieht wirklich cool aus! Doch wie funktioniert das? Fangen wir mal klein an. Jede Farbe im Compi wird aus einem Rot-Anteil, einem Blau-Anteil und einem Grn-Anteil gebildet. Diese Anteile k”nnen von 0 bis 63 reichen. Je h”her der Anteil (die "Intensit„t"), desto mehr rot, blau oder grn ist die Farbe. Einige Beispiele: Sind alle Anteile gleich 0, dann ist die Farbe schwarz. Wenn alle Anteile gleich 63 sind, so ist sie dagegen weiá. Ist nur der Rot-Anteil gleich 63 und alle anderen Anteile 0, ist die Farbe ein helles Rot. Bei weniger als 63 w„re es ein dnkleres Rot. Und dann gibt's noch die Mischfarben: Zum Beispiel ergibt Rot=50, Grn=50 und Blau=0 ein dunkles Gelb. Und so werden alle Farben gebildet! Alles klar? Der Trick beim Fadeout, dem Ausblenden des Bilds, besteht einfach darin, ganz langsam die Anteile der Farben gegen null wandern zu lassen! Nehmen wir einmal als Beispiel die Farbe Weiá (R=63, G= 63, B=63): Wir machen eine Schleife, die von 63 immer um 1 nach 0 wandert und dann den R-, G- und B-Wert von Weiá (also der Farbe 15) auf den Schleifenz„hler setzt. OK, das hat jetzt sicher niemand verstanden, hier also ein Beispiel im Pseudocode: ^0 Z„hlschleife von 63 bis 0, Schrittweite -1, Schleifenz„hler i ^0 { ^0 Setze Rot-Wert von Farbe 15 auf i ^0 Setze Grn-Wert von Farbe 15 auf i ^0 Setze Blau-Wert von Farbe 15 auf i ^0 } Habt ihr's verstanden? Nur: Bei Farbe 15 geht's einfach! Aber wie geht's bei anderen Farben? Gibt's eine universelle Fadeout-Routine? Ja, die gibt's! Und zwar máte sie so aussehen (Pseudocode): ^0 Speichere den ursprnglichen Rot-Wert von Farbe 15 in der Variablen r ^0 Speichere den ursprnglichen Grn-Wert von Farbe 15 in der Variablen g ^0 Speichere den ursprnglichen Blau-Wert von Farbe 15 in der Variablen b ^0 Z„hlschleife von 0 bis 63, Schrittweite +1, Schleifenz„hler i ^0 { ^0 Wenn r minus i gr”áer gleich 0 dann ^0 Setze Rot-Wert von Farbe 15 auf r minus i ^0 Wenn g minus i gr”áer gleich 0 dann ^0 Setze Grn-Wert von Farbe 15 auf g minus i ^0 Wenn b minus i gr”áer gleich 0 dann ^0 Setze Blau-Wert von Farbe 15 auf b minus i ^0 } Die Sicherheitsabfragen (wenn r minus i gr”áer gleich 0 etc.) werden deshalb ben”tigt, damit die Farbwerte nicht mehr ver„ndert werden, wenn sie sowieso schon null sind. Ansonsten g„be es wohl eine unerwartete Fehlermeldung, weil dann die Farbwerte, also r minus i & Co. negativ w„ren. Auáerdem geht die Z„hlschleife in dieser Variante im Gegensatz zur vorigen nicht von 63 bis 0, sondern genau umgekehrt, von 0 bis 63. Das hat einen ganz einfachen Grund: šberlegt mal, was passieren wrde, wenn die Schleife von 63 bis 0 ginge und r gleich 63 w„re. Dann w„re der Rot-Wert der Farbe zuerst 63 minus 63, also 0, dann 63 minus 62, also 1 etc. Hier g„be es einen Fadein, ein Einblenden, statt einem Fadeout! Aber ihr habt recht: So funktioniert das Fadein fr eine Farbe! Genauso wie das Fadeout, nur geht die Schleife eben andersrum. So h„tten wir zwei Fliegen mit einer Klappe gesch... „h, natrlich zwei Menschen mit einem Stock verdroschen (ich bin Tierschtzer!). Weiter mit der Theorie. Nun gut, wir k”nnen eine Farbe ein- und ausblenden. Aber wie geht's mit mehreren Farben? Dazu ben”tigen wir zwei Schleifen: Eine, die die RGB-Werte von 0 bis 63 durchl„uft (wie vorhin), und eine andere, die die Farben von 0 bis 255 durchl„uft und ihre RGB-Werte anpaát (mit jedem Durchlauf der ERSTEN Schleife sollen die RGB-Werte um Eins dnkler werden). Hier ist das ganze im Pseudocode: ^0 Z„hlschleife von 0 bis 63, Schrittweite +1, Schleifenz„hler i ^0 { ^0 Z„hlschleife von 0 bis 255, Schrittweite +1, Schleifenz„hler col ^0 { ^0 Speichere den ursprnglichen Rot-Wert von Farbe col in der Variablen r ^0 Speichere den ursprnglichen Grn-Wert von Farbe col in der Variablen g ^0 Speichere den ursprnglichen Blau-Wert von Farbe col in der Variablen b ^0 Wenn r minus i gr”áer gleich 0 dann ^0 Setze Rot-Wert von Farbe col auf r minus i ^0 Wenn g minus i gr”áer gleich 0 dann ^0 Setze Grn-Wert von Farbe col auf g minus i ^0 Wenn b minus i gr”áer gleich 0 dann ^0 Setze Blau-Wert von Farbe col auf b minus i ^0 } ^0 } Und Fadein geht wieder genauso, nur andersrum (aber nur die erste Schleife)! Yeah, cool, jetzt wissen wir, wie sie gehen, die Fade-Effekte. Aber wir wissen nicht, WIE sie gehen! (Gutes Wortspiel, was?) Wie kann man die RGB-Werte einer Frage abfragen und sie setzen? Das ist das einzige, was uns zur vollst„ndigen Erleuchtung fehlt! Nun, ganz einfach: Wir bedienen uns der E/A-Ports 3C7h, 3C8h und 3C9h. Um die RGB-Werte einer Farbe herauszufinden, mssen wir den Farbcode in 3C7h schreiben. Dann k”nnen wir uns aus dem Port 3C9h nacheinander den R-, den G- und schlieálich den B-Wert abzapfen. (Bei einigen SVGA-Karten geht statt 3C7h auch 3C8h, aber wir wollen ja kompatibel bleiben.) So einfach geht's! Im Pseudocode heiát das: ^0 Setze Port 3C7h auf den Farbcode der gewnschten Farbe ^0 Hole eine Zahl vom Port 3C9h und speichere sie in der Variablen r ^0 Hole eine Zahl vom Port 3C9h und speichere sie in der Variablen g ^0 Hole eine Zahl vom Port 3C9h und speichere sie in der Variablen b Dann ist der Rot-Wert in der Variablen r, der Grn-Wert in g und der Blau-Wert in b. Und um die RGB-Werte eines Farbcodes zu setzen, verfahren wir genauso, nur schreiben wir die RGB-Werte in 3C9h! Also: ^0 Setze Port 3C8h auf den Farbcode der gewnschten Farbe ^0 Setze Port 3C9h auf den Rot-Wert ^0 Setze Port 3C9h auf den Grn-Wert ^0 Setze Port 3C9h auf den Blau-Wert Fertig! Das war's, nicht mehr und auch nicht weniger. Das "Umsetzen" der Farb- palette hat brigens noch einen weiteren praktischen Verwendungszweck: In den VGA-Bildschirmmodi ist normalerweise die Texthintergrundfarbe immer schwarz. Das l„át sich aber sehr leicht „ndern, indem man der Farbe 0 andere RGB-Werte zuweist. Dann ist auch Schwarz auf Weiá und „hnliches m”glich, was doch viel besser fr die Augen ist als umgekehrt! Super, nicht wahr? So, nun noch eine kurze Beschreibung, wozu die Funktionen des Beispielproggys gut sind: ^1- delay: Wartet eine bestimmte Anzahl von Mikrosekunden. Dabei mssen als ^1 Parameter das Hi-Word und das Low-Word dieser Anzahl bergeben werden. In ^1 fast allen F„llen gengt es, das Hi-Word auf null und das Low-Word auf eine ^1 Zahl zwischen 0 und 65535 zu setzen - obwohl auch schon eine Verz”gerung von ^1 20000 Mikrosekunden zum Einschlafen ist! ^1- fadein: Damit wird der Bildschirm eingefadet. Parameter wie bei delay. ^1- fadeincol: Fadet eine einzige Farbe ein. Als Parameter muá der Farbcode an- ^1 gegeben werden, ansonsten wie bei delay. ^1- fadeout: Siehe fadein, nur wird der Bildschirm ausgefadet. ^1- fadeoutcol: Siehe fadeoutcol, nur wird die Farbe ausgefadet. ^1- getpal: Damit wird die Farbpalette in dem Array pal gespeichert. ACHTUNG: ^1 Diese Funktion muá immer am Anfang eines Programms aufgerufen werden, wenn ^1 fadein, fadeincol, fadeout, fadeoutcol, restorecol oder restorepal verwendet ^1 werden sollen! All diese Funktionen beziehen sich n„mlich auf die Werte, die ^1 in dem Array pal gespeichert sind! ^1- restorecol: Setzt eine einzige Farbe auf die Werte, die im Array pal ge- ^1 speichert sind, zurck. Der Farbcode muá als Parameter bergeben werden. ^1- restorepal: Setzt die ganze Farbpalette auf die Werte, die im Array pal ^1 gespeichert sind, zurck. ^1- setpal: Setzt eine Farbe auf die gewnschten RGB-Werte. Als Parameter mssen ^1 logischerweise der Farbcode, der Rot-Wert, der Grn-Wert und der Blau-Wert ^1 bergeben werden. Das ist alles, was ber den Gebrauch der Funktionen zu sagen w„re! Viel Spaá mit den Fade-Effekten! ^4 Euer The Real Adok. ^2______________________________________________________________________________ ^0/* ^0 Palette-Library v1.00 (C) 1996 by The Real Adok of Hugendubelexpress ^0 Diese Library enth„lt einige Funktionen, mit denen man Fadein/Fadeout- ^0 Effekte coden kann! In
ist ein Beispielprogramm, das dies sehr ^0 eindrucksvoll demonstriert. muá brigens nur fr das Bei- ^0 spielprogramm eingebunden werden! ^0*/ ^0#include ^0#include ^0void delay(int hi,int lo); ^0void fadein(int hi,int lo); ^0void fadeincol(char col,int hi,int lo); ^0void fadeout(int hi,int lo); ^0void fadeoutcol(char col,int hi,int lo); ^0void getpal(void); ^0void restorecol(char col); ^0void restorepal(void); ^0void setpal(char col,char r,char g,char b); ^0char pal[768]; ^0void delay(int hi,int lo) ^0{ ^0 _asm ^0 { ^0 mov ax,8600h ^0 mov cx,word ptr hi ^0 mov dx,word ptr lo ^0 int 15h ^0 } ^0} ^0void fadein(int hi,int lo) ^0{ ^0 char r=0, ^0 g=0, ^0 b=0, ^0 i=0; ^0 int col=0; ^0 for(i=63;i>=0;i--) ^0 { ^0 for(col=0;col<=255;col++) ^0 { ^0 if((r=pal[3*col]-i)<0) r=0; ^0 if((g=pal[1+3*col]-i)<0) g=0; ^0 if((b=pal[2+3*col]-i)<0) b=0; ^0 setpal(col,r,g,b); ^0 } ^0 delay(hi,lo); ^0 } ^0} ^0void fadeincol(char col,int hi,int lo) ^0{ ^0 char r=0, ^0 g=0, ^0 b=0, ^0 i=0; ^0 for(i=0;i<=63;i++) ^0 { ^0 if(++r>pal[3*col]) r=pal[3*col]; ^0 if(++g>pal[1+3*col]) g=pal[1+3*col]; ^0 if(++b>pal[2+3*col]) b=pal[2+3*col]; ^0 setpal(col,r,g,b); ^0 delay(hi,lo); ^0 } ^0} ^0void fadeout(int hi,int lo) ^0{ ^0 char r=0, ^0 g=0, ^0 b=0, ^0 i=0; ^0 int col=0; ^0 for(i=0;i<=63;i++) ^0 { ^0 for(col=0;col<=255;col++) ^0 { ^0 if((r=pal[3*col]-i)<0) r=0; ^0 if((g=pal[1+3*col]-i)<0) g=0; ^0 if((b=pal[2+3*col]-i)<0) b=0; ^0 setpal(col,r,g,b); ^0 } ^0 delay(hi,lo); ^0 } ^0} ^0void fadeoutcol(char col,int hi,int lo) ^0{ ^0 char r=pal[3+3*col], ^0 g=pal[1+3*col], ^0 b=pal[2+3*col], ^0 i=0; ^0 for(i=63;i>=0;i--) ^0 { ^0 if(--r<0) r=0; ^0 if(--g<0) g=0; ^0 if(--b<0) b=0; ^0 setpal(col,r,g,b); ^0 delay(hi,lo); ^0 } ^0} ^0void getpal(void) ^0{ ^0 int i=0, ^0 j=0, ^0 k=0; ^0 for(i=0;i<=255;i++) ^0 { ^0 outp(0x3c7,i); ^0 for(k=1;k<=3;k++) ^0 { ^0 pal[j]=inp(0x3c9); ^0 j++; ^0 } ^0 } ^0} ^0void restorecol(char col) ^0{ ^0 setpal(col,pal[3*col],pal[1+3*col],pal[2+3*col]); ^0} ^0void restorepal(void) ^0{ ^0 int i=0; ^0 for(i=0;i<=255;i++) ^0 restorecol((char)i); ^0} ^0void setpal(char col,char r,char g,char b) ^0{ ^0 outp(0x3c8,col); ^0 outp(0x3c9,r); ^0 outp(0x3c9,g); ^0 outp(0x3c9,b); ^0} ^0void main(void) ^0{ ^0 printf("Hallo!"); ^0 getpal(); ^0 fadeout(0,20000); ^0 fadein(0,20000); ^0} ^2______________________________________________________________________________