home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Simtel MSDOS 1992 June
/
SIMTEL_0692.cdr
/
msdos
/
turbopas
/
stay42.arc
/
STAYWNDO.341
< prev
next >
Wrap
Text File
|
1986-06-07
|
16KB
|
376 lines
{**********************************************************************}
{ W I N D O . I N C }
{ "...but I dont do floors !" }
{**********************************************************************}
{ Kloned and Kludged by Lane Ferris }
{ -- The Hunters Helper -- }
{ Original Copyright 1984 by Michael A. Covington }
{ Modifications by Lynn Canning 9/25/85 }
{ 1) Foreground and Background colors added. }
{ Monochrome monitors are automatically set }
{ to white on black. }
{ 2) Multiple borders added. }
{ 3) TimeDelay procedure added. }
{ Requirements: IBM PC or close compatible. }
{----------------------------------------------------------------------}
{ To make a window on the screen, call the procedure }
{ MkWin(x1,y1,x2,y2,FG,BG,BD); }
{ The x and y coordinates define the window placement and are the }
{ same as the Turbo Pascal Window coordinates. }
{ The border parameters (BD) are 0 = No border }
{ 1 = Single line border }
{ 2 = Double line border }
{ 3 = Double Top/Bottom Single sides }
{ The foreground (FG) and background (BG) parameters are the same }
{ values as the corresponding Turbo Pascal values. }
{ }
{ The maximum number of windows open at one time is set at five }
{ (see MaxWin=5). This may be set to greater values if necessary. }
{ }
{ After the window is made, you must write the text desired from the }
{ calling program. Note that the usable text area is actually 1 }
{ position smaller than the window coordinates to allow for the border.}
{ Hence, a window defined as 1,1,80,25 would actually be 2,2,79,24 }
{ after the border is created. When writing to the window in your }
{ calling program, the textcolor and backgroundcolor may be changed as }
{ desired by using the standard Turbo Pascal commands. }
{ }
{ To return to the previous screen or window, call the procedure }
{ RmWin; }
{ }
{ The TimeDelay procedure is invoked from your calling program. It }
{ is similar to the Turbo Pascal DELAY except DELAY is based on clock }
{ speed whereas TimeDelay is based on the actual clock. This means }
{ that the delay will be the same duration on all systems no matter }
{ what the clock speed. }
{ The procedure could be used for an error condition as follows: }
{ MkWin - make an error message window }
{ Writeln - write error message to window }
{ TimeDelay(5) - leave window on screen 5 seconds }
{ RmWin - remove error window }
{ cont processing }
{----------------------------------------------------------------------}
Const
InitDone :boolean = false ; { Initialization switch }
On = True ;
Off = False ;
VideoEnable = $08; { Video Signal Enable Bit }
Bright = 8; { Bright Text bit}
Mono = 7; {MonoChrome Mode}
Type
Imagetype = array [1..4000] of char; { Screen Image in the heap }
WinDimtype = record
x1,y1,x2,y2: integer
end;
Screens = record { Save Screen Information }
Image: Imagetype; { Saved screen Image }
Dim: WinDimtype; { Saved Window Dimensions }
x,y: integer; { Saved cursor position }
end;
Var
Win: { Global variable package }
record
Dim: WinDimtype; { Current Window Dimensions }
Depth: integer;
{ MaxWin should be included in your program }
{ and it should be the number of windows saved }
{ at one time }
{ It should be in the const section of your program }
Stack: array[1..MaxWin] of ^Screens;
end;
Crtmode :byte absolute $0040:$0049; {Crt Mode,Mono,Color,B&W..}
Crtwidth :byte absolute $0040:$004A; {Crt Mode Width, 40:80 .. }
Monobuffer :Imagetype absolute $B000:$0000; {Monochrome Adapter Memory}
Colorbuffer :Imagetype absolute $B800:$0000; {Color Adapter Memory }
CrtAdapter :integer absolute $0040:$0063; { Current Display Adapter }
VideoMode :byte absolute $0040:$0065; { Video Port Mode byte }
TurboCrtMode: byte absolute Dseg:6; {Turbo's Crt Mode byte }
Video_Buffer:integer; { Record the current Video}
Delta,
x,y :integer;
{------------------------------------------------------------------}
{ Delay for X seconds }
{------------------------------------------------------------------}
procedure TimeDelay (hold : integer);
type
RegRec = { The data to pass to DOS }
record
AX, BX, CX, DX, BP, SI, DI, DS, ES, Flags : Integer;
end;
var
regs:regrec;
ah, al, ch, cl, dh:byte;
sec :string[2];
result, secn, error, secn2, diff :integer;
begin
ah := $2c; {Get Time-Of-Day from DOS}
with regs do {Will give back Ch:hours }
{Cl:minutes,Dh:seconds }
ax := ah shl 8 + al; {Dl:hundreds }
intr($21,regs);
with regs do
str(dx shr 8:2, sec); {Get seconds }
{with leading null}
if (sec[1] = ' ') then
sec[1]:= '0';
val(sec, secn, error); {Conver seconds to integer}
repeat { stay in this loop until the time }
ah := $2c; { has expired }
with regs do
ax := ah shl 8 + al;
intr($21,regs); {Get current time-of-day}
with regs do {Normalize to Char}
str(dx shr 8:2, sec);
if (sec[1] = ' ') then
sec[1]:= '0';
val(sec, secn2, error); {Convert seconds to integer}
diff := secn2 - secn; {Number of elapsed seconds}
if diff < 0 then { we just went over the minute }
diff := diff + 60; { so add 60 seconds }
until diff > hold; { has our time expired yet }
end; { procedure TimeDelay }
{------------------------------------------------------------------}
{ Get Absolute postion of Cursor into parameters x,y }
{------------------------------------------------------------------}
Procedure Get_Abs_Cursor (var x,y :integer);
Var
Active_Page : byte absolute $0040:$0062; { Current Video Page Index}
Crt_Pages : array[0..7] of integer absolute $0040:$0050 ;
Begin
X := Crt_Pages[active_page]; { Get Cursor Position }
Y := Hi(X)+1; { Y get Row }
X := Lo(X)+1; { X gets Col position }
End;
{------------------------------------------------------------------}
{ Turn the Video On/Off to avoid Read/Write snow }
{------------------------------------------------------------------}
Procedure Video (Switch:boolean);
Begin
If (Switch = Off) then
Port[CrtAdapter+4] := (VideoMode - VideoEnable)
else Port[CrtAdapter+4] := (VideoMode or VideoEnable);
End;
{------------------------------------------------------------------}
{ InitWin Saves the Current (whole) Screen }
{------------------------------------------------------------------}
Procedure InitWin;
{ Records Initial Window Dimensions }
Begin
with Win.Dim do
begin x1:=1; y1:=1; x2:=crtwidth; y2:=25 end;
Win.Depth:=0;
InitDone := True ; { Show initialization Done }
end;
{------------------------------------------------------------------}
{ BoxWin Draws a Box around the current Window }
{------------------------------------------------------------------}
procedure BoxWin(x1,y1,x2,y2, BD, FG, BG :integer);
{ Draws a box, fills it with blanks, and makes it the current }
{ Window. Dimensions given are for the box; actual Window is }
{ one unit smaller in each direction. }
var
I,
TB,SID,TLC,TRC,BLC,BRC :integer;
begin
if Crtmode = Mono then begin
FG := 7;
BG := 0;
end;
Window(x1,y1,x2,y2); {Make the Window}
TextColor(FG) ; {Set the colors}
TextBackground(BG);
Case BD of {Make Border characters}
0:; {No border option}
1:begin {Single line border option}
TB := 196; {Top Border}
SID := 179; {Side Border}
TLC := 218; {Top Left Corner}
TRC := 191; {Top Right Corner}
BLC := 192; {Bottom Left Corner}
BRC := 217; {Bottom Right Corner}
end;
2:begin {Double line border option}
TB := 205;
SID := 186;
TLC := 201; TRC := 187;
BLC := 200; BRC := 188;
end;
3:begin {Double Top/Bottom with single sides}
TB := 205; {"deary and dont spare the lace"}
SID := 179;
TLC := 213; TRC := 184;
BLC := 212; BRC := 190;
end;
End;{Case}
IF BD > 0 then begin { User want a border? }
{ Top }
gotoxy(1,1); { Window Origin }
Write( chr(TLC) ); { Top Left Corner }
For I:=2 to x2-x1 do { Top Bar }
Write( chr(TB));
Write( chr(TRC) ); { Top Right Corner
{ Sides }
for I:=2 to y2-y1 do
begin
gotoxy(1,I); { Left Side Bar }
write( chr(SID) );
gotoxy(x2-x1+1,I) ; { Right Side Bar }
write( chr(SID) );
end;
{ Bottom }
gotoxy(1,y2-y1+1); { Bottom Left Corner }
write( chr(BLC) );
for I:=2 to x2-x1 do { Bottom Bar }
write( chr(TB) );
{ Make it the current Window }
Window(x1+1,y1+1,x2-1,y2-1);
write( chr(BRC) ); { Bottom Right Corner }
end; {If BD > 0};
gotoxy(1,1) ;
TextColor( FG) ; { Take Low nibble 0..15 }
TextBackground (BG); { Take High nibble 0..9 }
ClrScr;
end;
{------------------------------------------------------------------}
{ MkWin Make a Window }
{------------------------------------------------------------------}
procedure MkWin(x1,y1,x2,y2, FG, BG, BD :integer);
{ Create a removable Window }
begin
If (InitDone = false) then { Initialize if not done yet }
InitWin;
TurboCrtMode := CrtMode; {Set Textmode w/o ClrScr}
If CrtMode = 7 then Video_Buffer := $B000 {Set Ptr to Monobuffer }
else Video_Buffer := $B800; {or Color Buffer }
with Win do Depth:=Depth+1; { Increment Stack pointer }
if Win.Depth>maxWin then
begin
writeln(^G,' Windows nested too deep ');
halt
end;
{-------------------------------------}
{ Save contents of screen }
{-------------------------------------}
With Win do
Begin
New(Stack[Depth]); { Allocate Current Screen to Heap }
Video( Off);
If CrtMode = 7 then
Stack[Depth]^.Image := monobuffer { set pointer to it }
else
Stack[Depth]^.Image := colorbuffer ;
Video( On);
End ;
With Win do
Begin { Save Screen Dimentions }
Stack[Depth]^.Dim := Dim;
Stack[Win.Depth]^.x := wherex; { Save Cursor Position }
Stack[Win.Depth]^.y := wherey;
End ;
{ Validate the Window Placement}
If (X2 > 80) then { If off right of screen }
begin
Delta := (X2 - 80); { Overflow off right margin }
If X1 > Delta then
X1 := X1 - Delta ; { Move Left window edge }
X2 := X2 - Delta ; { Move Right edge on 80 }
end;
If (Y2 > 25) then { If off bottom screen }
begin
Delta := Y2 - 25; { Overflow off right margin }
If Y1 > Delta then
Y1 := Y1 - Delta ; { Move Top edge up }
Y2 := Y2 - Delta ; { Move Bottom 24 }
end;
{ Create the New Window }
BoxWin(x1,y1,x2,y2,BD,FG,BG);
If BD >0 then begin {Shrink window within borders}
Win.Dim.x1 := x1+1;
Win.Dim.y1 := y1+1; { Allow for margins }
Win.Dim.x2 := x2-1;
Win.Dim.y2 := y2-1;
end;
end;
{------------------------------------------------------------------}
{ Remove Window }
{------------------------------------------------------------------}
{ Remove the most recently created removable Window }
{ Restore screen contents, Window Dimensions, and }
{ position of cursor. }
Procedure RmWin;
Var
Tempbyte : byte;
Begin
Video(Off);
With Win do
Begin { Restore next Screen }
If crtmode = 7 then
monobuffer := Stack[Depth]^.Image
else
colorbuffer := Stack[Depth]^.Image;
Dispose(Stack[Depth]); { Remove Screen from Heap }
Video(On);
With Win do { Re-instate the Sub-Window }
Begin { Position the old cursor }
Dim := Stack[Depth]^.Dim;
Window(Dim.x1,Dim.y1,Dim.x2,Dim.y2);
gotoxy(Stack[Depth]^.x,Stack[Depth]^.y);
end;
Get_Abs_Cursor(x,y) ; { New Cursor Position }
Tempbyte := { Get old Cursor attributes }
Mem[ Video_Buffer:((x-1 + (y-1) * 80 ) * 2)+1 ];
TextColor( Tempbyte And $0F ); { Take Low nibble 0..15}
TextBackground ( Tempbyte Div 16); { Take High nibble 0..9 }
Depth := Depth - 1
end ;
end;
{------------------------------------------------------------------}