GrafikProgrammierung in Pascal - Teil 1 Mein erster Beitrag wird eigentlich noch nix mit GrafikEffekten an sich zu tun haben, sondern erstmal mit dem Elementarem der Grafikkarte... Die Grafikkarte stellt einem standardm„áig ein kleines "Fenster" zur Verfgung, in den sie ihren Speicher blockweise einblendet. Das heisst konkret, das man immer nur 64 KB des gesamten Videospeichers ansprechen kann und zwar an der Speicheradresse $a000:0. Bei Grafikmodi wie dem Mode $13 (320x200,256 Farben) kein Problem, da er ja nur 64000 Bytes ben”tigt. Deswegen werden wir vorerst bei diesem VGA-Modus bleiben, um uns nicht gleich zu Anfang mit dem VESA-Bios, das leicht h”here Aufl”sungen erm”glichen kann, herumschlagen zu mssen. Die Initialisierung von Grafikmodi geschieht immer ber den Interrupt $10, wobei wir bei Standard-VGA-Modi im AX-Register den gewnschten Modus bergeben. Wer jetzt schon nerv”s wird, weil er mit Interrupts und CPU-Registern nix anfangen kann, soll halt versuchen den Rest zu kapieren, da zu einem sp„teren Zeitpunkt die fertigen Routinen vorliegen und man sich nicht weiter darum zu kmmern braucht, wie sie genau funktionieren. PROCEDURE InitVGAMode(mode : word); Var regs : trealregs; BEGIN regs.ax:=mode; Realintr($10,regs); END; Will man nun mal ein bisschen mit besagtem Mode $13 herumexperimentieren, z.B. Pixel setzen, mssen wir auf den Speicherbereich $a000:0 zugreifen. Jetzt wirds leider schon etwas verworren: Da ich ausdrcklich nur den FPK-Pascal Compiler explizit untersttzen werde, sollten Programmier-Anf„nger sich diesen zun„chst besorgen. Dieser Compiler wird uns unsere Arbeit n„mlich sehr erleichtern. Den Fortgeschrittenen drfte es kein Problem bereiten, meine Ans„tze in sonstigen Compilern umzusetzen. Also weiter: Wir schaffen uns zun„chst einen Speicherbereich, in dem wir alle Grafikoperationen durchfhren. Nach getaner Arbeit kopieren wir dann alles auf einen Rutsch zur Grafikkarte. (Auch Double-Buffering genannt) USES Go32; VAR VideoBuffer : pointer; BEGIN getmem(videobuffer,64000); initvgamode($13); { 320x200,256 } pixel(videobuffer,160,100,1); { PIXEL IN BUFFER SETZEN } dosmemput($a000,0,videobuffer^,64000); { BUFFER AN $a000:0 KOPIEREN } readln; initvgamode($3); { TEXTMODUS } freemem(videobuffer,64000); END. Jetzt fehlt uns nur noch die Pixel-Routine. Da der Bildschirm 320 Pixel breit ist, berechnen wir den Speicherbereich nach folgender "Formel": adr = x+y*320 Auáerdem sollten wir berprfen, ob man diesen Punkt berhaupt sehen kann, d.h. ob er innerhalb des sichtbaren Videobereichs liegt. Setzt man n„mlich einen Punkt z.B. an Position 400,400 h„tte dies eine Fehlermeldung zur Folge: wir h„tten dann den Speicherbereich verlassen und in (uns) fremde Bereiche hineingeschrieben. PROCEDURE Pixel(destiny : pointer; x,y : longint; color : byte); BEGIN if (x<0) or (x>319) or (y<0) or (y>199) then exit; ASM mov edi,destiny add edi,x { In unserem Videobuffer um x-Bytes weiter } mov eax,320 imul y { Und um y*320 Bytes weiter } add edi,eax mov al,color mov [edi],al { Pixel setzen } END; END; Leider l„át sich (zumindest am Anfang unseres Kurses) Assembler bei der Grafikprogrammierung nicht vermeiden. Es geht auch nicht darum ASM zu lernen, sondern die Grundprinzipien dieser ASM-Routinen zu verstehen. Comin' Up : Linien, Kreise, etc. Also bis n„chstes Mal... Carsten aka Toxic Avenger/Ainc.