{ 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 x20 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 y2screenwidth 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.