home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
DP Tool Club 16
/
CD_ASCQ_16_0994.iso
/
news
/
573
/
3dlab101
/
vgawin.pas
< prev
next >
Wrap
Pascal/Delphi Source File
|
1994-05-26
|
17KB
|
464 lines
{────────────────────────────────────────────────────────────────────────────}
{───( C ) Copyright 1994 By Kimmo Fredriksson.───────────────────────────────}
{────────────────────────────────────────────────────────────────────────────}
{───You may use this unit freely in your programs, and distribute them,──────}
{───but you are *NOT* allowed to distribute any modified form of this────────}
{───unit, not source, nor the compiled TPU, TPP or whatsoever, *without*─────}
{───my permission! In it's original form, this source is freeware.───────────}
{────────────────────────────────────────────────────────────────────────────}
{───Internet email: Kimmo.Fredriksson@Helsinki.FI────────────────────────────}
{────────────────────────────────────────────────────────────────────────────}
{
╔═════════════════════════════════════════════════════════════════════════╗
║ VGAWin ║
╠═════════════════════════════════════════════════════════════════════════╣
║ ║
║ (C) Copyright 1994 by Kimmo Fredriksson. ║
║ ║
╠═════════════════════════════════════════════════════════════════════════╣
║ Simple windowing routines for VGA 320x200x256 mode ║
╚═════════════════════════════════════════════════════════════════════════╝
}
{$A+,B-,D-,E-,F-,G+,I-,L-,N-,O-,P+,Q-,R-,S-,T-,V-,X+}
UNIT VGAWin;
(*****************************************************************************)
INTERFACE
(*****************************************************************************)
CONST SingleFr = 0; { frame types }
DoubleFr = 1;
Block1Fr = 2;
Block2Fr = 3;
Block3Fr = 4;
Block4Fr = 5;
Shadow : Boolean = TRUE; { Shaded text ? }
PROCEDURE InitVGAWin;
PROCEDURE WriteAT ( X, Y, C : Byte; CONST St : STRING );
PROCEDURE WriteWin ( X, Y : Word; C : Byte; CONST St : STRING );
FUNCTION OpenWin ( X1, Y1, X2, Y2 : Word; BackC, BordC, FrS : Byte ) : Boolean;
FUNCTION OpenWinCenter( WinSizeX, WinSizeY : Word; BaC, BoC, Fr : Byte ) : Boolean;
PROCEDURE CloseWin;
PROCEDURE CloseAllWins;
PROCEDURE ClrWin ( C : Byte );
PROCEDURE GetFonts;
PROCEDURE MakeItalics;
(*****************************************************************************)
IMPLEMENTATION
(*****************************************************************************)
USES AsmSys;
CONST WinInd : Word = 0; { front-window's index }
ClipOn : Boolean = TRUE; { clip the text ? }
MaxWins = 9;
TYPE FontType = ARRAY[ 0..7 ] OF Byte; { 8*8 bits / font }
FontsType = ARRAY[ 0..255 ] OF FontType; { 256 ASCII codes }
FrameType = RECORD
UpL : Char;
UpR : Char;
LoL : Char;
LoR : Char;
Ver : Char;
Hor : Char;
END;
CONST FrCh : ARRAY[ 0..5 ] OF FrameType = (
( UpL : '┌'; UpR : '┐'; LoL : '└'; LoR : '┘'; Ver : '│'; Hor : '─' ),
( UpL : '╔'; UpR : '╗'; LoL : '╚'; LoR : '╝'; Ver : '║'; Hor : '═' ),
( UpL : '░'; UpR : '░'; LoL : '░'; LoR : '░'; Ver : '░'; Hor : '░' ),
( UpL : '▒'; UpR : '▒'; LoL : '▒'; LoR : '▒'; Ver : '▒'; Hor : '▒' ),
( UpL : '▓'; UpR : '▓'; LoL : '▓'; LoR : '▓'; Ver : '▓'; Hor : '▓' ),
( UpL : '█'; UpR : '█'; LoL : '█'; LoR : '█'; Ver : '█'; Hor : '█' ));
TYPE WinType = RECORD
WX1 : Word;
WY1 : Word;
WX2 : Word;
WY2 : Word;
SX1 : Word;
SX2 : Word;
SY1 : Word;
SY2 : Word;
BaC : Word;
BoC : Word;
FrStyle : Word;
ScrOfs : Word;
BuffSize : Word;
Buff : Pointer;
END;
VAR FontBuff : FontsType;
FontPtr : ^FontsType;
WinDef : ARRAY[ 1..MaxWins ] OF WinType;
{
╔═════════════════════════════════════════════════════════════════════════╗
║ PROCEDURE InitVGAWin ║
╚═════════════════════════════════════════════════════════════════════════╝
}
PROCEDURE InitVGAWin;
BEGIN
END;
{
╔═════════════════════════════════════════════════════════════════════════╗
║ FUNCTION GetFontPtr ║
╟─────────────────────────────────────────────────────────────────────────╢
║ Output : Pointer to BIOS font-buffer ║
╚═════════════════════════════════════════════════════════════════════════╝
}
FUNCTION GetFontPtr : Pointer; ASSEMBLER;
ASM
PUSH BP
MOV AX,1130h
MOV BH,03h
INT 10h
MOV DX,ES
MOV AX,BP
POP BP
END;
{
╔═════════════════════════════════════════════════════════════════════════╗
║ PROCEDURE GetFonts ║
╟─────────────────────────────────────────────────────────────────────────╢
║ Copy BIOS fonts to FontBuff buffer ║
╚═════════════════════════════════════════════════════════════════════════╝
}
PROCEDURE GetFonts;
BEGIN
Move( GetFontPtr^, FontBuff, SizeOf( FontBuff ))
END;
{
╔═════════════════════════════════════════════════════════════════════════╗
║ PROCEDURE MakeItalics ║
╟─────────────────────────────────────────────────────────────────────────╢
║ Change the ASCII codes between 32-127 to italics ║
╚═════════════════════════════════════════════════════════════════════════╝
}
PROCEDURE MakeItalics;
VAR i : Word;
BEGIN
FOR i := 32 TO 127 DO
BEGIN
FontBuff[ i ][ 0 ] := FontBuff[ i ][ 0 ] SHR 3;
FontBuff[ i ][ 1 ] := FontBuff[ i ][ 1 ] SHR 2;
FontBuff[ i ][ 2 ] := FontBuff[ i ][ 2 ] SHR 1;
FontBuff[ i ][ 5 ] := FontBuff[ i ][ 5 ] SHL 1;
FontBuff[ i ][ 6 ] := FontBuff[ i ][ 6 ] SHL 2;
FontBuff[ i ][ 7 ] := FontBuff[ i ][ 7 ] SHL 3
END
END;
{
╔═════════════════════════════════════════════════════════════════════════╗
║ PROCEDURE PutVGACh ║
╟─────────────────────────────────────────────────────────────────────────╢
║ Input : Font, screen offset and font color ║
╟─────────────────────────────────────────────────────────────────────────╢
║ Copy font to video memory to desired position ║
╚═════════════════════════════════════════════════════════════════════════╝
}
PROCEDURE PutVGAChr( VAR Font : FontType; ScrOfs : Word; C : Byte ); ASSEMBLER;
ASM
PUSH DS
LDS SI,[Font]
MOV ES,[SegA000]
MOV DI,[ScrOfs]
MOV BX,320 - 8
MOV DL,[C]
MOV CX,0008
CLD
@Rows: MOV DH,8
LODSB
@Cols: SHL AL,1
JNC @Mask
MOV ES:[DI],DL
@Mask: INC DI
DEC DH
JNZ @Cols
ADD DI,BX
LOOP @Rows
POP DS
END;
{
╔═════════════════════════════════════════════════════════════════════════╗
║ PROCEDURE PutChr ║
╟─────────────────────────────────────────────────────────────────────────╢
║ Input : Fonts X,Y position, color and char ║
╟─────────────────────────────────────────────────────────────────────────╢
║ Write one letter to video memory, posible shadowed ║
╚═════════════════════════════════════════════════════════════════════════╝
}
PROCEDURE PutChr( X, Y : Word; C : Byte; Ch : Char );
VAR SOfs : Word;
BEGIN
SOfs := Y * ( 8 * 320 ) + X * 8;
IF Shadow THEN
PutVGAChr( FontBuff[ Ord( Ch ) ], SOfs - ( 320 + 1 ), 0 );
PutVGAChr( FontBuff[ Ord( Ch ) ], SOfs, C )
END;
{
╔═════════════════════════════════════════════════════════════════════════╗
║ PROCEDURE WriteAT ║
╟─────────────────────────────────────────────────────────────────────────╢
║ Input : Write string St to X, Y with color C ║
╚═════════════════════════════════════════════════════════════════════════╝
}
PROCEDURE WriteAT( X, Y, C : Byte; CONST St : STRING );
VAR i : Word;
BEGIN
FOR i := 1 TO Byte( St[ 0 ] ) DO PutChr( X + Pred( i ), Y, C, St[ i ] );
END;
{
╔═════════════════════════════════════════════════════════════════════════╗
║ PROCEDURE WriteWin ║
╟─────────────────────────────────────────────────────────────────────────╢
║ Input : Write string St to X,Y with color C ║
╟─────────────────────────────────────────────────────────────────────────╢
║ X, Y is position from upper left corner of the active window ║
╚═════════════════════════════════════════════════════════════════════════╝
}
PROCEDURE WriteWin( X, Y : Word; C : Byte; CONST St : STRING );
VAR i, xS, xE, SOfs : Word;
Ch : Char;
BEGIN
WITH WinDef[ WinInd ] DO
BEGIN
xS := WX1 + X;
xE := xS + Length( St ) - 1;
IF ClipOn AND ( xE > WX2 ) THEN xE := WX2;
SOfs := ( WY1 + Y ) * ( 8 * 320 ) + xS * 8;
FOR i := xS TO xE DO
BEGIN
Ch := St[ i - xS + 1 ];
IF Shadow THEN
PutVGAChr( FontBuff[ Ord( Ch ) ], SOfs - ( 320 + 1 ), 0 );
PutVGAChr( FontBuff[ Ord( Ch ) ], SOfs, C );
Inc( SOfs, 8 )
END
END
END;
{
╔═════════════════════════════════════════════════════════════════════════╗
║ PROCEDURE SaveScrBuff ║
╟─────────────────────────────────────────────────────────────────────────╢
║ Save the portion behind window ║
╚═════════════════════════════════════════════════════════════════════════╝
}
PROCEDURE SaveScrBuff;
VAR i, xd, sl : Word;
p : Pointer;
BEGIN
WITH WinDef[ WinInd ] DO
BEGIN
p := Buff;
xd := SX2 - SX1 + 8 + 3 * 8;
sl := ( SY1 - 8 ) * 320 + SX1 - 8;
FOR i := SY1 TO SY2 + 8 + 3 * 8 DO
BEGIN
Copy16( Ptr( SegA000, sl ), p, xd );
Inc( Word( p ), xd );
Inc( sl, 320 )
END
END
END;
{
╔═════════════════════════════════════════════════════════════════════════╗
║ PROCEDURE RestoreScrBuff ║
╟─────────────────────────────────────────────────────────────────────────╢
║ Restore portion behind window ║
╚═════════════════════════════════════════════════════════════════════════╝
}
PROCEDURE RestoreScrBuff;
VAR i, xd, sl : Word;
p : Pointer;
BEGIN
WITH WinDef[ WinInd ] DO
BEGIN
p := Buff;
xd := SX2 - SX1 + 8 + 3 * 8;
sl := ( SY1 - 8 ) * 320 + SX1 - 8;
FOR i := SY1 TO SY2 + 8 + 3 * 8 DO
BEGIN
Copy16( p, Ptr( SegA000, sl ), xd );
Inc( Word( p ), xd );
Inc( sl, 320 )
END
END;
END;
{
╔═════════════════════════════════════════════════════════════════════════╗
║ FUNCTION OpenWin ║
╟─────────────────────────────────────────────────────────────────────────╢
║ Input : upper-left and lower-right cornesr of window, colors, and frame║
║ type ║
║ Output : TRUE, if succeed, FALSE otherwise ║
╚═════════════════════════════════════════════════════════════════════════╝
}
FUNCTION OpenWin( X1, Y1, X2, Y2 : Word; BackC, BordC, FrS : Byte ) : Boolean;
BEGIN
IF WinInd = MaxWins THEN Exit;
WITH WinDef[ Succ( WinInd )] DO
BEGIN
WX1 := X1;
WY1 := Y1;
WX2 := X2;
WY2 := Y2;
SX1 := WX1 * 8;
SX2 := WX2 * 8;
SY1 := WY1 * 8;
SY2 := WY2 * 8;
BaC := BackC;
BoC := BordC;
FrStyle := FrS;
ScrOfs := SY1 * 320 + SX1;
BuffSize := Succ( SX2 - SX1 + 8 + 3 * 8 ) * Succ( SY2 - SY1 + 8 + 3 * 8 + 8 );
IF BuffSize > MaxAvail THEN
BEGIN
OpenWin := FALSE;
Exit
END;
Inc( WinInd );
GetMem( Buff, BuffSize );
SaveScrBuff;
ClrWin( BaC )
END;
OpenWin := TRUE
END;
{
╔═════════════════════════════════════════════════════════════════════════╗
║ FUNCTION OpenWinCenter ║
╟─────────────────────────────────────────────────────────────────────────╢
║ Input : Windows X, Y size; colors, and frame type ║
║ Output : TRUE, if succeed, FALSE otherwise ║
╟─────────────────────────────────────────────────────────────────────────╢
║ Open window to center of the screen ║
╚═════════════════════════════════════════════════════════════════════════╝
}
FUNCTION OpenWinCenter( WinSizeX, WinSizeY : Word; BaC, BoC, Fr : Byte ) : Boolean;
VAR XPos, YPos : Word;
BEGIN
Dec( WinSizeX ); { start counting from zero... }
Dec( WinSizeY );
XPos := Pred( 20 - WinSizeX DIV 2 );
YPos := 12 - WinSizeY DIV 2;
OpenWinCenter := OpenWin( XPos, YPos, XPos + WinSizeX, YPos + WinSizeY, BaC, BoC, Fr )
END;
{
╔═════════════════════════════════════════════════════════════════════════╗
║ PROCEDURE CloseWin ║
╟─────────────────────────────────────────────────────────────────────────╢
║ Close the window last opened ║
╚═════════════════════════════════════════════════════════════════════════╝
}
PROCEDURE CloseWin;
BEGIN
IF WinInd < 1 THEN Exit;
RestoreScrBuff;
WITH WinDef[ WinInd ] DO FreeMem( Buff, BuffSize );
Dec( WinInd )
END;
{
╔═════════════════════════════════════════════════════════════════════════╗
║ PROCEDURE CloseAllWins ║
╟─────────────────────────────────────────────────────────────────────────╢
║ Close all windows ║
╚═════════════════════════════════════════════════════════════════════════╝
}
PROCEDURE CloseAllWins;
BEGIN
WHILE WinInd > 0 DO CloseWin
END;
{
╔═════════════════════════════════════════════════════════════════════════╗
║ PROCEDURE MakeBorder ║
╟─────────────────────────────────────────────────────────────────────────╢
║ Draw border to window ║
╚═════════════════════════════════════════════════════════════════════════╝
}
PROCEDURE MakeBorder;
VAR i : Word;
ss : Boolean;
BEGIN
WITH WinDef[ WinInd ] DO
BEGIN
ss := Shadow;
Shadow := FALSE;
FOR i := WX1 TO WX2 DO PutChr( i, WY1 - 1, BoC, FrCh[ FrStyle ].Hor );
FOR i := WX1 TO WX2 DO PutChr( i, WY2 + 1, BoC, FrCh[ FrStyle ].Hor );
FOR i := WY1 TO WY2 DO PutChr( WX1 - 1, i, BoC, FrCh[ FrStyle ].Ver );
FOR i := WY1 TO WY2 DO PutChr( WX2 + 1, i, BoC, FrCh[ FrStyle ].Ver );
PutChr( WX1 - 1, WY1 - 1, BoC, FrCh[ FrStyle ].UpL );
PutChr( WX2 + 1, WY1 - 1, BoC, FrCh[ FrStyle ].UpR );
PutChr( WX1 - 1, WY2 + 1, BoC, FrCh[ FrStyle ].LoL );
PutChr( WX2 + 1, WY2 + 1, BoC, FrCh[ FrStyle ].LoR );
Shadow := ss
END
END;
{
╔═════════════════════════════════════════════════════════════════════════╗
║ PROCEDURE MakeWinShadow ║
╟─────────────────────────────────────────────────────────────────────────╢
║ Draw shadow to the window ║
╚═════════════════════════════════════════════════════════════════════════╝
}
PROCEDURE MakeWinShadow;
VAR i, b : Word;
ss : Boolean;
BEGIN
IF WinInd > 0 THEN WITH WinDef[ WinInd ] DO
BEGIN
ss := Shadow;
Shadow := FALSE;
FOR i := WX1 TO WX2 + 2 DO PutChr( i, WY2 + 2, 0, '█' );
FOR i := WY1 TO WY2 + 2 DO PutChr( WX2 + 2, i, 0, '█' );
Shadow := ss
END
END;
{
╔═════════════════════════════════════════════════════════════════════════╗
║ PROCEDURE ClrWin ║
╟─────────────────────────────────────────────────────────────────────────╢
║ Input : Background color C ║
╟─────────────────────────────────────────────────────────────────────────╢
║ Clear the window with color C ║
╚═════════════════════════════════════════════════════════════════════════╝
}
PROCEDURE ClrWin( C : Byte );
VAR i, b : Word;
BEGIN
IF WinInd > 0 THEN WITH WinDef[ WinInd ] DO
BEGIN
MakeWinShadow;
BaC := C;
b := SX2 - SX1 + 8 + 2 * 8;
FOR i := SY1 - 8 TO SY2 + 2 * 8 DO
FillCharFast( Mem[ SegA000:i * 320 + SX1 - 8 ], b, C );
MakeBorder;
END
END;
(*****************************************************************************)
(* INITIALIZATION *)
(*****************************************************************************)
BEGIN
InitVGAWin;
GetFonts;
FontPtr := @FontBuff
END.