[Back to TEXTWNDW SWAG index] [Back to Main SWAG index] [Original]
{ WRITTEN BY TIM SCHEMPP
OCTOBER 21, 1993 }
unit drawline;
interface
procedure horizline(x1,x2,y:integer; default:char);
procedure vertline(x,y1,y2:integer; default:char);
procedure rectlines(x1,y1,x2,y2:integer; default:char);
{ IF writetomemory IS SET TO TRUE, LINES WILL BE DRAWN AN AVERAGE OF
ABOUT 15 TO 20 PERCENT FASTER THAN IF writetomemory IS SET TO FALSE.
HOWEVER, IF DATA IS WRITTEN DIRECTLY TO VIDEO MEMORY, YOU ARE STUCK WITH
THE SCREENS CURRENT COLORS (TEXTCOLOR AND TEXTBACKGROUND HAVE NO EFFECT).
THE DEFAULT VALUE OF writetomemory IS FALSE. }
var writetomemory:boolean;
implementation
uses crt; {for gotoxy, wherex and wherey}
const symbols:array[1..40] of char=
('³','´','µ','¶','·','¸','¹','º','»','¼','½','¾','¿',
'À','Á','Â','Ã','Ä','Å','Æ','Ç','È','É','Ê','Ë','Ì',
'Í','Î','Ï','Ð','Ñ','Ò','Ó','Ô','Õ','Ö','×','Ø','Ù',
'Ú');
codes:array[1..40] of string[4]=
('1010','1011','1012','2021','0021','0012','2022','2020',
'0022','2002','2001','1002','0011','1100','1101','0111',
'1110','0101','1111','1210','2120','2200','0220','2202',
'0222','2220','0202','2222','1202','2101','0212','0121',
'2100','1200','0210','0120','2121','1212','1001','0110');
{THE SCREEN DIMENSIONS}
screenwidth=80; screenlength=25;
{******}
{READS A CHARACTER FROM VIDEO MEMORY AT THE GIVEN COORDINANTS}
function Memread(col,row:integer):char;
Const
Seg = $B000; { Video memory address for color system }
Ofs = $8000; { For monochrome system, make Ofs = $0000 }
Var
SChar : Integer;
Begin
SChar := ((Row-1)*160) + ((Col-1)*2); { Compute starting location }
memread:=chr(Mem[Seg:Ofs + SChar]); { read character from memory}
End;
{******}
{WRITES A CHARACTER DIRECTORY TO VIDEO MEMORY AT THE GIVEN COORDINATES}
{NOTE: THE CURRENT COLORS AT THE GIVEN COORDINANTS ARE USED FOR DRAWING.}
procedure Memwrite(col,row:integer; c:char);
Const
Seg = $B000; { Video memory address for color system }
Ofs = $8000; { For monochrome system, make Ofs = $0000 }
Var
SChar : Integer;
Begin
SChar := ((Row-1)*160) + ((Col-1)*2); { Compute starting location }
Mem[Seg:Ofs + SChar]:=ord(c); { write character to memory}
End;
{******}
{PROCEDURE USED INTERNALLY TO CREATE A SET OF CHARACTER CODES}
function getcode(c:char; direction:byte):char;
var counter:integer;
begin
counter:=1;
while (counter<=40) and (c<>symbols[counter]) do inc(counter);
if counter>40 then getcode:='0' else getcode:=codes[counter,direction];
end;
{******}
{PROCEDURE DRAWS A LINE IN TEXT MODE FROM (X1,Y) TO (X2,Y)}
{DEFAULT IS EITHER '1' OR '2' FOR SINGLE OF DOUBLE LINES}
procedure horizline(x1,x2,y:integer; default:char);
var code:string[4];
defaultchar:char;
c,index:integer;
xpos,ypos:integer;
begin
xpos:=wherex; ypos:=wherey;
if x2<x1 then begin c:=x1; x1:=x2; x2:=c; end;
if default='1' then defaultchar:=symbols[18]
else defaultchar:=symbols[27];
for c:=x1 to x2 do
begin
code:='0000';
if y<>0 then code[1]:=getcode(memread(c,y-1),3) else code[1]:='0';
if (c=x2) and (x2=screenwidth) then code[2]:='0'
else if (c=x2) then code[2]:=getcode(memread(x2+1,y),4)
else code[2]:=default;
if y<>screenlength then code[3]:=getcode(memread(c,y+1),1)
else code[3]:='0';
if (c=x1) and (x1=1) then code[4]:='0'
else
if (c=x1) then code[4]:=getcode(memread(x1-1,y),2)
else code[4]:=default;
index:=1;
while (index<=40) and (code<>codes[index]) do inc(index);
if writetomemory then
if index>40 then memwrite(c,y,defaultchar)
else memwrite(c,y,symbols[index])
else
if index>40 then begin gotoxy(c,y); write(defaultchar); end
else begin gotoxy(c,y); write(symbols[index]); end;
end; {counter}
if not writetomemory then gotoxy(xpos,ypos);
end;
{******}
{PROCEDURE DRAWS A LINE IN TEXT MODE FROM (X,Y1) TO (X,Y2)}
{DEFAULT IS EITHER '1' OR '2' FOR SINGLE OF DOUBLE LINES}
procedure vertline(x,y1,y2:integer; default:char);
var code:string[4];
defaultchar:char;
c,index:integer;
xpos,ypos:integer;
begin
xpos:=wherex; ypos:=wherey;
if y2<y1 then begin c:=y1; y1:=y2; y2:=c; end;
if default='1' then defaultchar:=symbols[1]
else defaultchar:=symbols[8];
for c:=y1 to y2 do
begin
code:='0000';
if (c=y2) and (y2=screenlength) then code[3]:='0'
else if (c=y2) then code[3]:=getcode(memread(x,y2+1),1)
else code[3]:=default;
if x<>screenwidth then code[2]:=getcode(memread(x+1,c),4)
else code[1]:='0';
if x<>1 then code[4]:=getcode(memread(x-1,c),2)
else code[1]:='0';
if (c=y1) and (y1=0) then code[1]:='0'
else if (c=y1) then code[1]:=getcode(memread(x,y1-1),3)
else code[1]:=default;
index:=1;
while (index<=40) and (code<>codes[index]) do inc(index);
if writetomemory then
if index>40 then memwrite(x,c,defaultchar)
else memwrite(x,c,symbols[index])
else
if index>40 then begin gotoxy(x,c); write(defaultchar) end
else begin gotoxy(x,c); write(symbols[index]); end;
end; {counter}
if not writetomemory then gotoxy(xpos,ypos);
end;
{******}
{PROCEDURE DRAWS A RECTANGLE IN TEXT MODE}
{DEFAULT IS EITHER '1' OR '2' FOR SINGLE OF DOUBLE LINES}
procedure rectlines(x1,y1,x2,y2:integer; default:char);
begin
horizline(x1,x2,y1,default);
horizline(x1,x2,y2,default);
vertline(x1,y1,y2,default);
vertline(x2,y1,y2,default);
end;
{******}
begin
writetomemory:=false;
end. {unit}
{------------------- DEMO PROGRAM ------------------------}
{ ---------------- CUT HERE --------------------------}
{ WRITTEN BY TIM SCHEMPP
OCTOBER 21, 1993 }
{THIS PROGRAM DEMONSTARTES THE USE OF THE UNIT drawline. UNIT DRAWLINE
WILL USE THE ASCII SET TO DRAW LINES. WHEN LINE INTERSECTIONS ARE
FOUND, THE PROCEDURES DESCIDE WHICH CHARACTER FITS BEST. THUS MAKING
IT VERY EASY TO CREATE VARIOUS TABLES AND OTHER SCREEN SET UPS. THE
UNIT ALSO HAS THE ABILITY TO WRITE DIRECTORY TO VIDEO MEMORY FOR
A 15% TO 20% IMPROVEMENT IN SPEED. SEE DRAWLINE.DOC FOR MORE INFO.}
program demo;
uses crt,drawline;
var counter:integer;
begin
{SET THE SCREEN UP}
textbackground(black);
textcolor(white);
clrscr;
{THE CALL TO CLEAR SCREEN FILLED THE SCREEN WITH SPACES WITH A BLACK
BACKGROUND AND A WHITE FOREGROUND. IF writetomemory IS SET TO TRUE,
ALL OF THE OUTPUT WILL BE WRITTEN WITH A BLACK BACKGROUND AND A WHITE
FOREGROUND REGARDLESS OF TEXT ATTRIBUTE CHANGES.}
{writetomemory:=true;} { <--- ADD THIS STATEMENT AND SEE COLOR DIFFERENCE}
{WRITE SOME TEXT}
gotoxy(22,6);
textcolor(lightblue);
write('LINE DRAWING DEMONSTARTATION PROGRAM');
textcolor(yellow);
{DRAW A RECTANGLE WITH DOUBLE LINES}
rectlines(10,4,70,20,'2');
{DRAW SOME HORIZONTAL SINGLE LINES}
for counter:=9 to 19 do
horizline(10,70,counter,'1');
{DRAW SOME SINGLE VERTICLE LINES}
counter:=20;
while counter<=60 do
begin
vertline(counter,8,20,'1');
inc(counter,10);
end; {WHILE}
{DRAW ONE LAST HORIZONTAL DOUBLE LINE}
horizline(10,70,8,'2');
repeat until keypressed;
end.
[Back to TEXTWNDW SWAG index] [Back to Main SWAG index] [Original]