Pascal PCX
Pascal
Download (.zip)
{ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ} {ÄÄÄPCX-file viewer, 256 colors only.ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ} {ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ} {ÄÄÄ( C ) Copyright 1994 By Kimmo Fredriksson.ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ} {ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}
{$A+,B-,D-,E-,F-,G+,I-,L-,N-,O-,P-,Q-,R-,S-,T-,V-,X+}
UNIT PCX;
INTERFACE
PROCEDURE InitPCX( BytesPerRow : Word; ScreenPtr : Pointer ); PROCEDURE LoadPCX( CONST f : STRING; X, Y : Word; PC : Boolean );
IMPLEMENTATION
USES VGAPal, BinFiles, Error, AsmSys;
TYPE BytePtr = ^Byte;
PtrTYPE = RECORD Ofs : Word; Seg : Word; END;
VAR BPR : Word; ScrOfs : Word; ScrSeg : Word; ScrPtr : BytePtr;
CurrPos : BytePtr;
PROCEDURE SetPix( x, y : Word; color : Byte ); BEGIN BytePtr( Ptr( ScrSeg, ScrOfs + y * BPR + x ))^ := color END;
PROCEDURE HorizLine( x0, x1, y : Word; color : Byte ); BEGIN IF x0 > x1 THEN SwapInt( x0, x1 ); FillCharFast( Ptr( ScrSeg, ScrOfs + y * BPR + x0 )^, x1 - x0, color ) END;
{ Load file f, to position X, Y. If PC = TRUE, load the palette too }
PROCEDURE LoadPCX( CONST f : STRING; X, Y : Word; PC : Boolean ); TYPE PCXFile = RECORD CASE Word OF 0 : ( Id0 : Byte; d0 : Word; Id1 : Byte; x0 : Word; y0 : Word; x1 : Word; y1 : Word ); 1 : ( d : ARRAY[ 0..2047 ] OF Byte ) END;
VAR q : FILE; b : PCXFile; BytesRead, pos, w, h, eX, eY, n : Word; cb : Byte;
{ Only 256-color files }
FUNCTION ValidFile : Boolean; BEGIN BlockRead( q, b, 128, BytesRead ); IF ( b.Id0 <> 10 ) OR ( b.Id1 <> 8 ) THEN BEGIN Close( q ); ValidFile := FALSE END ELSE ValidFile := TRUE END;
{ Set the palette registers }
PROCEDURE SetPCXPal; VAR i : Word; BEGIN Seek( q, FileSize( q ) - 3 * 256 - 1 ); BlockRead( q, b, 3 * 256 + 1 ); IF b.Id0 = 12 THEN BEGIN FOR i := 1 TO 3 * 256 + 1 DO b.d[ i ] := b.d[ i ] SHR 2; SetDACs( 0, 256, @b.d[ 1 ] ) END END; { PCX-file is coded as follows:
- If two hi bits in the byte = 0 --> this is the pixel color - If two hi bits in the byte = 1 --> six lo bits is the pixel run length, and next byte is the color of these pixels } BEGIN IF NOT FOpenRead( q, f ) THEN FatalError('Cannot load file ' + f + '!'); IF NOT ValidFile THEN Exit; w := Succ( b.x1 - b.x0 ); { width } h := Succ( b.y1 - b.y0 ); { height } n := 0; { run-length } eX := X + w; { X, Y end points } eY := Y + h; CurrPos := BytePtr( Ptr( ScrSeg, ScrOfs + Y * BPR + X )); REPEAT BlockRead( q, b, 2048, BytesRead ); pos := 0; WHILE ( pos < BytesRead ) AND ( y < eY ) DO BEGIN cb := b.d[ pos ]; IF n <> 0 THEN BEGIN HorizLine( X, X + n, Y, cb ); Inc( Word( CurrPos ), n ); Inc( X, n ); n := 0 END ELSE IF ( cb AND $C0 ) = $C0 THEN n := cb AND $3F ELSE BEGIN { SetPix( X, Y, cb ); } CurrPos^ := cb; Inc( Word( CurrPos )); Inc( X ) END; Inc( pos ); IF X >= eX THEN BEGIN Inc( Word( CurrPos ), BPR - w ); Dec( X, w ); Inc( Y ) END END UNTIL ( BytesRead = 0 ) OR ( Y >= eY ); IF PC THEN SetPCXPal; Close( q ) END;
PROCEDURE InitPCX( BytesPerRow : Word; ScreenPtr : Pointer ); BEGIN BPR := BytesPerRow; ScrPtr := ScreenPtr; ScrOfs := PtrTYPE( ScrPtr ).Ofs; ScrSeg := PtrTYPE( ScrPtr ).Seg; END;
END.
|