home *** CD-ROM | disk | FTP | other *** search
- (* ------------------------------------------------------ *)
- (* HI_RES.PAS *)
- (* Schnelle Grafiken für 16 Bit VGA mit Trident-Chips *)
- (* (c) 1992,93 Arno Bücken & DMV-Verlag *)
- (* ------------------------------------------------------ *)
- UNIT Hi_Res;
-
- INTERFACE
-
- VAR
- GraphicError : BYTE;
-
- PROCEDURE GraphMode;
- PROCEDURE TextModus;
- PROCEDURE PutPixel(x, y, c : WORD);
- PROCEDURE Line(x, y, x2, y2, c : INTEGER);
- PROCEDURE Circle(xm, ym, r, c : INTEGER);
- PROCEDURE Ellipse(xm, ym, rx, ry, c : INTEGER);
- PROCEDURE Quad(x1, y1, x2, y2, c1, c2 : INTEGER);
- PROCEDURE Rec(x1, y1, x2, y2, c : INTEGER);
- PROCEDURE Paint(x, y, c : WORD);
- PROCEDURE PrintScreen;
- { PROCEDURE PrintScreen9; --> vgl. Listing 2 }
- PROCEDURE SetColorToPrint(b : BYTE);
- PROCEDURE ClearColorToPrint(b : BYTE);
- PROCEDURE hLine(x1, x2, y, c : WORD);
- PROCEDURE WrChar(ch : CHAR; c : WORD);
- PROCEDURE SetPos(x, y : WORD);
- PROCEDURE WrStr(VAR Str; c : WORD);
- PROCEDURE SavePalette;
- PROCEDURE RestorePalette;
- PROCEDURE SetColor(n, r, g, b : BYTE);
- FUNCTION GetPixel(x, y : WORD) : WORD;
-
- IMPLEMENTATION
-
- USES Printer, Dos;
-
- TYPE
- PixelP = ^Pixel;
- Pixel = RECORD
- x, y : WORD;
- Next : PixelP;
- END;
-
- CONST
- Index = $03ce;
- Daten = $03cf;
- br : ARRAY [0..7] OF BYTE = (128, 64, 32, 16, 8, 4, 2, 1);
-
- VAR
- Regs : Registers;
- Modus : BYTE;
- i : WORD;
- Drucken : ARRAY [0..16] OF BYTE;
- Palette : ARRAY [0..16] OF BYTE;
- Color : ARRAY [0..48] OF BYTE;
-
- PROCEDURE GraphMode;
- BEGIN
- Regs.ah := $0F;
- Intr($10, Regs);
- Modus := Regs.al;
- Regs.al := $00;
- Regs.ah := $1a;
- Intr($10, Regs);
- IF (Regs.al <> $1A) OR (Regs.bl <> 8) THEN BEGIN
- GraphicError := 1;
- Exit;
- END ELSE BEGIN
- Regs.ah := 0;
- Regs.al := $5F;
- Intr($10, Regs);
- END;
- END;
-
- PROCEDURE TextModus;
- BEGIN
- Regs.ah := 0;
- Regs.al := Modus;
- Intr($10, Regs);
- END;
-
- PROCEDURE PutPixel(x, y, c : WORD);
- VAR
- a, AdrA : BYTE;
- AdrB, Seg : WORD;
- BEGIN
- IF (c < 0) OR (c > 15) THEN BEGIN
- GraphicError := 2;
- Exit;
- END;
- IF (x < 0) OR (y < 0) OR (x > 1023) OR
- (y>767) THEN BEGIN
- GraphicError := 3;
- Exit;
- END;
- AdrA := x MOD 8;
- AdrB := x DIV 8;
- Seg := $A000+y * 8;
- a := Mem[Seg:AdrB];
- Port[Index] := 1;
- Port[Daten] := $0F;
- Port[Index] := 8;
- Port[Daten] := Br[AdrA];
- Port[Index] := 0;
- Port[Daten] := c;
- Mem[Seg:AdrB] := a;
- Port[Index] := 1;
- Port[Daten] := 0;
- Port[Index] := 8;
- Port[Daten] := 0;
- END;
-
- FUNCTION GetPixel(x, y : WORD) : WORD;
- VAR
- AdrB : WORD;
- AdrA : BYTE;
- a, b, c, d : BYTE;
- Seg, g : WORD;
- BEGIN
- IF (x < 0) OR (x > 1023) OR (y < 0) OR
- (y > 767) THEN BEGIN
- GraphicError := 3;
- Exit;
- END;
- AdrA := x MOD 8;
- AdrB := x DIV 8;
- seg := $A000+y * 8;
- a := Mem[Seg:AdrB];
- Port[Index] := 4;
- Port[Daten] := 1;
- b := Mem[Seg:AdrB];
- Port[Daten] := 2;
- c := Mem[Seg:AdrB];
- Port[Daten] := 3;
- d := Mem[Seg:AdrB];
- Port[Daten] := 0;
- g := 0;
- IF (a AND Br[AdrA]) <> 0 THEN Inc(g, 1);
- IF (b AND Br[AdrA]) <> 0 THEN Inc(g, 2);
- IF (c AND Br[AdrA]) <> 0 THEN Inc(g, 4);
- IF (d AND Br[AdrA]) <> 0 THEN Inc(g, 8);
- GetPixel := g;
- END;
-
- PROCEDURE hLine(x1, x2, y, c : WORD);
- VAR
- Seg, Counter, AdrA, AdrB : WORD;
- BEGIN
- WHILE (x1 < x2) AND (x1 MOD 8 <> 0) DO BEGIN
- PutPixel(x1, y, c);
- Inc(x1);
- END;
- WHILE (x2 > x1) AND (x2 MOD 8 <> 7) DO BEGIN
- PutPixel(x2, y, c);
- Dec(x2);
- END;
- IF x1 = x2 THEN Exit;
- Port[Index] := 1;
- Port[Daten] := $0F;
- Port[Index] := 8;
- Port[Daten] := 255;
- Port[Index] := 0;
- Port[Daten] := c;
- Seg := $A000+y * 8;
- AdrA := x1 DIV 8;
- AdrB := x2 DIV 8;
- FOR Counter := AdrA TO AdrB DO
- Mem[Seg:Counter] := 255;
- Port[Index] := 1;
- Port[Daten] := 0;
- Port[Index] := 8;
- Port[Daten] := 0;
- END;
-
- FUNCTION Sgn(i : INTEGER) : INTEGER;
- BEGIN
- IF i = 0 THEN
- Sgn := 0
- ELSE IF i < 0 THEN
- Sgn := -1
- ELSE Sgn := 1;
- END;
-
- PROCEDURE Line(x, y, x2, y2 : INTEGER; c : INTEGER);
- VAR
- i1, i2, i, d, s1, s2, dx, dy : INTEGER;
- t : BOOLEAN;
- BEGIN
- dx := Abs(x2-x);
- dy := Abs(y2-y);
- s1 := Sgn(x2-x);
- s2 := Sgn(y2-y);
- IF dx < dy THEN BEGIN
- d := dx;
- dx := dy;
- dy := d;
- t := TRUE;
- END ELSE
- t := FALSE;
- d := 2 * dy-dx;
- i1 := 2 * dy;
- i2 := 2 * dx;
- FOR i := 1 TO dx DO BEGIN
- PutPixel(x, y, c);
- IF d >= 0 THEN BEGIN
- IF t THEN Inc(x, s1) ELSE Inc(y, s2);
- Dec(d,i2);
- END;
- IF t THEN Inc(y, s2) ELSE Inc (x, s1);
- Inc(d, i1);
- END;
- END;
-
- PROCEDURE Circle(xm, ym, r : INTEGER; c : INTEGER);
- VAR
- x, y, d : INTEGER;
- BEGIN
- x := 0;
- y := r;
- d := r-1;
- REPEAT
- IF d < 0 THEN BEGIN
- Dec(y);
- Inc(d, y);
- Inc(d, y);
- END;
- PutPixel(xm+x, ym+y, c);
- PutPixel(xm-x, ym+y, c);
- PutPixel(xm+x, ym-y, c);
- PutPixel(xm-x, ym-y, c);
- PutPixel(xm+y, ym+x, c);
- PutPixel(xm-y, ym+x, c);
- PutPixel(xm+y, ym-x, c);
- PutPixel(xm-y, ym-x, c);
- Dec(d,x);
- Dec(d,x);
- Dec(d);
- Inc(x);
- UNTIL y < x;
- END;
-
- PROCEDURE Ellipse(xm, ym, rx, ry, c : INTEGER);
- VAR
- r, x, y, d : INTEGER;
- fx, fy : REAL;
- BEGIN
- IF rx = ry THEN BEGIN
- Circle(xm, ym, rx, c);
- Exit;
- END;
- IF rx > ry THEN BEGIN
- r := rx;
- fx := 1.0;
- fy := ry/rx;
- END ELSE BEGIN
- r := ry;
- fy := 1.0;
- fx := rx/ry;
- END;
- x := 0;
- y := r;
- d := r-1;
- REPEAT
- IF d < 0 THEN BEGIN
- Dec(y);
- Inc(d, y);
- Inc(d, y);
- END;
- PutPixel(Round(xm+fx*x), Round(ym+fy*y), c);
- PutPixel(Round(xm-fx*x), Round(ym+fy*y), c);
- PutPixel(Round(xm+fx*x), Round(ym-fy*y), c);
- PutPixel(Round(xm-fx*x), Round(ym-fy*y), c);
- PutPixel(Round(xm+fx*y), Round(ym+fy*x), c);
- PutPixel(Round(xm-fx*y), Round(ym+fy*x), c);
- PutPixel(Round(xm+fx*y), Round(ym-fy*x), c);
- PutPixel(Round(xm-fx*y), Round(ym-fy*x), c);
- Dec(d, x);
- Dec(d, x);
- Dec(d);
- Inc(x);
- UNTIL y < x;
- END;
-
- PROCEDURE Quad(x1, y1, x2, y2, c1, c2 : INTEGER);
- VAR
- Counter : INTEGER;
- BEGIN
- IF Abs(x1-x2) = 1 THEN BEGIN
- Rec(x1, y1, x2, y2, c1);
- Exit;
- END;
- hLine(x1, x2, y1, c1);
- hLine(x1, x2, y2, c1);
- FOR Counter := y1 TO y2 DO BEGIN
- PutPixel(x1, Counter, c1);
- PutPixel(x2, Counter, c1);
- END;
- FOR Counter := y1+1 TO y2-1 DO
- hLine(x1+1, x1-1, Counter, c2);
- END;
-
- PROCEDURE Rec(x1, y1, x2, y2, c : INTEGER);
- VAR
- i : INTEGER;
- BEGIN
- hLine(x1, x2, y1, c);
- hLine(x1, x2, y2, c);
- FOR i := y1 TO y2 DO BEGIN
- PutPixel(x1, i, c);
- PutPixel(x2, i, c);
- END;
- END;
-
- PROCEDURE Paint(x, y, c : WORD);
- VAR
- p, p2 : PixelP;
- DownFlag, UpFlag, Flag : BOOLEAN;
- xMin, xMax : WORD;
-
- PROCEDURE Heap(hx, hy : WORD);
- VAR
- pi : PixelP;
- BEGIN
- IF Maxavail < 8 THEN Exit;
- New(Pi);
- pi^.x := hx;
- pi^.y := hy;
- pi^.Next := p^.Next;
- p^.Next := pi;
- END;
-
- FUNCTION SearchLeft(x, y : WORD) : WORD;
- BEGIN
- IF GetPixel(x, y) = c THEN BEGIN
- SearchLeft := x;
- Exit;
- END;
- DownFlag := (GetPixel(x, y+1) = c);
- UpFlag := (GetPixel(x, y-1) = c);
- Dec(x);
- WHILE (GetPixel(x, y) <> c) AND (GraphicError <> 3) DO BEGIN
- Flag := (GetPixel(x, y+1) = c);
- IF Flag <> DownFlag THEN BEGIN
- DownFlag := Flag;
- Heap(x, y+1);
- END;
- Flag := (GetPixel(x, y-1) = c);
- IF Flag <> UpFlag THEN BEGIN
- UpFlag := Flag;
- Heap(x, y-1);
- END;
- Dec(x);
- END;
- Inc(x);
- GraphicError := 0;
- SearchLeft := x;
- END;
-
- FUNCTION SearchRight(x, y : WORD) : WORD;
- BEGIN
- IF GetPixel(x, y) = c THEN BEGIN
- SearchRight := x;
- Exit;
- END;
- DownFlag := (GetPixel(x, y+1) = c);
- IF NOT DownFlag THEN Heap(x, y+1);
- UpFlag := (GetPixel(x, y-1) = c);
- IF NOT UpFlag THEN Heap(x, y-1);
- Inc(x);
- WHILE (GetPixel(x, y) <> c) AND (GraphicError <> 3) DO BEGIN
- Flag := (GetPixel(x, y+1) = c);
- IF Flag <> DownFlag THEN BEGIN
- DownFlag := Flag;
- Heap(x, y+1);
- END;
- Flag := (GetPixel(x, y-1) = c);
- IF Flag <> UpFlag THEN BEGIN
- UpFlag := Flag;
- Heap(x, y-1);
- END;
- Inc(x);
- END;
- Dec(x);
- GraphicError := 0;
- SearchRight := x;
- END;
-
- BEGIN
- New(p);
- p^.x := x;
- p^.y := y;
- p^.next := NIL;
- WHILE p <> NIL DO BEGIN
- p2 := p;
- x := p^.x;
- y := p^.y;
- xmin := SearchLeft(x, y);
- xmax := SearchRight(x, y);
- hLine(xMin, xMax, y, c);
- p := p^.Next;
- Dispose(p2);
- END;
- END;
-
- PROCEDURE PrintScreen;
- CONST
- Line = 45;
- VAR
- x, y : WORD;
- a, b, c : BYTE;
-
- PROCEDURE MakeByte(x, y : WORD; VAR a, b, c : BYTE);
- BEGIN
- a := 0; b := 0; c := 0;
- Inc(a, Drucken[GetPixel(x, y )] * 128);
- Inc(a, Drucken[GetPixel(x, y+ 2)] * 64);
- Inc(a, Drucken[GetPixel(x, y+ 4)] * 32);
- Inc(a, Drucken[GetPixel(x, y+ 6)] * 16);
- Inc(a, Drucken[GetPixel(x, y+ 8)] * 8);
- Inc(a, Drucken[GetPixel(x, y+10)] * 4);
- Inc(a, Drucken[GetPixel(x, y+12)] * 2);
- Inc(a, Drucken[GetPixel(x, y+14)]);
- Inc(b, Drucken[GetPixel(x, y+16)] * 128);
- Inc(b, Drucken[GetPixel(x, y+18)] * 64);
- Inc(b, Drucken[GetPixel(x, y+20)] * 32);
- Inc(b, Drucken[GetPixel(x, y+22)] * 16);
- Inc(b, Drucken[GetPixel(x, y+24)] * 8);
- Inc(b, Drucken[GetPixel(x, y+26)] * 4);
- Inc(b, Drucken[GetPixel(x, y+28)] * 2);
- Inc(b, Drucken[GetPixel(x, y+30)]);
- Inc(c, Drucken[GetPixel(x, y+32)] * 128);
- Inc(c, Drucken[GetPixel(x, y+34)] * 64);
- Inc(c, Drucken[GetPixel(x, y+36)] * 32);
- Inc(c, Drucken[GetPixel(x, y+38)] * 16);
- Inc(c, Drucken[GetPixel(x, y+40)] * 8);
- Inc(c, Drucken[GetPixel(x, y+42)] * 4);
- Inc(c, Drucken[GetPixel(x, y+44)] * 2);
- Inc(c, Drucken[GetPixel(x, y+46)]);
- END;
-
- BEGIN
- {$I-}
- y := 0;
- Write(LST, #0);
- IF IoReSult <> 0 THEN BEGIN
- GraphicError := 4;
- Exit;
- END;
- WHILE y < 768 DO BEGIN
- Write(LST, #28, #90, #0, #4);
- FOR x := 0 TO 1023 DO BEGIN
- MakeByte(x, y, a, b, c);
- Write(LST, Chr(a), Chr(b), Chr(c));
- END;
- Write(LST, #28, #51, #1, #13, #10);
- Write(LST, #28, #90, #0, #4);
- FOR x := 0 TO 1023 DO BEGIN
- MakeByte(x, y+1, a, b, c);
- Write(LST, Chr(a), Chr(b), Chr(c));
- END;
- Write(LST, #28, #51,Chr(Line), #13, #10);
- Inc(y, 48);
- END;
- {$I+}
- END;
-
- PROCEDURE SetColorToPrint(b : BYTE);
- BEGIN
- IF (b < 0) OR (b > 15) THEN BEGIN
- GraphicError:=5;
- Exit;
- END;
- Drucken[b] := 1;
- END;
-
- PROCEDURE ClearColorToPrint(b : BYTE);
- BEGIN
- IF (b < 0) OR (b > 15) THEN BEGIN
- GraphicError := 5;
- Exit;
- END;
- Drucken[b] := 0;
- END;
-
- PROCEDURE WrChar(ch : CHAR; c : WORD);
- BEGIN
- Regs.ah := 14;
- Regs.al := Ord(ch);
- Regs.bx := c;
- Intr($10, Regs);
- END;
-
- PROCEDURE SetPos(x, y : WORD);
- BEGIN
- Regs.ah := 2;
- Regs.dl := x;
- Regs.dh := y;
- Intr($10, Regs);
- END;
-
- PROCEDURE WrStr(VAR Str; c : WORD);
- VAR
- st2 : STRING [255] ABSOLUTE Str;
- Counter : BYTE;
- BEGIN
- FOR Counter := 1 TO Ord(st2[0]) DO
- WrChar(st2[i], c);
- END;
-
- PROCEDURE SavePalette;
- BEGIN
- Regs.ax := $1009;
- Regs.dx := Ofs(Palette);
- Regs.es := Seg(Palette);
- Intr($10, Regs);
- Regs.ax := $1017;
- Regs.cx := 16; { Anzahl Register}
- Regs.bx := 0; { Register 0 als erstes}
- Regs.dx := Ofs(Color);
- Regs.es := Seg(Color);
- END;
-
- PROCEDURE RestorePalette;
- BEGIN
- Regs.ax := $1002;
- Regs.dx := Ofs(Palette);
- Regs.es := Seg(Palette);
- Intr($10, Regs);
- Regs.ax := $1012;
- Regs.cx := 16;
- Regs.bx := 0;
- Regs.dx := Ofs(Color);
- Regs.es := Seg(Color);
- Intr($10, Regs);
- END;
-
- PROCEDURE SetColor(n, r, g, b : BYTE);
- BEGIN
- Regs.ax := $1000;
- Regs.bl := n;
- Regs.bh := n;
- Intr($10, Regs);
- Regs.ax := $1010;
- Regs.bx := n;
- Regs.dh := r;
- Regs.ch := g;
- Regs.cl := b;
- Intr($10, Regs);
- END;
-
- BEGIN
- GraphicError := 0;
- Drucken[0] := 0;
- FOR i := 1 TO 15 DO Drucken[i] := 1;
- END.
- (* ------------------------------------------------------ *)
- (* Ende von HI_RES.PAS *)