home *** CD-ROM | disk | FTP | other *** search
- (* ------------------------------------------------------ *)
- (* LoadPCX.PAS *)
- (* Unit LoadPCX *)
- (* Turbo Pascal ab 5.0 *)
- (* (c) 1990 Gerald Arend, G. Huber & TOOLBOX *)
- (* ------------------------------------------------------ *)
- {$R-,S-,I-,V-,B-,N-,D-,L-}
-
- UNIT LoadPCX;
-
- INTERFACE
-
- USES Graph, Crt;
-
- TYPE
- PCXHeader = RECORD
- Creator : BYTE; { Immer 10 für ZSoft }
- Version : BYTE; { PCX-Version: }
- { 0 = Version 2.5 o. Palette }
- { 2 = Version 2.8 m. Palette }
- { oder Version 3.0 o. Pal.}
- { 3 = Version 2.8/3.0 o. Pal.}
- { 5 = Version 3.0 mit Pal. }
- Encoding : BYTE;
- { 1 = Run-Length-Encoded }
- Bits : BYTE; { Pixel pro Bit }
- xmin, ymin,
- xmax, ymax : INTEGER;
- Hres, VRes : INTEGER;
- Palette : ARRAY[0..15, 0..2] OF BYTE;
- VMode : BYTE; { Reserviert }
- Planes : BYTE; { Farbebenen }
- BytePerLine: INTEGER; { Bytes/Scanzeile }
- PaletteInfo: INTEGER;
- { 1 = Farbe/Schwarz-Weiß }
- { 2 = Grauwerte }
- Dummy : ARRAY[0..57] OF BYTE;
- END;
-
- VAR
- gd, gm: INTEGER;
- Header: PCXHeader;
- Screen: BYTE;
- FileName: STRING;
- CONST
- PCXError: BOOLEAN = FALSE; { Fehler-Flag }
- EGAOnly: BOOLEAN = FALSE; { EGA explizit setzen }
- ClearScreen: BOOLEAN = TRUE; { Soll Screen gelöscht werden? }
-
- { Daten des Headers einlesen }
- PROCEDURE ReadPCXHeader(DateiName: STRING; VAR Header: PCXHeader);
-
- { Palette aus PCX-File setzen - nur EGA und VGA }
- PROCEDURE SetPCXPalette(VAR Header: PCXHeader);
-
- { Bit-Plane für Schreiboperationen setzen }
- PROCEDURE SetWritePlane(Nr : BYTE);
-
- { PCX-Datei entschlüsseln und Screen aufbauen }
- PROCEDURE PCX2Screen(DateiName: STRING; VAR Header: PCXHeader);
-
- { Startet die BGI-Grafik }
- PROCEDURE InitGrafik(XRes, YRes: INTEGER);
-
- { PCX-Datei laden und anzeigen }
- PROCEDURE LoadPCXScreen(DateiName: STRING);
-
- IMPLEMENTATION
-
- PROCEDURE ReadPCXHeader(DateiName: STRING; VAR Header: PCXHeader);
- VAR
- Datei: FILE OF PCXHeader;
- BEGIN
- {$I-}
- Assign(Datei, DateiName);
- Reset(Datei);
- IF IOResult <> 0 THEN
- BEGIN
- WriteLn(^G, 'Die PCX-Datei ', DateiName, ' kann nicht gelesen werden!');
- PCXError:=TRUE;
- Exit;
- END;
- Read(Datei, Header);
- Close(Datei);
- {$I+}
- END;
-
- PROCEDURE SetPCXPalette(VAR Header: PCXHeader);
- VAR
- Color, i, j: BYTE;
- CONST
- Colors: ARRAY[0..2, 0..3] OF BYTE =
- ((0,32,4,36),(0,16,2,18),(0,8,1,9));
- BEGIN
- IF gd IN [EGA, EGA64, VGA] THEN
- FOR i:=0 TO 15 DO
- BEGIN
- IF (gd=EGA) OR EGAOnly THEN { EGA-Palette setzen }
- BEGIN
- Color:=0;
- FOR j:=0 TO 2 DO
- BEGIN
- CASE Header.Palette[i, j] OF
- 0..63: Color:=Color OR Colors[j, 0];
- 64..130: Color:=Color OR Colors[j, 1];
- 131..191: Color:=Color OR Colors[j, 2];
- 192..255: Color:=Color OR Colors[j, 3];
- END;
- END;
- SetPalette(i, Color);
- END
- ELSE { VGA-Palette setzen }
- BEGIN
- SetPalette(i, i);
- WITH Header DO
- SetRGBPalette(i, Palette[i, 0] SHR 2, Palette[i, 1] SHR 2,
- Palette[i, 2] SHR 2);
- END;
- END;
- END;
-
- PROCEDURE SetWritePlane(Nr : BYTE);
- BEGIN
- Port[$3C4] := 2;
- Port[$3C5] := 1 SHL Nr;
- END;
-
- PROCEDURE PCX2Screen(DateiName: STRING; VAR Header: PCXHeader);
- TYPE { PCX-Datei entschlüsseln und Bild aufbauen }
- PlaneType = ARRAY[0..767] OF BYTE;
- CONST
- PufferSize = 8192;
- BlockSize: WORD = PufferSize;
- VAR
- PCXBuf: ARRAY[1..PufferSize] OF BYTE;
- Plane: ARRAY[0..3] OF PlaneType;
- PlaneNr: BYTE;
- Datei: FILE;
- x, y: INTEGER;
- Count, n, j: BYTE;
- P: Pointer;
- Posi: WORD;
-
- FUNCTION GetPCXByte: BYTE; { Nächstes Byte aus PCX-Datei lesen }
- CONST
- Count: BYTE = 0;
- Wert: BYTE = 0;
- P: WORD = PufferSize;
- EndOfFile: BOOLEAN = FALSE;
- VAR
- Temp: BYTE;
-
- PROCEDURE Read_Block;
- VAR
- Result: WORD;
- BEGIN
- IF EoF(Datei) THEN
- EndOfFile := TRUE
- ELSE BEGIN
- BlockRead(Datei, PCXBuf, BlockSize, Result);
- IF Result<BlockSize THEN
- BlockSize := Result;
- P:=1;
- END;
- END;
-
- FUNCTION Get_Byte: BYTE; { Byte aus Datei holen }
- BEGIN
- IF EndOfFile THEN
- Get_Byte := 0
- ELSE
- BEGIN
- IF P=BlockSize THEN { wenn Puffer leer -> neu lesen }
- Read_Block
- ELSE
- Inc(P);
- Get_Byte:=PCXBuf[P];
- END;
- END;
-
- BEGIN
- IF Count>0 THEN
- BEGIN { alten Wert erneut übergeben }
- Dec(Count);
- GetPCXByte:=Wert;
- Exit;
- END;
- Temp := Get_Byte;
- IF Temp AND $C0 = $C0 THEN { Runtime-Encoding }
- BEGIN
- Count:=Temp AND $3F-1;
- Wert:=Get_Byte;
- END
- ELSE
- BEGIN
- Count:=0;
- Wert:=Temp;
- END;
- GetPCXByte:=Wert;
- END;
-
- PROCEDURE BuildPlane(Nr: BYTE); { Bit-Plane aufbauen }
- VAR
- Wert, Count: BYTE;
- n: WORD;
- BEGIN
- FOR n:=0 TO Header.BytePerLine-1 DO
- Plane[Nr][n]:=GetPCXByte;
- END;
-
- BEGIN
- Assign(Datei, DateiName);
- Reset(Datei, 1);
- Seek(Datei, 128);
-
- FOR y := 0 TO Header.ymax-Header.ymin DO BEGIN
- FOR PlaneNr := 0 TO Header.Planes-1 DO
- BuildPlane(PlaneNr);
- CASE Screen OF
- 0 : BEGIN { alle Planes anzeigen: EGA/VGA }
- {$R-}
- P:=Ptr($A000, y*80);
- {$R+}
- FOR j := 0 TO Header.Planes-1 DO BEGIN
- SetWritePlane(j);
- Move(Plane[j], P^, 80);
- END;
- END;
- 1 : BEGIN { nur das erste Plane wird geschrieben: CGA }
- P := Ptr($B000, WORD((y AND 3) SHL 13 + 90 *
- (y SHR 2)));
- Move(Plane[0], P^, 90);
- END;
- 2 : BEGIN { nur das erste Plane wird geschrieben: HGC }
- P := Ptr($B800, WORD((y AND 1) SHL 13 + 80 *
- (y SHR 1)));
- Move(Plane[0], P^, 80);
- END;
- END;
- END;
- Close(Datei);
- PutPixel(0, 0, GetPixel(0, 0)); { nötig für BGI-Treiber }
- END;
-
- PROCEDURE InitGrafik(XRes, YRes: INTEGER); { BGI starten }
- VAR
- Karte: INTEGER;
- Fehler: BOOLEAN;
- BEGIN
- Fehler:=FALSE;
- Karte:=Detect;
- DetectGraph(Karte, gm);
- CASE XRes OF
- 640: CASE YRes OF
- 200: BEGIN
- Fehler:=(Karte=HercMono);
- Case Karte OF
- CGA,
- MCGA,
- EGAMono:BEGIN
- Screen:=1;
- gd:=CGA;
- gm:=CGAHi;
- END;
- EGA,
- EGA64: BEGIN
- Screen:=0;
- gd:=Karte;
- gm:=EGALo;
- END;
- VGA: BEGIN
- Screen:=0;
- gd:=Karte;
- gm:=VGALo;
- END;
- END;
- END;
- 350: BEGIN
- Fehler:=NOT (Karte IN [EGA, EGAMono, VGA]);
- Screen:=0;
- gd:=Karte;
- IF gd=VGA THEN
- gm:=VGAMed
- ELSE
- gm:=EGAHi;
- END;
- 480: BEGIN
- Fehler:=NOT (Karte IN [VGA, MCGA]);
- Screen:=0;
- gd:=VGA;
- gm:=VGAHi;
- END;
- END;
- 320: BEGIN
- Fehler:=(Karte=HercMono);
- Screen:=2;
- gd:=CGA;
- gm:=CGAC0;
- END;
- 720: BEGIN
- Fehler:=(Karte<>HercMono);
- Screen:=1;
- gd:=HercMono;
- gm:=HercMonoHi;
- END;
- END;
- IF Fehler THEN
- BEGIN
- WriteLn(^G, 'Benötigte Grafikkarte nicht vorhanden!');
- PCXError:=TRUE;
- Exit;
- END;
- InitGraph(gd, gm, '');
- IF GraphResult<>0 THEN
- BEGIN
- WriteLn(^G, 'Fehler beim Initialisieren des Grafikpakets!');
- PCXError:=TRUE;
- Exit;
- END;
- END;
-
- PROCEDURE LoadPCXScreen(DateiName: STRING); { PCX-Bild laden }
- BEGIN
- ReadPCXHeader(DateiName, Header);
- IF PCXError THEN
- Exit;
- WITH Header DO
- InitGrafik(Hres, VRes);
- IF PCXError THEN
- Exit;
- SetPCXPalette(Header);
- PCX2Screen(DateiName, Header);
- END;
-
- BEGIN
- END.
- (* ------------------------------------------------------ *)
- (* Ende von LOADPCX.PAS *)